mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-25 15:26:17 +02:00
nix: Add command baseDir to parse --expr relative to shebang script
This commit is contained in:
parent
20ff61ab25
commit
198bc22e3b
5 changed files with 51 additions and 1 deletions
|
@ -4,6 +4,7 @@
|
||||||
contents of any `#! nix` lines and the script's location to a single call.
|
contents of any `#! nix` lines and the script's location to a single call.
|
||||||
|
|
||||||
Verbatim strings may be passed in double backtick (```` `` ````) quotes.
|
Verbatim strings may be passed in double backtick (```` `` ````) quotes.
|
||||||
|
`--expr` resolves relative paths based on the shebang script location.
|
||||||
|
|
||||||
Some examples:
|
Some examples:
|
||||||
```
|
```
|
||||||
|
|
|
@ -445,7 +445,8 @@ Installables SourceExprCommand::parseInstallables(
|
||||||
else if (file)
|
else if (file)
|
||||||
state->evalFile(lookupFileArg(*state, *file), *vFile);
|
state->evalFile(lookupFileArg(*state, *file), *vFile);
|
||||||
else {
|
else {
|
||||||
auto e = state->parseExprFromString(*expr, state->rootPath(CanonPath::fromCwd()));
|
CanonPath dir(CanonPath::fromCwd(getCommandBaseDir()));
|
||||||
|
auto e = state->parseExprFromString(*expr, state->rootPath(dir));
|
||||||
state->eval(e, *vFile);
|
state->eval(e, *vFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -276,6 +276,7 @@ void Args::parseCmdline(const Strings & _cmdline, bool allowShebang)
|
||||||
cmdline.push_back(word);
|
cmdline.push_back(word);
|
||||||
}
|
}
|
||||||
cmdline.push_back(script);
|
cmdline.push_back(script);
|
||||||
|
commandBaseDir = dirOf(script);
|
||||||
for (auto pos = savedArgs.begin(); pos != savedArgs.end();pos++)
|
for (auto pos = savedArgs.begin(); pos != savedArgs.end();pos++)
|
||||||
cmdline.push_back(*pos);
|
cmdline.push_back(*pos);
|
||||||
}
|
}
|
||||||
|
@ -336,6 +337,14 @@ void Args::parseCmdline(const Strings & _cmdline, bool allowShebang)
|
||||||
d.completer(*completions, d.n, d.prefix);
|
d.completer(*completions, d.n, d.prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Path Args::getCommandBaseDir() const
|
||||||
|
{
|
||||||
|
if (parent)
|
||||||
|
return parent->getCommandBaseDir();
|
||||||
|
else
|
||||||
|
return commandBaseDir;
|
||||||
|
}
|
||||||
|
|
||||||
bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
|
bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
|
||||||
{
|
{
|
||||||
assert(pos != end);
|
assert(pos != end);
|
||||||
|
|
|
@ -24,6 +24,16 @@ class AddCompletions;
|
||||||
|
|
||||||
class Args
|
class Args
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @brief The command's "working directory", but only set when top level.
|
||||||
|
*
|
||||||
|
* Use getCommandBaseDir() to get the directory regardless of whether this
|
||||||
|
* is a top-level command or subcommand.
|
||||||
|
*
|
||||||
|
* @see getCommandBaseDir()
|
||||||
|
*/
|
||||||
|
Path commandBaseDir = ".";
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +54,16 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual std::string doc() { return ""; }
|
virtual std::string doc() { return ""; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the base directory for the command.
|
||||||
|
*
|
||||||
|
* @return Generally the working directory, but in case of a shebang
|
||||||
|
* interpreter, returns the directory of the script.
|
||||||
|
*
|
||||||
|
* This only returns the correct value after parseCmdline() has run.
|
||||||
|
*/
|
||||||
|
Path getCommandBaseDir() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -105,6 +105,24 @@ foo
|
||||||
EOF
|
EOF
|
||||||
chmod +x $nonFlakeDir/shebang-reject.sh
|
chmod +x $nonFlakeDir/shebang-reject.sh
|
||||||
|
|
||||||
|
cat > $nonFlakeDir/shebang-inline-expr.sh <<EOF
|
||||||
|
#! $(type -P env) nix
|
||||||
|
EOF
|
||||||
|
cat >> $nonFlakeDir/shebang-inline-expr.sh <<"EOF"
|
||||||
|
#! nix --offline shell
|
||||||
|
#! nix --impure --expr ``
|
||||||
|
#! nix let flake = (builtins.getFlake (toString ../flake1)).packages;
|
||||||
|
#! nix fooScript = flake.${builtins.currentSystem}.fooScript;
|
||||||
|
#! nix /* just a comment !@#$%^&*()__+ # */
|
||||||
|
#! nix in fooScript
|
||||||
|
#! nix ``
|
||||||
|
#! nix --no-write-lock-file --command bash
|
||||||
|
set -ex
|
||||||
|
foo
|
||||||
|
echo "$@"
|
||||||
|
EOF
|
||||||
|
chmod +x $nonFlakeDir/shebang-inline-expr.sh
|
||||||
|
|
||||||
# Construct a custom registry, additionally test the --registry flag
|
# Construct a custom registry, additionally test the --registry flag
|
||||||
nix registry add --registry "$registry" flake1 "git+file://$flake1Dir"
|
nix registry add --registry "$registry" flake1 "git+file://$flake1Dir"
|
||||||
nix registry add --registry "$registry" flake2 "git+file://$percentEncodedFlake2Dir"
|
nix registry add --registry "$registry" flake2 "git+file://$percentEncodedFlake2Dir"
|
||||||
|
@ -552,4 +570,5 @@ expectStderr 1 nix flake metadata "$flake2Dir" --no-allow-dirty --reference-lock
|
||||||
[[ $($nonFlakeDir/shebang.sh) = "foo" ]]
|
[[ $($nonFlakeDir/shebang.sh) = "foo" ]]
|
||||||
[[ $($nonFlakeDir/shebang.sh "bar") = "foo"$'\n'"bar" ]]
|
[[ $($nonFlakeDir/shebang.sh "bar") = "foo"$'\n'"bar" ]]
|
||||||
[[ $($nonFlakeDir/shebang-comments.sh ) = "foo" ]]
|
[[ $($nonFlakeDir/shebang-comments.sh ) = "foo" ]]
|
||||||
|
[[ $($nonFlakeDir/shebang-inline-expr.sh baz) = "foo"$'\n'"baz" ]]
|
||||||
expect 1 $nonFlakeDir/shebang-reject.sh 2>&1 | grepQuiet -F 'error: unsupported unquoted character in nix shebang: *. Use double backticks to escape?'
|
expect 1 $nonFlakeDir/shebang-reject.sh 2>&1 | grepQuiet -F 'error: unsupported unquoted character in nix shebang: *. Use double backticks to escape?'
|
||||||
|
|
Loading…
Reference in a new issue