Skip to content

Commit

Permalink
feat: adds --relative flag for relative path resolution in shebangs
Browse files Browse the repository at this point in the history
  • Loading branch information
tomberek committed Jan 22, 2024
1 parent f66f498 commit 2fd7ee2
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 6 deletions.
5 changes: 5 additions & 0 deletions doc/manual/src/command-ref/nix-shell.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
[`--exclude` *regexp*]
[`--pure`]
[`--keep` *name*]
[`--relative`]
{{`--packages` | `-p`} {*packages* | *expressions*} … | [*path*]}

# Disambiguation
Expand Down Expand Up @@ -101,6 +102,10 @@ All options not listed here are passed to `nix-store
When a `--pure` shell is started, keep the listed environment
variables.

- `--relative`\
If this flag is specified when using the shebang feature, relative paths
will be resolved relative to the script's location.

{{#include ./opt-common.md}}

# Environment variables
Expand Down
8 changes: 6 additions & 2 deletions src/nix-build/nix-build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ static void main_nix_build(int argc, char * * argv)
auto myName = runEnv ? "nix-shell" : "nix-build";

auto inShebang = false;
auto inShebangRelative = false;
std::string script;
std::vector<std::string> savedArgs;

Expand Down Expand Up @@ -206,6 +207,9 @@ static void main_nix_build(int argc, char * * argv)
else if (runEnv && (*arg == "--packages" || *arg == "-p"))
packages = true;

else if (inShebang && (*arg == "--relative")) {
inShebangRelative = true;
}
else if (inShebang && *arg == "-i") {
auto interpreter = getArg(*arg, arg, end);
interactive = false;
Expand Down Expand Up @@ -300,7 +304,7 @@ static void main_nix_build(int argc, char * * argv)
if (fromArgs)
exprs.push_back(state->parseExprFromString(
std::move(i),
state->rootPath(CanonPath::fromCwd(inShebang ? dirOf(script) : "."))));
state->rootPath(CanonPath::fromCwd((inShebang && inShebangRelative) ? dirOf(script) : "."))));
else {
auto absolute = i;
try {
Expand All @@ -313,7 +317,7 @@ static void main_nix_build(int argc, char * * argv)
/* If we're in a #! script, interpret filenames
relative to the script. */
exprs.push_back(state->parseExprFromFile(resolveExprPath(state->checkSourcePath(lookupFileArg(*state,
inShebang ? absPath(i, absPath(dirOf(script))) : i)))));
(inShebang && inShebangRelative) ? absPath(i, absPath(dirOf(script))) : i)))));
}
}

Expand Down
16 changes: 12 additions & 4 deletions tests/functional/nix-shell.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,21 @@ output=$($TEST_ROOT/shell.shebang.sh abc def)

# Test nix-shell shebang mode with an alternate working directory
sed -e "s|@ENV_PROG@|$(type -P env)|" shell.shebang.expr > $TEST_ROOT/shell.shebang.expr
chmod a+rx $TEST_ROOT/shell.shebang.expr
sed -e "s|nix-shell -E|nix-shell --relative -E|" \
-e "s|@ENV_PROG@|$(type -P env)|" \
shell.shebang.expr > $TEST_ROOT/shell.shebang.expr.relative
chmod a+rx $TEST_ROOT/shell.shebang.expr{,.relative}
# Should fail due to expressions using relative path
pushd ..
! $TEST_ROOT/shell.shebang.expr bar
popd
cp shell.nix config.nix $TEST_ROOT
# Should succeed
output=$($TEST_ROOT/shell.shebang.expr bar)
[ "$output" = '-e load(ARGV.shift) -- '"$TEST_ROOT"'/shell.shebang.expr bar' ]
# Should fail
pushd ..
! $TEST_ROOT/shell.shebang.expr bar
output=$($TEST_ROOT/shell.shebang.expr.relative bar)
popd
[ "$output" = '-e load(ARGV.shift) -- '"$TEST_ROOT"'/shell.shebang.expr.relative bar' ]

# 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.
Expand Down
4 changes: 4 additions & 0 deletions tests/functional/shell.shebang.expr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#! @ENV_PROG@ nix-shell
#! nix-shell -E "with (import ./shell.nix {}); runCommand \"hi\" {buildInputs = [ruby];} \"\""
#! nix-shell --pure -i ruby
puts ARGV[1]

0 comments on commit 2fd7ee2

Please sign in to comment.