* Synchronise terminology with the ICSE paper (e.g., slice -> closure,
fstate -> Nix expression). * Fix src/test.cc.
This commit is contained in:
parent
563afb7fcc
commit
5d4171f7fb
15 changed files with 254 additions and 268 deletions
|
@ -10,7 +10,7 @@ foreach my $id (@ARGV) {
|
|||
die unless $id =~ /^([0-9a-z]{32})$/;
|
||||
|
||||
# Get all paths referenced by the normalisation of the given
|
||||
# fstate expression.
|
||||
# Nix expression.
|
||||
system "nix --install $id";
|
||||
if ($?) { die "`nix --install' failed"; }
|
||||
|
||||
|
@ -52,7 +52,7 @@ foreach my $id (@ARGV) {
|
|||
# Construct a Fix expression that creates a Nix archive.
|
||||
my $fixexpr =
|
||||
"App(IncludeFix(\"nar/nar.fix\"), " .
|
||||
"[ (\"path\", Slice([\"$path\"], [(\"$path\", \"$pathid\", [])]))" .
|
||||
"[ (\"path\", Closure([\"$path\"], [(\"$path\", \"$pathid\", [])]))" .
|
||||
"])";
|
||||
|
||||
print FIX "," unless ($first);
|
||||
|
|
|
@ -23,7 +23,7 @@ test_LDADD = libshared.a libnix.a $(LDADD)
|
|||
noinst_LIBRARIES = libnix.a libshared.a
|
||||
|
||||
libnix_a_SOURCES = util.cc hash.cc archive.cc md5.c \
|
||||
store.cc fstate.cc normalise.cc exec.cc \
|
||||
store.cc expr.cc normalise.cc exec.cc \
|
||||
globals.cc db.cc references.cc pathlocks.cc
|
||||
|
||||
libshared_a_SOURCES = shared.cc
|
||||
|
|
|
@ -51,9 +51,9 @@ string pathLabel(const FSId & id, const string & path)
|
|||
}
|
||||
|
||||
|
||||
void printSlice(const FSId & id, const FState & fs)
|
||||
void printClosure(const FSId & id, const NixExpr & fs)
|
||||
{
|
||||
Strings workList(fs.slice.roots.begin(), fs.slice.roots.end());
|
||||
Strings workList(fs.closure.roots.begin(), fs.closure.roots.end());
|
||||
StringSet doneSet;
|
||||
|
||||
for (Strings::iterator i = workList.begin(); i != workList.end(); i++) {
|
||||
|
@ -67,9 +67,9 @@ void printSlice(const FSId & id, const FState & fs)
|
|||
if (doneSet.find(path) == doneSet.end()) {
|
||||
doneSet.insert(path);
|
||||
|
||||
SliceElems::const_iterator elem = fs.slice.elems.find(path);
|
||||
if (elem == fs.slice.elems.end())
|
||||
throw Error(format("bad slice, missing path `%1%'") % path);
|
||||
ClosureElems::const_iterator elem = fs.closure.elems.find(path);
|
||||
if (elem == fs.closure.elems.end())
|
||||
throw Error(format("bad closure, missing path `%1%'") % path);
|
||||
|
||||
for (StringSet::const_iterator i = elem->second.refs.begin();
|
||||
i != elem->second.refs.end(); i++)
|
||||
|
@ -99,29 +99,29 @@ void printDotGraph(const FSIds & roots)
|
|||
if (doneSet.find(id) == doneSet.end()) {
|
||||
doneSet.insert(id);
|
||||
|
||||
FState fs = parseFState(termFromId(id));
|
||||
NixExpr ne = parseNixExpr(termFromId(id));
|
||||
|
||||
string label, colour;
|
||||
|
||||
if (fs.type == FState::fsDerive) {
|
||||
for (FSIdSet::iterator i = fs.derive.inputs.begin();
|
||||
i != fs.derive.inputs.end(); i++)
|
||||
if (ne.type == NixExpr::neDerivation) {
|
||||
for (FSIdSet::iterator i = ne.derivation.inputs.begin();
|
||||
i != ne.derivation.inputs.end(); i++)
|
||||
{
|
||||
workList.push_back(*i);
|
||||
cout << makeEdge(*i, id);
|
||||
}
|
||||
|
||||
label = "derive";
|
||||
label = "derivation";
|
||||
colour = "#00ff00";
|
||||
for (StringPairs::iterator i = fs.derive.env.begin();
|
||||
i != fs.derive.env.end(); i++)
|
||||
for (StringPairs::iterator i = ne.derivation.env.begin();
|
||||
i != ne.derivation.env.end(); i++)
|
||||
if (i->first == "name") label = i->second;
|
||||
}
|
||||
|
||||
else if (fs.type == FState::fsSlice) {
|
||||
label = "<slice>";
|
||||
else if (ne.type == NixExpr::neClosure) {
|
||||
label = "<closure>";
|
||||
colour = "#00ffff";
|
||||
printSlice(id, fs);
|
||||
printClosure(id, ne);
|
||||
}
|
||||
|
||||
else abort();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __DOTGRAPH_H
|
||||
#define __DOTGRAPH_H
|
||||
|
||||
#include "fstate.hh"
|
||||
#include "expr.hh"
|
||||
|
||||
void printDotGraph(const FSIds & roots);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "fstate.hh"
|
||||
#include "expr.hh"
|
||||
#include "globals.hh"
|
||||
#include "store.hh"
|
||||
|
||||
|
@ -65,23 +65,23 @@ static void parsePaths(ATermList paths, StringSet & out)
|
|||
}
|
||||
|
||||
|
||||
static void checkSlice(const Slice & slice)
|
||||
static void checkClosure(const Closure & closure)
|
||||
{
|
||||
if (slice.elems.size() == 0)
|
||||
throw Error("empty slice");
|
||||
if (closure.elems.size() == 0)
|
||||
throw Error("empty closure");
|
||||
|
||||
StringSet decl;
|
||||
for (SliceElems::const_iterator i = slice.elems.begin();
|
||||
i != slice.elems.end(); i++)
|
||||
for (ClosureElems::const_iterator i = closure.elems.begin();
|
||||
i != closure.elems.end(); i++)
|
||||
decl.insert(i->first);
|
||||
|
||||
for (StringSet::const_iterator i = slice.roots.begin();
|
||||
i != slice.roots.end(); i++)
|
||||
for (StringSet::const_iterator i = closure.roots.begin();
|
||||
i != closure.roots.end(); i++)
|
||||
if (decl.find(*i) == decl.end())
|
||||
throw Error(format("undefined root path `%1%'") % *i);
|
||||
|
||||
for (SliceElems::const_iterator i = slice.elems.begin();
|
||||
i != slice.elems.end(); i++)
|
||||
for (ClosureElems::const_iterator i = closure.elems.begin();
|
||||
i != closure.elems.end(); i++)
|
||||
for (StringSet::const_iterator j = i->second.refs.begin();
|
||||
j != i->second.refs.end(); j++)
|
||||
if (decl.find(*j) == decl.end())
|
||||
|
@ -91,35 +91,35 @@ static void checkSlice(const Slice & slice)
|
|||
}
|
||||
|
||||
|
||||
/* Parse a slice. */
|
||||
static bool parseSlice(ATerm t, Slice & slice)
|
||||
/* Parse a closure. */
|
||||
static bool parseClosure(ATerm t, Closure & closure)
|
||||
{
|
||||
ATermList roots, elems;
|
||||
|
||||
if (!ATmatch(t, "Slice([<list>], [<list>])", &roots, &elems))
|
||||
if (!ATmatch(t, "Closure([<list>], [<list>])", &roots, &elems))
|
||||
return false;
|
||||
|
||||
parsePaths(roots, slice.roots);
|
||||
parsePaths(roots, closure.roots);
|
||||
|
||||
while (!ATisEmpty(elems)) {
|
||||
char * s1, * s2;
|
||||
ATermList refs;
|
||||
ATerm t = ATgetFirst(elems);
|
||||
if (!ATmatch(t, "(<str>, <str>, [<list>])", &s1, &s2, &refs))
|
||||
throw badTerm("not a slice element", t);
|
||||
SliceElem elem;
|
||||
throw badTerm("not a closure element", t);
|
||||
ClosureElem elem;
|
||||
elem.id = parseHash(s2);
|
||||
parsePaths(refs, elem.refs);
|
||||
slice.elems[s1] = elem;
|
||||
closure.elems[s1] = elem;
|
||||
elems = ATgetNext(elems);
|
||||
}
|
||||
|
||||
checkSlice(slice);
|
||||
checkClosure(closure);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool parseDerive(ATerm t, Derive & derive)
|
||||
static bool parseDerivation(ATerm t, Derivation & derivation)
|
||||
{
|
||||
ATermList outs, ins, args, bnds;
|
||||
char * builder;
|
||||
|
@ -139,8 +139,8 @@ static bool parseDerive(ATerm t, Derive & derive)
|
|||
char * s1, * s2;
|
||||
ATerm t = ATgetFirst(outs);
|
||||
if (!ATmatch(t, "(<str>, <str>)", &s1, &s2))
|
||||
throw badTerm("not a derive output", t);
|
||||
derive.outputs[s1] = parseHash(s2);
|
||||
throw badTerm("not a derivation output", t);
|
||||
derivation.outputs[s1] = parseHash(s2);
|
||||
outs = ATgetNext(outs);
|
||||
}
|
||||
|
||||
|
@ -149,19 +149,19 @@ static bool parseDerive(ATerm t, Derive & derive)
|
|||
ATerm t = ATgetFirst(ins);
|
||||
if (!ATmatch(t, "<str>", &s))
|
||||
throw badTerm("not an id", t);
|
||||
derive.inputs.insert(parseHash(s));
|
||||
derivation.inputs.insert(parseHash(s));
|
||||
ins = ATgetNext(ins);
|
||||
}
|
||||
|
||||
derive.builder = builder;
|
||||
derive.platform = platform;
|
||||
derivation.builder = builder;
|
||||
derivation.platform = platform;
|
||||
|
||||
while (!ATisEmpty(args)) {
|
||||
char * s;
|
||||
ATerm arg = ATgetFirst(args);
|
||||
if (!ATmatch(arg, "<str>", &s))
|
||||
throw badTerm("string expected", arg);
|
||||
derive.args.push_back(s);
|
||||
derivation.args.push_back(s);
|
||||
args = ATgetNext(args);
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ static bool parseDerive(ATerm t, Derive & derive)
|
|||
ATerm bnd = ATgetFirst(bnds);
|
||||
if (!ATmatch(bnd, "(<str>, <str>)", &s1, &s2))
|
||||
throw badTerm("tuple of strings expected", bnd);
|
||||
derive.env[s1] = s2;
|
||||
derivation.env[s1] = s2;
|
||||
bnds = ATgetNext(bnds);
|
||||
}
|
||||
|
||||
|
@ -178,15 +178,15 @@ static bool parseDerive(ATerm t, Derive & derive)
|
|||
}
|
||||
|
||||
|
||||
FState parseFState(ATerm t)
|
||||
NixExpr parseNixExpr(ATerm t)
|
||||
{
|
||||
FState fs;
|
||||
if (parseSlice(t, fs.slice))
|
||||
fs.type = FState::fsSlice;
|
||||
else if (parseDerive(t, fs.derive))
|
||||
fs.type = FState::fsDerive;
|
||||
else throw badTerm("not an fstate-expression", t);
|
||||
return fs;
|
||||
NixExpr ne;
|
||||
if (parseClosure(t, ne.closure))
|
||||
ne.type = NixExpr::neClosure;
|
||||
else if (parseDerivation(t, ne.derivation))
|
||||
ne.type = NixExpr::neDerivation;
|
||||
else throw badTerm("not a Nix expression", t);
|
||||
return ne;
|
||||
}
|
||||
|
||||
|
||||
|
@ -200,45 +200,45 @@ static ATermList unparsePaths(const StringSet & paths)
|
|||
}
|
||||
|
||||
|
||||
static ATerm unparseSlice(const Slice & slice)
|
||||
static ATerm unparseClosure(const Closure & closure)
|
||||
{
|
||||
ATermList roots = unparsePaths(slice.roots);
|
||||
ATermList roots = unparsePaths(closure.roots);
|
||||
|
||||
ATermList elems = ATempty;
|
||||
for (SliceElems::const_iterator i = slice.elems.begin();
|
||||
i != slice.elems.end(); i++)
|
||||
for (ClosureElems::const_iterator i = closure.elems.begin();
|
||||
i != closure.elems.end(); i++)
|
||||
elems = ATinsert(elems,
|
||||
ATmake("(<str>, <str>, <term>)",
|
||||
i->first.c_str(),
|
||||
((string) i->second.id).c_str(),
|
||||
unparsePaths(i->second.refs)));
|
||||
|
||||
return ATmake("Slice(<term>, <term>)", roots, elems);
|
||||
return ATmake("Closure(<term>, <term>)", roots, elems);
|
||||
}
|
||||
|
||||
|
||||
static ATerm unparseDerive(const Derive & derive)
|
||||
static ATerm unparseDerivation(const Derivation & derivation)
|
||||
{
|
||||
ATermList outs = ATempty;
|
||||
for (DeriveOutputs::const_iterator i = derive.outputs.begin();
|
||||
i != derive.outputs.end(); i++)
|
||||
for (DerivationOutputs::const_iterator i = derivation.outputs.begin();
|
||||
i != derivation.outputs.end(); i++)
|
||||
outs = ATinsert(outs,
|
||||
ATmake("(<str>, <str>)",
|
||||
i->first.c_str(), ((string) i->second).c_str()));
|
||||
|
||||
ATermList ins = ATempty;
|
||||
for (FSIdSet::const_iterator i = derive.inputs.begin();
|
||||
i != derive.inputs.end(); i++)
|
||||
for (FSIdSet::const_iterator i = derivation.inputs.begin();
|
||||
i != derivation.inputs.end(); i++)
|
||||
ins = ATinsert(ins, ATmake("<str>", ((string) *i).c_str()));
|
||||
|
||||
ATermList args = ATempty;
|
||||
for (Strings::const_iterator i = derive.args.begin();
|
||||
i != derive.args.end(); i++)
|
||||
for (Strings::const_iterator i = derivation.args.begin();
|
||||
i != derivation.args.end(); i++)
|
||||
args = ATinsert(args, ATmake("<str>", i->c_str()));
|
||||
|
||||
ATermList env = ATempty;
|
||||
for (StringPairs::const_iterator i = derive.env.begin();
|
||||
i != derive.env.end(); i++)
|
||||
for (StringPairs::const_iterator i = derivation.env.begin();
|
||||
i != derivation.env.end(); i++)
|
||||
env = ATinsert(env,
|
||||
ATmake("(<str>, <str>)",
|
||||
i->first.c_str(), i->second.c_str()));
|
||||
|
@ -246,18 +246,18 @@ static ATerm unparseDerive(const Derive & derive)
|
|||
return ATmake("Derive(<term>, <term>, <str>, <str>, <term>, <term>)",
|
||||
ATreverse(outs),
|
||||
ATreverse(ins),
|
||||
derive.platform.c_str(),
|
||||
derive.builder.c_str(),
|
||||
derivation.platform.c_str(),
|
||||
derivation.builder.c_str(),
|
||||
ATreverse(args),
|
||||
ATreverse(env));
|
||||
}
|
||||
|
||||
|
||||
ATerm unparseFState(const FState & fs)
|
||||
ATerm unparseNixExpr(const NixExpr & ne)
|
||||
{
|
||||
if (fs.type == FState::fsSlice)
|
||||
return unparseSlice(fs.slice);
|
||||
else if (fs.type == FState::fsDerive)
|
||||
return unparseDerive(fs.derive);
|
||||
if (ne.type == NixExpr::neClosure)
|
||||
return unparseClosure(ne.closure);
|
||||
else if (ne.type == NixExpr::neDerivation)
|
||||
return unparseDerivation(ne.derivation);
|
||||
else abort();
|
||||
}
|
|
@ -8,30 +8,30 @@ extern "C" {
|
|||
#include "store.hh"
|
||||
|
||||
|
||||
/* Abstract syntax of fstate-expressions. */
|
||||
/* Abstract syntax of Nix expressions. */
|
||||
|
||||
typedef list<FSId> FSIds;
|
||||
|
||||
struct SliceElem
|
||||
struct ClosureElem
|
||||
{
|
||||
FSId id;
|
||||
StringSet refs;
|
||||
};
|
||||
|
||||
typedef map<string, SliceElem> SliceElems;
|
||||
typedef map<string, ClosureElem> ClosureElems;
|
||||
|
||||
struct Slice
|
||||
struct Closure
|
||||
{
|
||||
StringSet roots;
|
||||
SliceElems elems;
|
||||
ClosureElems elems;
|
||||
};
|
||||
|
||||
typedef map<string, FSId> DeriveOutputs;
|
||||
typedef map<string, FSId> DerivationOutputs;
|
||||
typedef map<string, string> StringPairs;
|
||||
|
||||
struct Derive
|
||||
struct Derivation
|
||||
{
|
||||
DeriveOutputs outputs;
|
||||
DerivationOutputs outputs;
|
||||
FSIdSet inputs;
|
||||
string platform;
|
||||
string builder;
|
||||
|
@ -39,11 +39,11 @@ struct Derive
|
|||
StringPairs env;
|
||||
};
|
||||
|
||||
struct FState
|
||||
struct NixExpr
|
||||
{
|
||||
enum { fsSlice, fsDerive } type;
|
||||
Slice slice;
|
||||
Derive derive;
|
||||
enum { neClosure, neDerivation } type;
|
||||
Closure closure;
|
||||
Derivation derivation;
|
||||
};
|
||||
|
||||
|
||||
|
@ -63,11 +63,11 @@ ATerm termFromId(const FSId & id);
|
|||
/* Write an aterm to the Nix store directory, and return its hash. */
|
||||
FSId writeTerm(ATerm t, const string & suffix, FSId id = FSId());
|
||||
|
||||
/* Parse an fstate-expression. */
|
||||
FState parseFState(ATerm t);
|
||||
/* Parse a Nix expression. */
|
||||
NixExpr parseNixExpr(ATerm t);
|
||||
|
||||
/* Parse an fstate-expression. */
|
||||
ATerm unparseFState(const FState & fs);
|
||||
/* Parse a Nix expression. */
|
||||
ATerm unparseNixExpr(const NixExpr & ne);
|
||||
|
||||
|
||||
#endif /* !__FSTATE_H */
|
73
src/fix.cc
73
src/fix.cc
|
@ -121,47 +121,47 @@ static Expr substExprMany(ATermList formals, ATermList args, Expr body)
|
|||
}
|
||||
|
||||
|
||||
static Strings fstatePathsCached(EvalState & state, const FSId & id)
|
||||
static Strings nixExprPathsCached(EvalState & state, const FSId & id)
|
||||
{
|
||||
PkgPaths::iterator i = state.pkgPaths.find(id);
|
||||
if (i != state.pkgPaths.end())
|
||||
return i->second;
|
||||
else {
|
||||
Strings paths = fstatePaths(id);
|
||||
Strings paths = nixExprPaths(id);
|
||||
state.pkgPaths[id] = paths;
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Hash hashPackage(EvalState & state, FState fs)
|
||||
static Hash hashPackage(EvalState & state, NixExpr ne)
|
||||
{
|
||||
if (fs.type == FState::fsDerive) {
|
||||
if (ne.type == NixExpr::neDerivation) {
|
||||
FSIdSet inputs2;
|
||||
for (FSIdSet::iterator i = fs.derive.inputs.begin();
|
||||
i != fs.derive.inputs.end(); i++)
|
||||
for (FSIdSet::iterator i = ne.derivation.inputs.begin();
|
||||
i != ne.derivation.inputs.end(); i++)
|
||||
{
|
||||
PkgHashes::iterator j = state.pkgHashes.find(*i);
|
||||
if (j == state.pkgHashes.end())
|
||||
throw Error(format("unknown package id %1%") % (string) *i);
|
||||
inputs2.insert(j->second);
|
||||
}
|
||||
fs.derive.inputs = inputs2;
|
||||
ne.derivation.inputs = inputs2;
|
||||
}
|
||||
return hashTerm(unparseFState(fs));
|
||||
return hashTerm(unparseNixExpr(ne));
|
||||
}
|
||||
|
||||
|
||||
static string processBinding(EvalState & state, Expr e, FState & fs)
|
||||
static string processBinding(EvalState & state, Expr e, NixExpr & ne)
|
||||
{
|
||||
char * s1;
|
||||
|
||||
if (ATmatch(e, "FSId(<str>)", &s1)) {
|
||||
FSId id = parseHash(s1);
|
||||
Strings paths = fstatePathsCached(state, id);
|
||||
Strings paths = nixExprPathsCached(state, id);
|
||||
if (paths.size() != 1) abort();
|
||||
string path = *(paths.begin());
|
||||
fs.derive.inputs.insert(id);
|
||||
ne.derivation.inputs.insert(id);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ static string processBinding(EvalState & state, Expr e, FState & fs)
|
|||
bool first = true;
|
||||
while (!ATisEmpty(l)) {
|
||||
if (!first) s = s + " "; else first = false;
|
||||
s += processBinding(state, evalExpr(state, ATgetFirst(l)), fs);
|
||||
s += processBinding(state, evalExpr(state, ATgetFirst(l)), ne);
|
||||
l = ATgetNext(l);
|
||||
}
|
||||
return s;
|
||||
|
@ -204,7 +204,7 @@ static Expr evalExpr2(EvalState & state, Expr e)
|
|||
return e;
|
||||
|
||||
try {
|
||||
Hash pkgHash = hashPackage(state, parseFState(e));
|
||||
Hash pkgHash = hashPackage(state, parseNixExpr(e));
|
||||
FSId pkgId = writeTerm(e, "");
|
||||
state.pkgHashes[pkgId] = pkgHash;
|
||||
return ATmake("FSId(<str>)", ((string) pkgId).c_str());
|
||||
|
@ -265,15 +265,15 @@ static Expr evalExpr2(EvalState & state, Expr e)
|
|||
FSId id;
|
||||
addToStore(srcPath, dstPath, id, true);
|
||||
|
||||
SliceElem elem;
|
||||
ClosureElem elem;
|
||||
elem.id = id;
|
||||
FState fs;
|
||||
fs.type = FState::fsSlice;
|
||||
fs.slice.roots.insert(dstPath);
|
||||
fs.slice.elems[dstPath] = elem;
|
||||
NixExpr ne;
|
||||
ne.type = NixExpr::neClosure;
|
||||
ne.closure.roots.insert(dstPath);
|
||||
ne.closure.elems[dstPath] = elem;
|
||||
|
||||
Hash pkgHash = hashPackage(state, fs);
|
||||
FSId pkgId = writeTerm(unparseFState(fs), "");
|
||||
Hash pkgHash = hashPackage(state, ne);
|
||||
FSId pkgId = writeTerm(unparseNixExpr(ne), "");
|
||||
state.pkgHashes[pkgId] = pkgHash;
|
||||
|
||||
msg(lvlChatty, format("copied `%1%' -> %2%")
|
||||
|
@ -282,7 +282,7 @@ static Expr evalExpr2(EvalState & state, Expr e)
|
|||
return ATmake("FSId(<str>)", ((string) pkgId).c_str());
|
||||
}
|
||||
|
||||
/* Packages are transformed into Derive fstate expressions. */
|
||||
/* Packages are transformed into Nix derivation expressions. */
|
||||
if (ATmatch(e, "Package([<list>])", &bnds)) {
|
||||
|
||||
/* Evaluate the bindings and put them in a map. */
|
||||
|
@ -296,10 +296,11 @@ static Expr evalExpr2(EvalState & state, Expr e)
|
|||
bnds = ATgetNext(bnds);
|
||||
}
|
||||
|
||||
/* Gather information for building the Derive expression. */
|
||||
FState fs;
|
||||
fs.type = FState::fsDerive;
|
||||
fs.derive.platform = SYSTEM;
|
||||
/* Gather information for building the derivation
|
||||
expression. */
|
||||
NixExpr ne;
|
||||
ne.type = NixExpr::neDerivation;
|
||||
ne.derivation.platform = SYSTEM;
|
||||
string name;
|
||||
FSId outId;
|
||||
bool outIdGiven = false;
|
||||
|
@ -318,16 +319,16 @@ static Expr evalExpr2(EvalState & state, Expr e)
|
|||
|
||||
while (!ATisEmpty(args)) {
|
||||
Expr arg = evalExpr(state, ATgetFirst(args));
|
||||
fs.derive.args.push_back(processBinding(state, arg, fs));
|
||||
ne.derivation.args.push_back(processBinding(state, arg, ne));
|
||||
args = ATgetNext(args);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
string s = processBinding(state, value, fs);
|
||||
fs.derive.env[key] = s;
|
||||
string s = processBinding(state, value, ne);
|
||||
ne.derivation.env[key] = s;
|
||||
|
||||
if (key == "build") fs.derive.builder = s;
|
||||
if (key == "build") ne.derivation.builder = s;
|
||||
if (key == "name") name = s;
|
||||
if (key == "id") {
|
||||
outId = parseHash(s);
|
||||
|
@ -339,25 +340,25 @@ static Expr evalExpr2(EvalState & state, Expr e)
|
|||
ATmake("(<str>, <term>)", key.c_str(), value));
|
||||
}
|
||||
|
||||
if (fs.derive.builder == "")
|
||||
if (ne.derivation.builder == "")
|
||||
throw badTerm("no builder specified", e);
|
||||
|
||||
if (name == "")
|
||||
throw badTerm("no package name specified", e);
|
||||
|
||||
/* Hash the fstate-expression with no outputs to produce a
|
||||
/* Hash the Nix expression with no outputs to produce a
|
||||
unique but deterministic path name for this package. */
|
||||
if (!outIdGiven) outId = hashPackage(state, fs);
|
||||
if (!outIdGiven) outId = hashPackage(state, ne);
|
||||
string outPath =
|
||||
canonPath(nixStore + "/" + ((string) outId).c_str() + "-" + name);
|
||||
fs.derive.env["out"] = outPath;
|
||||
fs.derive.outputs[outPath] = outId;
|
||||
ne.derivation.env["out"] = outPath;
|
||||
ne.derivation.outputs[outPath] = outId;
|
||||
|
||||
/* Write the resulting term into the Nix store directory. */
|
||||
Hash pkgHash = outIdGiven
|
||||
? hashString((string) outId + outPath)
|
||||
: hashPackage(state, fs);
|
||||
FSId pkgId = writeTerm(unparseFState(fs), "-d-" + name);
|
||||
: hashPackage(state, ne);
|
||||
FSId pkgId = writeTerm(unparseNixExpr(ne), "-d-" + name);
|
||||
state.pkgHashes[pkgId] = pkgHash;
|
||||
|
||||
msg(lvlChatty, format("instantiated `%1%' -> %2%")
|
||||
|
|
|
@ -29,7 +29,7 @@ extern TableId dbId2Paths;
|
|||
/* dbSuccessors :: FSId -> FSId
|
||||
|
||||
Each pair $(id_1, id_2)$ in this mapping records the fact that a
|
||||
successor of an fstate expression stored in a file with identifier
|
||||
successor of a Nix expression stored in a file with identifier
|
||||
$id_1$ is stored in a file with identifier $id_2$.
|
||||
|
||||
Note that a term $y$ is successor of $x$ iff there exists a
|
||||
|
@ -41,15 +41,14 @@ extern TableId dbSuccessors;
|
|||
/* dbSubstitutes :: FSId -> [FSId]
|
||||
|
||||
Each pair $(id, [ids])$ tells Nix that it can realise any of the
|
||||
fstate expressions referenced by the identifiers in $ids$ to
|
||||
Nix expressions referenced by the identifiers in $ids$ to
|
||||
generate a path with identifier $id$.
|
||||
|
||||
The main purpose of this is for distributed caching of derivates.
|
||||
One system can compute a derivate with hash $h$ and put it on a
|
||||
website (as a Nix archive), for instance, and then another system
|
||||
can register a substitute for that derivate. The substitute in
|
||||
this case might be an fstate expression that fetches the Nix
|
||||
archive.
|
||||
this case might be a Nix expression that fetches the Nix archive.
|
||||
*/
|
||||
extern TableId dbSubstitutes;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ nix [OPTIONS...] [ARGUMENTS...]
|
|||
|
||||
Operations:
|
||||
|
||||
--install / -i: realise an fstate
|
||||
--install / -i: realise a Nix expression
|
||||
--delete / -d: delete paths from the Nix store
|
||||
--add / -A: copy a path to the Nix store
|
||||
--query / -q: query information
|
||||
|
@ -25,7 +25,7 @@ Source selection for --install, --dump:
|
|||
|
||||
Query flags:
|
||||
|
||||
--list / -l: query the output paths (roots) of an fstate (default)
|
||||
--list / -l: query the output paths (roots) of a Nix expression (default)
|
||||
--requisites / -r: print all paths necessary to realise expression
|
||||
--generators / -g: find expressions producing a subset of given ids
|
||||
--expansion / -e: print a path containing id
|
||||
|
|
13
src/nix.cc
13
src/nix.cc
|
@ -37,8 +37,7 @@ static FSId argToId(const string & arg)
|
|||
}
|
||||
|
||||
|
||||
/* Realise (or install) paths from the given Nix fstate
|
||||
expressions. */
|
||||
/* Realise (or install) paths from the given Nix expressions. */
|
||||
static void opInstall(Strings opFlags, Strings opArgs)
|
||||
{
|
||||
if (!opFlags.empty()) throw UsageError("unknown flag");
|
||||
|
@ -46,8 +45,8 @@ static void opInstall(Strings opFlags, Strings opArgs)
|
|||
for (Strings::iterator it = opArgs.begin();
|
||||
it != opArgs.end(); it++)
|
||||
{
|
||||
FSId id = normaliseFState(argToId(*it));
|
||||
realiseSlice(id);
|
||||
FSId id = normaliseNixExpr(argToId(*it));
|
||||
realiseClosure(id);
|
||||
cout << format("%1%\n") % (string) id;
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +82,7 @@ static void opAdd(Strings opFlags, Strings opArgs)
|
|||
|
||||
FSId maybeNormalise(const FSId & id, bool normalise)
|
||||
{
|
||||
return normalise ? normaliseFState(id) : id;
|
||||
return normalise ? normaliseNixExpr(id) : id;
|
||||
}
|
||||
|
||||
|
||||
|
@ -115,7 +114,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
for (Strings::iterator i = opArgs.begin();
|
||||
i != opArgs.end(); i++)
|
||||
{
|
||||
Strings paths2 = fstatePaths(
|
||||
Strings paths2 = nixExprPaths(
|
||||
maybeNormalise(argToId(*i), normalise));
|
||||
paths.insert(paths2.begin(), paths2.end());
|
||||
}
|
||||
|
@ -130,7 +129,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
for (Strings::iterator i = opArgs.begin();
|
||||
i != opArgs.end(); i++)
|
||||
{
|
||||
Strings paths2 = fstateRequisites(
|
||||
Strings paths2 = nixExprRequisites(
|
||||
maybeNormalise(argToId(*i), normalise),
|
||||
includeExprs, includeSuccessors);
|
||||
paths.insert(paths2.begin(), paths2.end());
|
||||
|
|
181
src/normalise.cc
181
src/normalise.cc
|
@ -26,40 +26,41 @@ static FSId useSuccessor(const FSId & id)
|
|||
}
|
||||
|
||||
|
||||
Strings pathsFromOutputs(const DeriveOutputs & ps)
|
||||
Strings pathsFromOutputs(const DerivationOutputs & ps)
|
||||
{
|
||||
Strings ss;
|
||||
for (DeriveOutputs::const_iterator i = ps.begin();
|
||||
for (DerivationOutputs::const_iterator i = ps.begin();
|
||||
i != ps.end(); i++)
|
||||
ss.push_back(i->first);
|
||||
return ss;
|
||||
}
|
||||
|
||||
|
||||
FSId normaliseFState(FSId id, FSIdSet pending)
|
||||
FSId normaliseNixExpr(FSId id, FSIdSet pending)
|
||||
{
|
||||
Nest nest(lvlTalkative, format("normalising fstate %1%") % (string) id);
|
||||
Nest nest(lvlTalkative,
|
||||
format("normalising nix expression %1%") % (string) id);
|
||||
|
||||
/* Try to substitute $id$ by any known successors in order to
|
||||
speed up the rewrite process. */
|
||||
id = useSuccessor(id);
|
||||
|
||||
/* Get the fstate expression. */
|
||||
FState fs = parseFState(termFromId(id));
|
||||
/* Get the Nix expression. */
|
||||
NixExpr ne = parseNixExpr(termFromId(id));
|
||||
|
||||
/* If this is a normal form (i.e., a slice) we are done. */
|
||||
if (fs.type == FState::fsSlice) return id;
|
||||
if (fs.type != FState::fsDerive) abort();
|
||||
/* If this is a normal form (i.e., a closure) we are done. */
|
||||
if (ne.type == NixExpr::neClosure) return id;
|
||||
if (ne.type != NixExpr::neDerivation) abort();
|
||||
|
||||
|
||||
/* Otherwise, it's a derive expression, and we have to build it to
|
||||
/* Otherwise, it's a derivation expression, and we have to build it to
|
||||
determine its normal form. */
|
||||
|
||||
|
||||
/* Some variables. */
|
||||
|
||||
/* Input paths, with their slice elements. */
|
||||
SliceElems inSlices;
|
||||
/* Input paths, with their closure elements. */
|
||||
ClosureElems inClosures;
|
||||
|
||||
/* Referencable paths (i.e., input and output paths). */
|
||||
StringSet allPaths;
|
||||
|
@ -68,13 +69,13 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
Environment env;
|
||||
|
||||
/* The result. */
|
||||
FState nfFS;
|
||||
nfFS.type = FState::fsSlice;
|
||||
NixExpr nf;
|
||||
nf.type = NixExpr::neClosure;
|
||||
|
||||
|
||||
/* Parse the outputs. */
|
||||
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
||||
i != fs.derive.outputs.end(); i++)
|
||||
for (DerivationOutputs::iterator i = ne.derivation.outputs.begin();
|
||||
i != ne.derivation.outputs.end(); i++)
|
||||
{
|
||||
debug(format("building %1% in `%2%'") % (string) i->second % i->first);
|
||||
allPaths.insert(i->first);
|
||||
|
@ -82,7 +83,7 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
|
||||
/* Obtain locks on all output paths. The locks are automatically
|
||||
released when we exit this function or Nix crashes. */
|
||||
PathLocks outputLocks(pathsFromOutputs(fs.derive.outputs));
|
||||
PathLocks outputLocks(pathsFromOutputs(ne.derivation.outputs));
|
||||
|
||||
/* Now check again whether there is a successor. This is because
|
||||
another process may have started building in parallel. After
|
||||
|
@ -95,33 +96,33 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
{
|
||||
FSId id2 = useSuccessor(id);
|
||||
if (id2 != id) {
|
||||
FState fs = parseFState(termFromId(id2));
|
||||
NixExpr ne = parseNixExpr(termFromId(id2));
|
||||
debug(format("skipping build of %1%, someone beat us to it")
|
||||
% (string) id);
|
||||
if (fs.type != FState::fsSlice) abort();
|
||||
if (ne.type != NixExpr::neClosure) abort();
|
||||
return id2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Right platform? */
|
||||
if (fs.derive.platform != thisSystem)
|
||||
if (ne.derivation.platform != thisSystem)
|
||||
throw Error(format("a `%1%' is required, but I am a `%2%'")
|
||||
% fs.derive.platform % thisSystem);
|
||||
% ne.derivation.platform % thisSystem);
|
||||
|
||||
/* Realise inputs (and remember all input paths). */
|
||||
for (FSIdSet::iterator i = fs.derive.inputs.begin();
|
||||
i != fs.derive.inputs.end(); i++)
|
||||
for (FSIdSet::iterator i = ne.derivation.inputs.begin();
|
||||
i != ne.derivation.inputs.end(); i++)
|
||||
{
|
||||
FSId nf = normaliseFState(*i, pending);
|
||||
realiseSlice(nf, pending);
|
||||
FSId nf = normaliseNixExpr(*i, pending);
|
||||
realiseClosure(nf, pending);
|
||||
/* !!! nf should be a root of the garbage collector while we
|
||||
are building */
|
||||
FState fs = parseFState(termFromId(nf));
|
||||
if (fs.type != FState::fsSlice) abort();
|
||||
for (SliceElems::iterator j = fs.slice.elems.begin();
|
||||
j != fs.slice.elems.end(); j++)
|
||||
NixExpr ne = parseNixExpr(termFromId(nf));
|
||||
if (ne.type != NixExpr::neClosure) abort();
|
||||
for (ClosureElems::iterator j = ne.closure.elems.begin();
|
||||
j != ne.closure.elems.end(); j++)
|
||||
{
|
||||
inSlices[j->first] = j->second;
|
||||
inClosures[j->first] = j->second;
|
||||
allPaths.insert(j->first);
|
||||
}
|
||||
}
|
||||
|
@ -140,15 +141,15 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
env["HOME"] = "/homeless-shelter";
|
||||
|
||||
/* Build the environment. */
|
||||
for (StringPairs::iterator i = fs.derive.env.begin();
|
||||
i != fs.derive.env.end(); i++)
|
||||
for (StringPairs::iterator i = ne.derivation.env.begin();
|
||||
i != ne.derivation.env.end(); i++)
|
||||
env[i->first] = i->second;
|
||||
|
||||
/* We can skip running the builder if we can expand all output
|
||||
paths from their ids. */
|
||||
bool fastBuild = true;
|
||||
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
||||
i != fs.derive.outputs.end(); i++)
|
||||
for (DerivationOutputs::iterator i = ne.derivation.outputs.begin();
|
||||
i != ne.derivation.outputs.end(); i++)
|
||||
{
|
||||
try {
|
||||
expandId(i->second, i->first, "/", pending);
|
||||
|
@ -164,8 +165,8 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
|
||||
/* If any of the outputs already exist but are not registered,
|
||||
delete them. */
|
||||
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
||||
i != fs.derive.outputs.end(); i++)
|
||||
for (DerivationOutputs::iterator i = ne.derivation.outputs.begin();
|
||||
i != ne.derivation.outputs.end(); i++)
|
||||
{
|
||||
string path = i->first;
|
||||
FSId id;
|
||||
|
@ -179,7 +180,7 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
|
||||
/* Run the builder. */
|
||||
msg(lvlChatty, format("building..."));
|
||||
runProgram(fs.derive.builder, fs.derive.args, env);
|
||||
runProgram(ne.derivation.builder, ne.derivation.args, env);
|
||||
msg(lvlChatty, format("build completed"));
|
||||
|
||||
} else
|
||||
|
@ -189,13 +190,13 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
output path to determine what other paths it references. Also make all
|
||||
output paths read-only. */
|
||||
StringSet usedPaths;
|
||||
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
||||
i != fs.derive.outputs.end(); i++)
|
||||
for (DerivationOutputs::iterator i = ne.derivation.outputs.begin();
|
||||
i != ne.derivation.outputs.end(); i++)
|
||||
{
|
||||
string path = i->first;
|
||||
if (!pathExists(path))
|
||||
throw Error(format("path `%1%' does not exist") % path);
|
||||
nfFS.slice.roots.insert(path);
|
||||
nf.closure.roots.insert(path);
|
||||
|
||||
makePathReadOnly(path);
|
||||
|
||||
|
@ -204,28 +205,28 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
Strings refPaths = filterReferences(path,
|
||||
Strings(allPaths.begin(), allPaths.end()));
|
||||
|
||||
/* Construct a slice element for this output path. */
|
||||
SliceElem elem;
|
||||
/* Construct a closure element for this output path. */
|
||||
ClosureElem elem;
|
||||
elem.id = i->second;
|
||||
|
||||
/* For each path referenced by this output path, add its id to the
|
||||
slice element and add the id to the `usedPaths' set (so that the
|
||||
elements referenced by *its* slice are added below). */
|
||||
closure element and add the id to the `usedPaths' set (so that the
|
||||
elements referenced by *its* closure are added below). */
|
||||
for (Strings::iterator j = refPaths.begin();
|
||||
j != refPaths.end(); j++)
|
||||
{
|
||||
string path = *j;
|
||||
elem.refs.insert(path);
|
||||
if (inSlices.find(path) != inSlices.end())
|
||||
if (inClosures.find(path) != inClosures.end())
|
||||
usedPaths.insert(path);
|
||||
else if (fs.derive.outputs.find(path) == fs.derive.outputs.end())
|
||||
else if (ne.derivation.outputs.find(path) == ne.derivation.outputs.end())
|
||||
abort();
|
||||
}
|
||||
|
||||
nfFS.slice.elems[path] = elem;
|
||||
nf.closure.elems[path] = elem;
|
||||
}
|
||||
|
||||
/* Close the slice. That is, for any referenced path, add the paths
|
||||
/* Close the closure. That is, for any referenced path, add the paths
|
||||
referenced by it. */
|
||||
StringSet donePaths;
|
||||
|
||||
|
@ -237,10 +238,10 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
if (donePaths.find(path) != donePaths.end()) continue;
|
||||
donePaths.insert(path);
|
||||
|
||||
SliceElems::iterator j = inSlices.find(path);
|
||||
if (j == inSlices.end()) abort();
|
||||
ClosureElems::iterator j = inClosures.find(path);
|
||||
if (j == inClosures.end()) abort();
|
||||
|
||||
nfFS.slice.elems[path] = j->second;
|
||||
nf.closure.elems[path] = j->second;
|
||||
|
||||
for (StringSet::iterator k = j->second.refs.begin();
|
||||
k != j->second.refs.end(); k++)
|
||||
|
@ -248,8 +249,8 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
}
|
||||
|
||||
/* For debugging, print out the referenced and unreferenced paths. */
|
||||
for (SliceElems::iterator i = inSlices.begin();
|
||||
i != inSlices.end(); i++)
|
||||
for (ClosureElems::iterator i = inClosures.begin();
|
||||
i != inClosures.end(); i++)
|
||||
{
|
||||
StringSet::iterator j = donePaths.find(i->first);
|
||||
if (j == donePaths.end())
|
||||
|
@ -260,9 +261,9 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
|
||||
/* Write the normal form. This does not have to occur in the
|
||||
transaction below because writing terms is idem-potent. */
|
||||
ATerm nf = unparseFState(nfFS);
|
||||
msg(lvlVomit, format("normal form: %1%") % printTerm(nf));
|
||||
FSId idNF = writeTerm(nf, "-s-" + (string) id);
|
||||
ATerm nfTerm = unparseNixExpr(nf);
|
||||
msg(lvlVomit, format("normal form: %1%") % printTerm(nfTerm));
|
||||
FSId idNF = writeTerm(nfTerm, "-s-" + (string) id);
|
||||
|
||||
/* Register each outpat path, and register the normal form. This
|
||||
is wrapped in one database transaction to ensure that if we
|
||||
|
@ -271,8 +272,8 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
deleted arbitrarily, while registered paths can only be deleted
|
||||
by running the garbage collector. */
|
||||
Transaction txn(nixDB);
|
||||
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
||||
i != fs.derive.outputs.end(); i++)
|
||||
for (DerivationOutputs::iterator i = ne.derivation.outputs.begin();
|
||||
i != ne.derivation.outputs.end(); i++)
|
||||
registerPath(txn, i->first, i->second);
|
||||
registerSuccessor(txn, id, idNF);
|
||||
txn.commit();
|
||||
|
@ -281,36 +282,36 @@ FSId normaliseFState(FSId id, FSIdSet pending)
|
|||
}
|
||||
|
||||
|
||||
void realiseSlice(const FSId & id, FSIdSet pending)
|
||||
void realiseClosure(const FSId & id, FSIdSet pending)
|
||||
{
|
||||
Nest nest(lvlDebug,
|
||||
format("realising slice %1%") % (string) id);
|
||||
format("realising closure %1%") % (string) id);
|
||||
|
||||
FState fs = parseFState(termFromId(id));
|
||||
if (fs.type != FState::fsSlice)
|
||||
throw Error(format("expected slice in %1%") % (string) id);
|
||||
NixExpr ne = parseNixExpr(termFromId(id));
|
||||
if (ne.type != NixExpr::neClosure)
|
||||
throw Error(format("expected closure in %1%") % (string) id);
|
||||
|
||||
for (SliceElems::const_iterator i = fs.slice.elems.begin();
|
||||
i != fs.slice.elems.end(); i++)
|
||||
for (ClosureElems::const_iterator i = ne.closure.elems.begin();
|
||||
i != ne.closure.elems.end(); i++)
|
||||
expandId(i->second.id, i->first, "/", pending);
|
||||
}
|
||||
|
||||
|
||||
Strings fstatePaths(const FSId & id)
|
||||
Strings nixExprPaths(const FSId & id)
|
||||
{
|
||||
Strings paths;
|
||||
|
||||
FState fs = parseFState(termFromId(id));
|
||||
NixExpr ne = parseNixExpr(termFromId(id));
|
||||
|
||||
if (fs.type == FState::fsSlice) {
|
||||
for (StringSet::const_iterator i = fs.slice.roots.begin();
|
||||
i != fs.slice.roots.end(); i++)
|
||||
if (ne.type == NixExpr::neClosure) {
|
||||
for (StringSet::const_iterator i = ne.closure.roots.begin();
|
||||
i != ne.closure.roots.end(); i++)
|
||||
paths.push_back(*i);
|
||||
}
|
||||
|
||||
else if (fs.type == FState::fsDerive) {
|
||||
for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
|
||||
i != fs.derive.outputs.end(); i++)
|
||||
else if (ne.type == NixExpr::neDerivation) {
|
||||
for (DerivationOutputs::iterator i = ne.derivation.outputs.begin();
|
||||
i != ne.derivation.outputs.end(); i++)
|
||||
paths.push_back(i->first);
|
||||
}
|
||||
|
||||
|
@ -320,24 +321,24 @@ Strings fstatePaths(const FSId & id)
|
|||
}
|
||||
|
||||
|
||||
static void fstateRequisitesSet(const FSId & id,
|
||||
static void nixExprRequisitesSet(const FSId & id,
|
||||
bool includeExprs, bool includeSuccessors, StringSet & paths,
|
||||
FSIdSet & doneSet)
|
||||
{
|
||||
if (doneSet.find(id) != doneSet.end()) return;
|
||||
doneSet.insert(id);
|
||||
|
||||
FState fs = parseFState(termFromId(id));
|
||||
NixExpr ne = parseNixExpr(termFromId(id));
|
||||
|
||||
if (fs.type == FState::fsSlice)
|
||||
for (SliceElems::iterator i = fs.slice.elems.begin();
|
||||
i != fs.slice.elems.end(); i++)
|
||||
if (ne.type == NixExpr::neClosure)
|
||||
for (ClosureElems::iterator i = ne.closure.elems.begin();
|
||||
i != ne.closure.elems.end(); i++)
|
||||
paths.insert(i->first);
|
||||
|
||||
else if (fs.type == FState::fsDerive)
|
||||
for (FSIdSet::iterator i = fs.derive.inputs.begin();
|
||||
i != fs.derive.inputs.end(); i++)
|
||||
fstateRequisitesSet(*i,
|
||||
else if (ne.type == NixExpr::neDerivation)
|
||||
for (FSIdSet::iterator i = ne.derivation.inputs.begin();
|
||||
i != ne.derivation.inputs.end(); i++)
|
||||
nixExprRequisitesSet(*i,
|
||||
includeExprs, includeSuccessors, paths, doneSet);
|
||||
|
||||
else abort();
|
||||
|
@ -348,17 +349,17 @@ static void fstateRequisitesSet(const FSId & id,
|
|||
string idSucc;
|
||||
if (includeSuccessors &&
|
||||
nixDB.queryString(noTxn, dbSuccessors, id, idSucc))
|
||||
fstateRequisitesSet(parseHash(idSucc),
|
||||
nixExprRequisitesSet(parseHash(idSucc),
|
||||
includeExprs, includeSuccessors, paths, doneSet);
|
||||
}
|
||||
|
||||
|
||||
Strings fstateRequisites(const FSId & id,
|
||||
Strings nixExprRequisites(const FSId & id,
|
||||
bool includeExprs, bool includeSuccessors)
|
||||
{
|
||||
StringSet paths;
|
||||
FSIdSet doneSet;
|
||||
fstateRequisitesSet(id, includeExprs, includeSuccessors, paths, doneSet);
|
||||
nixExprRequisitesSet(id, includeExprs, includeSuccessors, paths, doneSet);
|
||||
return Strings(paths.begin(), paths.end());
|
||||
}
|
||||
|
||||
|
@ -381,19 +382,19 @@ FSIds findGenerators(const FSIds & _ids)
|
|||
if (!nixDB.queryString(noTxn, dbSuccessors, *i, s)) continue;
|
||||
FSId id = parseHash(s);
|
||||
|
||||
FState fs;
|
||||
NixExpr ne;
|
||||
try {
|
||||
/* !!! should substitutes be used? */
|
||||
fs = parseFState(termFromId(id));
|
||||
ne = parseNixExpr(termFromId(id));
|
||||
} catch (...) { /* !!! only catch parse errors */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fs.type != FState::fsSlice) continue;
|
||||
if (ne.type != NixExpr::neClosure) continue;
|
||||
|
||||
bool okay = true;
|
||||
for (SliceElems::const_iterator i = fs.slice.elems.begin();
|
||||
i != fs.slice.elems.end(); i++)
|
||||
for (ClosureElems::const_iterator i = ne.closure.elems.begin();
|
||||
i != ne.closure.elems.end(); i++)
|
||||
if (ids.find(i->second.id) == ids.end()) {
|
||||
okay = false;
|
||||
break;
|
||||
|
|
|
@ -1,30 +1,29 @@
|
|||
#ifndef __NORMALISE_H
|
||||
#define __NORMALISE_H
|
||||
|
||||
#include "fstate.hh"
|
||||
#include "expr.hh"
|
||||
|
||||
|
||||
/* Normalise an fstate-expression, that is, return an equivalent
|
||||
slice. (For the meaning of `pending', see expandId()). */
|
||||
FSId normaliseFState(FSId id, FSIdSet pending = FSIdSet());
|
||||
/* Normalise a Nix expression, that is, return an equivalent
|
||||
closure. (For the meaning of `pending', see expandId()). */
|
||||
FSId normaliseNixExpr(FSId id, FSIdSet pending = FSIdSet());
|
||||
|
||||
/* Realise a Slice in the file system. */
|
||||
void realiseSlice(const FSId & id, FSIdSet pending = FSIdSet());
|
||||
/* Realise a Closure in the file system. */
|
||||
void realiseClosure(const FSId & id, FSIdSet pending = FSIdSet());
|
||||
|
||||
/* Get the list of root (output) paths of the given
|
||||
fstate-expression. */
|
||||
Strings fstatePaths(const FSId & id);
|
||||
/* Get the list of root (output) paths of the given Nix expression. */
|
||||
Strings nixExprPaths(const FSId & id);
|
||||
|
||||
/* Get the list of paths that are required to realise the given
|
||||
expression. For a derive expression, this is the union of
|
||||
requisites of the inputs; for a slice expression, it is the path of
|
||||
each element in the slice. If `includeExprs' is true, include the
|
||||
requisites of the inputs; for a closure expression, it is the path of
|
||||
each element in the closure. If `includeExprs' is true, include the
|
||||
paths of the Nix expressions themselves. If `includeSuccessors' is
|
||||
true, include the requisites of successors. */
|
||||
Strings fstateRequisites(const FSId & id,
|
||||
Strings nixExprRequisites(const FSId & id,
|
||||
bool includeExprs, bool includeSuccessors);
|
||||
|
||||
/* Return the list of the ids of all known fstate-expressions whose
|
||||
/* Return the list of the ids of all known Nix expressions whose
|
||||
output ids are completely contained in `ids'. */
|
||||
FSIds findGenerators(const FSIds & ids);
|
||||
|
||||
|
|
|
@ -246,7 +246,7 @@ string expandId(const FSId & id, const string & target,
|
|||
|
||||
debug(format("trying substitute %1%") % (string) subId);
|
||||
|
||||
realiseSlice(normaliseFState(subId, pending), pending);
|
||||
realiseClosure(normaliseNixExpr(subId, pending), pending);
|
||||
|
||||
return expandId(id, target, prefix, pending);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
echo "builder 2"
|
||||
|
||||
mkdir $out || exit 1
|
||||
/bin/mkdir $out || exit 1
|
||||
cd $out || exit 1
|
||||
echo "Hallo Wereld" > bla
|
||||
echo $builder >> bla
|
||||
|
|
35
src/test.cc
35
src/test.cc
|
@ -13,23 +13,10 @@
|
|||
void realise(FSId id)
|
||||
{
|
||||
Nest nest(lvlDebug, format("TEST: realising %1%") % (string) id);
|
||||
realiseSlice(normaliseFState(id));
|
||||
realiseClosure(normaliseNixExpr(id));
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void realiseFail(FState fs)
|
||||
{
|
||||
try {
|
||||
realiseFState(fs);
|
||||
abort();
|
||||
} catch (Error e) {
|
||||
cout << "error (expected): " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct MySink : DumpSink
|
||||
{
|
||||
virtual void operator () (const unsigned char * data, unsigned int len)
|
||||
|
@ -115,8 +102,8 @@ void runTests()
|
|||
addToStore("./test-builder-1.sh", builder1fn, builder1id);
|
||||
|
||||
ATerm fs1 = ATmake(
|
||||
"Slice([<str>], [(<str>, <str>, [])])",
|
||||
((string) builder1id).c_str(),
|
||||
"Closure([<str>], [(<str>, <str>, [])])",
|
||||
builder1fn.c_str(),
|
||||
builder1fn.c_str(),
|
||||
((string) builder1id).c_str());
|
||||
FSId fs1id = writeTerm(fs1, "");
|
||||
|
@ -125,8 +112,8 @@ void runTests()
|
|||
realise(fs1id);
|
||||
|
||||
ATerm fs2 = ATmake(
|
||||
"Slice([<str>], [(<str>, <str>, [])])",
|
||||
((string) builder1id).c_str(),
|
||||
"Closure([<str>], [(<str>, <str>, [])])",
|
||||
(builder1fn + "_bla").c_str(),
|
||||
(builder1fn + "_bla").c_str(),
|
||||
((string) builder1id).c_str());
|
||||
FSId fs2id = writeTerm(fs2, "");
|
||||
|
@ -137,12 +124,12 @@ void runTests()
|
|||
string out1id = hashString("foo"); /* !!! bad */
|
||||
string out1fn = nixStore + "/" + (string) out1id + "-hello.txt";
|
||||
ATerm fs3 = ATmake(
|
||||
"Derive([(<str>, <str>)], [<str>], <str>, <str>, [(\"out\", <str>)])",
|
||||
"Derive([(<str>, <str>)], [<str>], <str>, <str>, [], [(\"out\", <str>)])",
|
||||
out1fn.c_str(),
|
||||
((string) out1id).c_str(),
|
||||
((string) fs1id).c_str(),
|
||||
((string) builder1fn).c_str(),
|
||||
thisSystem.c_str(),
|
||||
((string) builder1fn).c_str(),
|
||||
out1fn.c_str());
|
||||
debug(printTerm(fs3));
|
||||
FSId fs3id = writeTerm(fs3, "");
|
||||
|
@ -156,8 +143,8 @@ void runTests()
|
|||
addToStore("./test-builder-2.sh", builder4fn, builder4id);
|
||||
|
||||
ATerm fs4 = ATmake(
|
||||
"Slice([<str>], [(<str>, <str>, [])])",
|
||||
((string) builder4id).c_str(),
|
||||
"Closure([<str>], [(<str>, <str>, [])])",
|
||||
builder4fn.c_str(),
|
||||
builder4fn.c_str(),
|
||||
((string) builder4id).c_str());
|
||||
FSId fs4id = writeTerm(fs4, "");
|
||||
|
@ -167,12 +154,12 @@ void runTests()
|
|||
string out5id = hashString("bar"); /* !!! bad */
|
||||
string out5fn = nixStore + "/" + (string) out5id + "-hello2";
|
||||
ATerm fs5 = ATmake(
|
||||
"Derive([(<str>, <str>)], [<str>], <str>, <str>, [(\"out\", <str>), (\"builder\", <str>)])",
|
||||
"Derive([(<str>, <str>)], [<str>], <str>, <str>, [], [(\"out\", <str>), (\"builder\", <str>)])",
|
||||
out5fn.c_str(),
|
||||
((string) out5id).c_str(),
|
||||
((string) fs4id).c_str(),
|
||||
((string) builder4fn).c_str(),
|
||||
thisSystem.c_str(),
|
||||
((string) builder4fn).c_str(),
|
||||
out5fn.c_str(),
|
||||
((string) builder4fn).c_str());
|
||||
debug(printTerm(fs5));
|
||||
|
|
Loading…
Reference in a new issue