diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc index 62745b681..ffc1ebd59 100644 --- a/src/libcmd/common-eval-args.cc +++ b/src/libcmd/common-eval-args.cc @@ -202,7 +202,7 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state) auto v = state.allocValue(); std::visit(overloaded { [&](const AutoArgExpr & arg) { - state.mkThunk_(*v, state.parseExprFromString(arg.expr, state.rootPath("."))); + state.mkThunk_(*v, state.parseExprFromString(arg.expr, true ? state.rootPath(absPath(getCommandBaseDir())) : state.rootPath("."))); }, [&](const AutoArgString & arg) { v->mkString(arg.s); diff --git a/src/libutil/args/root.hh b/src/libutil/args/root.hh index 5c55c37a5..34a43b538 100644 --- a/src/libutil/args/root.hh +++ b/src/libutil/args/root.hh @@ -29,6 +29,7 @@ struct Completions final : AddCompletions */ class RootArgs : virtual public Args { +protected: /** * @brief The command's "working directory", but only set when top level. * diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 872295045..cfe183888 100644 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -183,6 +183,9 @@ static void main_nix_build(int argc, char * * argv) struct MyArgs : LegacyArgs, MixEvalArgs { using LegacyArgs::LegacyArgs; + void setBaseDir(Path baseDir) { + commandBaseDir = baseDir; + } }; MyArgs myArgs(myName, [&](Strings::iterator & arg, const Strings::iterator & end) { @@ -290,6 +293,9 @@ static void main_nix_build(int argc, char * * argv) state->repair = myArgs.repair; if (myArgs.repair) buildMode = bmRepair; + if (inShebang) { + myArgs.setBaseDir(absPath(dirOf(script))); + } auto autoArgs = myArgs.getAutoArgs(*state); auto autoArgsWithInNixShell = autoArgs; diff --git a/tests/functional/nix-shell.sh b/tests/functional/nix-shell.sh index f881acd03..596ac5951 100755 --- a/tests/functional/nix-shell.sh +++ b/tests/functional/nix-shell.sh @@ -72,8 +72,9 @@ chmod a+rx $TEST_ROOT/shell.shebang.expr ! $TEST_ROOT/shell.shebang.expr bar cp shell.nix config.nix $TEST_ROOT # Should succeed +echo "cwd: $PWD" output=$($TEST_ROOT/shell.shebang.expr bar) -[ "$output" = '-e load(ARGV.shift) -- '"$TEST_ROOT"'/shell.shebang.expr bar' ] +[ "$output" = foo ] # 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. diff --git a/tests/functional/shell.nix b/tests/functional/shell.nix index 75e3845ea..a7577ff63 100644 --- a/tests/functional/shell.nix +++ b/tests/functional/shell.nix @@ -43,6 +43,7 @@ let pkgs = rec { ASCII_PERCENT = "%"; ASCII_AT = "@"; TEST_inNixShell = if inNixShell then "true" else "false"; + FOO = fooContents; inherit stdenv; outputs = ["dev" "out"]; } // { diff --git a/tests/functional/shell.shebang.expr b/tests/functional/shell.shebang.expr new file mode 100755 index 000000000..c602dedbf --- /dev/null +++ b/tests/functional/shell.shebang.expr @@ -0,0 +1,9 @@ +#! @ENV_PROG@ nix-shell +#! nix-shell "{ script, path, ... }: assert path == ./shell.nix; script { }" +#! nix-shell --no-substitute +#! nix-shell --expr +#! nix-shell --arg script "import ./shell.nix" +#! nix-shell --arg path "./shell.nix" +#! nix-shell -A shellDrv +#! nix-shell -i bash +echo "$FOO"