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
This commit is contained in:
regnat 2021-05-20 13:55:00 +02:00
parent 8e6ee1b9e9
commit 56605b4688
5 changed files with 42 additions and 6 deletions

View file

@ -387,6 +387,13 @@ static void main_nix_build(int argc, char * * argv)
if (dryRun) return; 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 cant continue", drvInfo.queryDrvPath());
drv = *resolvedDrv;
}
// Set the environment. // Set the environment.
auto env = getEnv(); auto env = getEnv();

10
tests/ca/nix-shell.sh Executable file
View file

@ -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

View file

@ -47,6 +47,7 @@ nix_tests = \
ca/build.sh \ ca/build.sh \
ca/substitute.sh \ ca/substitute.sh \
ca/signatures.sh \ ca/signatures.sh \
ca/nix-shell.sh \
ca/nix-run.sh \ ca/nix-run.sh \
ca/nix-copy.sh ca/nix-copy.sh
# parallel.sh # parallel.sh

View file

@ -2,6 +2,12 @@ source common.sh
clearStore clearStore
if [[ -n ${CONTENT_ADDRESSED:-} ]]; then
nix-shell () {
command nix-shell --arg contentAddressed true "$@"
}
fi
# Test nix-shell -A # Test nix-shell -A
export IMPURE_VAR=foo export IMPURE_VAR=foo
export SELECTED_IMPURE_VAR=baz 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" ] [ "$output" = "foo bar" ]
# Test nix-shell shebang mode # 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 chmod a+rx $TEST_ROOT/shell.shebang.sh
output=$($TEST_ROOT/shell.shebang.sh abc def) 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. # 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. # 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 chmod a+rx $TEST_ROOT/spaced\ \\\'\"shell.shebang.sh
output=$($TEST_ROOT/spaced\ \\\'\"shell.shebang.sh abc def) 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 # Test nix-shell shebang mode for ruby
# This uses a fake interpreter that returns the arguments passed # 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. # 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 chmod a+rx $TEST_ROOT/shell.shebang.rb
output=$($TEST_ROOT/shell.shebang.rb abc ruby) 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. # 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. # 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 chmod a+rx $TEST_ROOT/spaced\ \\\'\"shell.shebang.rb
output=$($TEST_ROOT/spaced\ \\\'\"shell.shebang.rb abc ruby) output=$($TEST_ROOT/spaced\ \\\'\"shell.shebang.rb abc ruby)

View file

@ -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 { let pkgs = rec {
setupSh = builtins.toFile "setup" '' setupSh = builtins.toFile "setup" ''