aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-06-04 20:56:13 +0200
committerEelco Dolstra <edolstra@gmail.com>2019-06-04 20:56:42 +0200
commit1e53a07712fba830eb3967cc16894992d5a33922 (patch)
tree419c034629eb0b1ce3fc28ffe9cccdcaf9062866
parent1c5067b9a7e1f561bf9e9e84642c495a50ca44a7 (diff)
Make non-flake inputs lazy
Also add a proper test for non-flake inputs.
-rw-r--r--src/libexpr/primops/flake.cc44
-rw-r--r--src/libexpr/primops/flake.hh1
-rw-r--r--src/nix/flake.cc2
-rw-r--r--tests/flakes.sh25
4 files changed, 53 insertions, 19 deletions
diff --git a/src/libexpr/primops/flake.cc b/src/libexpr/primops/flake.cc
index 52d8df69e..f99738db5 100644
--- a/src/libexpr/primops/flake.cc
+++ b/src/libexpr/primops/flake.cc
@@ -276,7 +276,7 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowe
}
// Get the `NonFlake` corresponding to a `FlakeRef`.
-NonFlake getNonFlake(EvalState & state, const FlakeRef & flakeRef, FlakeAlias alias, bool impureIsAllowed = false)
+NonFlake getNonFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowed = false)
{
auto sourceInfo = fetchFlake(state, flakeRef, impureIsAllowed);
debug("got non-flake source '%s' with flakeref %s", sourceInfo.storePath, sourceInfo.resolvedRef.to_string());
@@ -290,8 +290,6 @@ NonFlake getNonFlake(EvalState & state, const FlakeRef & flakeRef, FlakeAlias al
if (state.allowedPaths)
state.allowedPaths->insert(nonFlake.sourceInfo.storePath);
- nonFlake.alias = alias;
-
return nonFlake;
}
@@ -339,7 +337,7 @@ static std::pair<Flake, FlakeInput> updateLocks(
} else {
if (handleLockFile == AllPure || handleLockFile == TopRefUsesRegistries)
throw Error("cannot update non-flake dependency '%s' in pure mode", id);
- auto nonFlake = getNonFlake(state, ref, id, allowedToUseRegistries(handleLockFile, false));
+ auto nonFlake = getNonFlake(state, ref, allowedToUseRegistries(handleLockFile, false));
newEntry.nonFlakeInputs.insert_or_assign(id,
NonFlakeInput(
nonFlake.sourceInfo.resolvedRef,
@@ -441,6 +439,25 @@ static void prim_callFlake(EvalState & state, const Pos & pos, Value * * args, V
callFlake(state, flake, *lazyFlake, v);
}
+static void prim_callNonFlake(EvalState & state, const Pos & pos, Value * * args, Value & v)
+{
+ auto lazyNonFlake = (NonFlakeInput *) args[0]->attrs;
+
+ auto nonFlake = getNonFlake(state, lazyNonFlake->ref);
+
+ if (nonFlake.sourceInfo.narHash != lazyNonFlake->narHash)
+ throw Error("the content hash of repository '%s' doesn't match the hash recorded in the referring lockfile", nonFlake.sourceInfo.resolvedRef);
+
+ state.mkAttrs(v, 8);
+
+ assert(state.store->isValidPath(nonFlake.sourceInfo.storePath));
+
+ mkString(*state.allocAttr(v, state.sOutPath),
+ nonFlake.sourceInfo.storePath, {nonFlake.sourceInfo.storePath});
+
+ emitSourceInfoAttrs(state, nonFlake.sourceInfo, v);
+}
+
void callFlake(EvalState & state,
const Flake & flake,
const FlakeInputs & inputs,
@@ -468,16 +485,15 @@ void callFlake(EvalState & state,
for (auto & dep : inputs.nonFlakeInputs) {
auto vNonFlake = state.allocAttr(v, dep.first);
- state.mkAttrs(*vNonFlake, 8);
-
- auto nonFlake = getNonFlake(state, dep.second.ref, dep.first);
-
- assert(state.store->isValidPath(nonFlake.sourceInfo.storePath));
-
- mkString(*state.allocAttr(*vNonFlake, state.sOutPath),
- nonFlake.sourceInfo.storePath, {nonFlake.sourceInfo.storePath});
-
- emitSourceInfoAttrs(state, nonFlake.sourceInfo, *vNonFlake);
+ auto vPrimOp = state.allocValue();
+ static auto primOp = new PrimOp(prim_callNonFlake, 1, state.symbols.create("callNonFlake"));
+ vPrimOp->type = tPrimOp;
+ vPrimOp->primOp = primOp;
+ auto vArg = state.allocValue();
+ vArg->type = tNull;
+ // FIXME: leak
+ vArg->attrs = (Bindings *) new NonFlakeInput(dep.second); // evil! also inefficient
+ mkApp(*vNonFlake, *vPrimOp, *vArg);
}
mkString(*state.allocAttr(v, state.sDescription), flake.description);
diff --git a/src/libexpr/primops/flake.hh b/src/libexpr/primops/flake.hh
index bbf35da02..b8d0da252 100644
--- a/src/libexpr/primops/flake.hh
+++ b/src/libexpr/primops/flake.hh
@@ -75,7 +75,6 @@ struct Flake
struct NonFlake
{
- FlakeAlias alias;
FlakeRef originalRef;
SourceInfo sourceInfo;
NonFlake(const FlakeRef & origRef, const SourceInfo & sourceInfo)
diff --git a/src/nix/flake.cc b/src/nix/flake.cc
index d229c7512..653154aaa 100644
--- a/src/nix/flake.cc
+++ b/src/nix/flake.cc
@@ -122,6 +122,7 @@ static nlohmann::json flakeToJson(const Flake & flake)
return j;
}
+#if 0
static void printNonFlakeInfo(const NonFlake & nonFlake)
{
std::cout << fmt("ID: %s\n", nonFlake.alias);
@@ -136,7 +137,6 @@ static nlohmann::json nonFlakeToJson(const NonFlake & nonFlake)
return j;
}
-#if 0
// FIXME: merge info CmdFlakeInfo?
struct CmdFlakeDeps : FlakeCommand
{
diff --git a/tests/flakes.sh b/tests/flakes.sh
index f9f8e5272..1cd8259b9 100644
--- a/tests/flakes.sh
+++ b/tests/flakes.sh
@@ -83,7 +83,7 @@ git -C $flake3Dir add flake.nix
git -C $flake3Dir commit -m 'Initial'
cat > $nonFlakeDir/README.md <<EOF
-Not much
+FNORD
EOF
git -C $nonFlakeDir add README.md
@@ -235,23 +235,42 @@ cat > $flake3Dir/flake.nix <<EOF
outputs = inputs: rec {
packages.xyzzy = inputs.flake2.outputs.packages.bar;
packages.sth = inputs.flake1.outputs.packages.foo;
+ packages.fnord =
+ with import ./config.nix;
+ mkDerivation {
+ inherit system;
+ name = "fnord";
+ buildCommand = ''
+ cat \${inputs.nonFlake}/README.md > \$out
+ '';
+ };
};
}
EOF
-git -C $flake3Dir add flake.nix
+cp ./config.nix $flake3Dir
+
+git -C $flake3Dir add flake.nix config.nix
git -C $flake3Dir commit -m 'Add nonFlakeInputs'
-# Check whether `nix build` works with a lockfile which is missing a nonFlakeInputs
+# Check whether `nix build` works with a lockfile which is missing a
+# nonFlakeInputs.
nix build -o $TEST_ROOT/result --flake-registry $registry $flake3Dir:sth
git -C $flake3Dir commit -m 'Update nonFlakeInputs'
+nix build -o $TEST_ROOT/result --flake-registry $registry flake3:fnord
+[[ $(cat $TEST_ROOT/result) = FNORD ]]
+
# Check whether flake input fetching is lazy: flake3:sth does not
# depend on flake2, so this shouldn't fail.
rm -rf $TEST_HOME/.cache
clearStore
mv $flake2Dir $flake2Dir.tmp
+mv $nonFlakeDir $nonFlakeDir.tmp
nix build -o $TEST_ROOT/result --flake-registry $registry flake3:sth
(! nix build -o $TEST_ROOT/result --flake-registry $registry flake3:xyzzy)
+(! nix build -o $TEST_ROOT/result --flake-registry $registry flake3:fnord)
mv $flake2Dir.tmp $flake2Dir
+mv $nonFlakeDir.tmp $nonFlakeDir
+nix build -o $TEST_ROOT/result --flake-registry $registry flake3:xyzzy flake3:fnord