Skip to content

Commit

Permalink
Make nix-shell support content-addressed derivations
Browse files Browse the repository at this point in the history
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
  • Loading branch information
thufschmitt committed May 20, 2021
1 parent af4ff64 commit 73957a6
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 6 deletions.
7 changes: 7 additions & 0 deletions src/nix-build/nix-build.cc
Expand Up @@ -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();

Expand Down
10 changes: 10 additions & 0 deletions 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

1 change: 1 addition & 0 deletions tests/local.mk
Expand Up @@ -46,6 +46,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
Expand Down
14 changes: 10 additions & 4 deletions tests/nix-shell.sh
Expand Up @@ -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
Expand Down Expand Up @@ -41,15 +47,15 @@ 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)
[ "$output" = "foo bar 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)
Expand All @@ -58,15 +64,15 @@ 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)
[ "$output" = '-e load(ARGV.shift) -- '"$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)
Expand Down
16 changes: 14 additions & 2 deletions 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" ''
Expand Down

0 comments on commit 73957a6

Please sign in to comment.