From 56605b468868b834e44a9700907b734428cb120a Mon Sep 17 00:00:00 2001 From: regnat Date: Thu, 20 May 2021 13:55:00 +0200 Subject: [PATCH 1/2] Make `nix-shell` support content-addressed derivations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/nix-build/nix-build.cc | 7 +++++++ tests/ca/nix-shell.sh | 10 ++++++++++ tests/local.mk | 1 + tests/nix-shell.sh | 14 ++++++++++---- tests/shell.nix | 16 ++++++++++++++-- 5 files changed, 42 insertions(+), 6 deletions(-) create mode 100755 tests/ca/nix-shell.sh 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" '' From 3b58dbb3561e02dc94e88b531d0942a7f8ccf8ea Mon Sep 17 00:00:00 2001 From: regnat Date: Tue, 22 Jun 2021 11:29:55 +0200 Subject: [PATCH 2/2] nix-shell: Replace resolving failure error by an assertion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This shouldn’t happen in practice, so better make it explicit --- src/nix-build/nix-build.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 05eb7e234..3fec2c06c 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -389,8 +389,7 @@ static void main_nix_build(int argc, char * * argv) 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()); + assert(resolvedDrv && "Successfully resolved the derivation"); drv = *resolvedDrv; }