aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorregnat <rg@regnat.ovh>2021-05-20 13:55:00 +0200
committerregnat <rg@regnat.ovh>2021-06-11 13:32:49 +0200
commit56605b468868b834e44a9700907b734428cb120a (patch)
treeb0117083df01f50aafd8186cc048082721e99ef1
parent8e6ee1b9e924fbbbeb5594eb89e7a570f36ab6e1 (diff)
Make `nix-shell` support content-addressed derivations
Resolve the derivation before trying to load its environment − essentially reproducing what the build loop does − so that we can effectively access our dependencies (and not just their placeholders). Fix #4821
-rwxr-xr-xsrc/nix-build/nix-build.cc7
-rwxr-xr-xtests/ca/nix-shell.sh10
-rw-r--r--tests/local.mk1
-rw-r--r--tests/nix-shell.sh14
-rw-r--r--tests/shell.nix16
5 files changed, 42 insertions, 6 deletions
diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc
index 9acbedda2..05eb7e234 100755
--- a/src/nix-build/nix-build.cc
+++ b/src/nix-build/nix-build.cc
@@ -387,6 +387,13 @@ static void main_nix_build(int argc, char * * argv)
if (dryRun) return;
+ if (settings.isExperimentalFeatureEnabled("ca-derivations")) {
+ auto resolvedDrv = drv.tryResolve(*store);
+ if (!resolvedDrv)
+ throw Error("unable to resolve the derivation '%s'. nix-shell can’t continue", drvInfo.queryDrvPath());
+ drv = *resolvedDrv;
+ }
+
// Set the environment.
auto env = getEnv();
diff --git a/tests/ca/nix-shell.sh b/tests/ca/nix-shell.sh
new file mode 100755
index 000000000..7f1a3a73e
--- /dev/null
+++ b/tests/ca/nix-shell.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+source common.sh
+
+sed -i 's/experimental-features .*/& ca-derivations ca-references nix-command flakes/' "$NIX_CONF_DIR"/nix.conf
+
+CONTENT_ADDRESSED=true
+cd ..
+source ./nix-shell.sh
+
diff --git a/tests/local.mk b/tests/local.mk
index 59eb4eb0f..d640bdd3c 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -47,6 +47,7 @@ nix_tests = \
ca/build.sh \
ca/substitute.sh \
ca/signatures.sh \
+ ca/nix-shell.sh \
ca/nix-run.sh \
ca/nix-copy.sh
# parallel.sh
diff --git a/tests/nix-shell.sh b/tests/nix-shell.sh
index 4775bafb9..e3174dac1 100644
--- a/tests/nix-shell.sh
+++ b/tests/nix-shell.sh
@@ -2,6 +2,12 @@ source common.sh
clearStore
+if [[ -n ${CONTENT_ADDRESSED:-} ]]; then
+ nix-shell () {
+ command nix-shell --arg contentAddressed true "$@"
+ }
+fi
+
# Test nix-shell -A
export IMPURE_VAR=foo
export SELECTED_IMPURE_VAR=baz
@@ -41,7 +47,7 @@ output=$(NIX_PATH=nixpkgs=shell.nix nix-shell --pure -p foo bar --run 'echo "$(f
[ "$output" = "foo bar" ]
# Test nix-shell shebang mode
-sed -e "s|@ENV_PROG@|$(type -p env)|" shell.shebang.sh > $TEST_ROOT/shell.shebang.sh
+sed -e "s|@ENV_PROG@|$(type -P env)|" shell.shebang.sh > $TEST_ROOT/shell.shebang.sh
chmod a+rx $TEST_ROOT/shell.shebang.sh
output=$($TEST_ROOT/shell.shebang.sh abc def)
@@ -49,7 +55,7 @@ output=$($TEST_ROOT/shell.shebang.sh abc def)
# Test nix-shell shebang mode again with metacharacters in the filename.
# First word of filename is chosen to not match any file in the test root.
-sed -e "s|@ENV_PROG@|$(type -p env)|" shell.shebang.sh > $TEST_ROOT/spaced\ \\\'\"shell.shebang.sh
+sed -e "s|@ENV_PROG@|$(type -P env)|" shell.shebang.sh > $TEST_ROOT/spaced\ \\\'\"shell.shebang.sh
chmod a+rx $TEST_ROOT/spaced\ \\\'\"shell.shebang.sh
output=$($TEST_ROOT/spaced\ \\\'\"shell.shebang.sh abc def)
@@ -58,7 +64,7 @@ output=$($TEST_ROOT/spaced\ \\\'\"shell.shebang.sh abc def)
# Test nix-shell shebang mode for ruby
# This uses a fake interpreter that returns the arguments passed
# This, in turn, verifies the `rc` script is valid and the `load()` script (given using `-e`) is as expected.
-sed -e "s|@SHELL_PROG@|$(type -p nix-shell)|" shell.shebang.rb > $TEST_ROOT/shell.shebang.rb
+sed -e "s|@SHELL_PROG@|$(type -P nix-shell)|" shell.shebang.rb > $TEST_ROOT/shell.shebang.rb
chmod a+rx $TEST_ROOT/shell.shebang.rb
output=$($TEST_ROOT/shell.shebang.rb abc ruby)
@@ -66,7 +72,7 @@ output=$($TEST_ROOT/shell.shebang.rb abc ruby)
# Test nix-shell shebang mode for ruby again with metacharacters in the filename.
# Note: fake interpreter only space-separates args without adding escapes to its output.
-sed -e "s|@SHELL_PROG@|$(type -p nix-shell)|" shell.shebang.rb > $TEST_ROOT/spaced\ \\\'\"shell.shebang.rb
+sed -e "s|@SHELL_PROG@|$(type -P nix-shell)|" shell.shebang.rb > $TEST_ROOT/spaced\ \\\'\"shell.shebang.rb
chmod a+rx $TEST_ROOT/spaced\ \\\'\"shell.shebang.rb
output=$($TEST_ROOT/spaced\ \\\'\"shell.shebang.rb abc ruby)
diff --git a/tests/shell.nix b/tests/shell.nix
index 24ebcc04c..53759f99a 100644
--- a/tests/shell.nix
+++ b/tests/shell.nix
@@ -1,6 +1,18 @@
-{ inNixShell ? false }:
+{ inNixShell ? false, contentAddressed ? false }:
-with import ./config.nix;
+let cfg = import ./config.nix; in
+with cfg;
+
+let
+ mkDerivation =
+ if contentAddressed then
+ args: cfg.mkDerivation ({
+ __contentAddressed = true;
+ outputHashMode = "recursive";
+ outputHashAlgo = "sha256";
+ } // args)
+ else cfg.mkDerivation;
+in
let pkgs = rec {
setupSh = builtins.toFile "setup" ''