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