mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-22 05:56:15 +02:00
nix-shell: Look for shell.nix when directory is specified
This commit is contained in:
parent
76245ffbeb
commit
73602a7c6f
5 changed files with 88 additions and 9 deletions
|
@ -2650,7 +2650,7 @@ void EvalState::printStatistics()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SourcePath resolveExprPath(SourcePath path)
|
SourcePath resolveExprPath(SourcePath path, bool addDefaultNix)
|
||||||
{
|
{
|
||||||
unsigned int followCount = 0, maxFollow = 1024;
|
unsigned int followCount = 0, maxFollow = 1024;
|
||||||
|
|
||||||
|
@ -2666,7 +2666,7 @@ SourcePath resolveExprPath(SourcePath path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If `path' refers to a directory, append `/default.nix'. */
|
/* If `path' refers to a directory, append `/default.nix'. */
|
||||||
if (path.resolveSymlinks().lstat().type == SourceAccessor::tDirectory)
|
if (addDefaultNix && path.resolveSymlinks().lstat().type == SourceAccessor::tDirectory)
|
||||||
return path / "default.nix";
|
return path / "default.nix";
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
|
|
|
@ -850,8 +850,10 @@ std::string showType(const Value & v);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If `path` refers to a directory, then append "/default.nix".
|
* If `path` refers to a directory, then append "/default.nix".
|
||||||
|
*
|
||||||
|
* @param addDefaultNix Whether to append "/default.nix" after resolving symlinks.
|
||||||
*/
|
*/
|
||||||
SourcePath resolveExprPath(SourcePath path);
|
SourcePath resolveExprPath(SourcePath path, bool addDefaultNix = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether a URI is allowed, assuming restrictEval is enabled
|
* Whether a URI is allowed, assuming restrictEval is enabled
|
||||||
|
|
|
@ -90,6 +90,26 @@ static std::vector<std::string> shellwords(const std::string & s)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like `resolveExprPath`, but prefers `shell.nix` instead of `default.nix`,
|
||||||
|
* and if `path` was a directory, it checks eagerly whether `shell.nix` or
|
||||||
|
* `default.nix` exist, throwing an error if they don't.
|
||||||
|
*/
|
||||||
|
static SourcePath resolveShellExprPath(SourcePath path)
|
||||||
|
{
|
||||||
|
auto resolvedOrDir = resolveExprPath(path, false);
|
||||||
|
if (resolvedOrDir.resolveSymlinks().lstat().type == SourceAccessor::tDirectory) {
|
||||||
|
if ((resolvedOrDir / "shell.nix").pathExists()) {
|
||||||
|
return resolvedOrDir / "shell.nix";
|
||||||
|
}
|
||||||
|
if ((resolvedOrDir / "default.nix").pathExists()) {
|
||||||
|
return resolvedOrDir / "default.nix";
|
||||||
|
}
|
||||||
|
throw Error("neither '%s' nor '%s' found in '%s'", "shell.nix", "default.nix", resolvedOrDir);
|
||||||
|
}
|
||||||
|
return resolvedOrDir;
|
||||||
|
}
|
||||||
|
|
||||||
static void main_nix_build(int argc, char * * argv)
|
static void main_nix_build(int argc, char * * argv)
|
||||||
{
|
{
|
||||||
auto dryRun = false;
|
auto dryRun = false;
|
||||||
|
@ -281,11 +301,12 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
joined << "]; } \"\"";
|
joined << "]; } \"\"";
|
||||||
fromArgs = true;
|
fromArgs = true;
|
||||||
remainingArgs = {joined.str()};
|
remainingArgs = {joined.str()};
|
||||||
} else if (!fromArgs) {
|
} else if (!fromArgs && remainingArgs.empty()) {
|
||||||
if (remainingArgs.empty() && isNixShell && pathExists("shell.nix"))
|
remainingArgs = {"."};
|
||||||
remainingArgs = {"shell.nix"};
|
|
||||||
if (remainingArgs.empty())
|
// Instead of letting it throw later, we throw here to give a more relevant error message
|
||||||
remainingArgs = {"default.nix"};
|
if (isNixShell && !std::filesystem::exists("shell.nix") && !std::filesystem::exists("default.nix"))
|
||||||
|
throw Error("no argument specified and no '%s' or '%s' file found in the working directory", "shell.nix", "default.nix");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNixShell)
|
if (isNixShell)
|
||||||
|
@ -317,7 +338,8 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
|
|
||||||
auto sourcePath = lookupFileArg(*state,
|
auto sourcePath = lookupFileArg(*state,
|
||||||
baseDir);
|
baseDir);
|
||||||
auto resolvedPath = resolveExprPath(sourcePath);
|
auto resolvedPath =
|
||||||
|
isNixShell ? resolveShellExprPath(sourcePath) : resolveExprPath(sourcePath);
|
||||||
|
|
||||||
exprs.push_back(state->parseExprFromFile(resolvedPath));
|
exprs.push_back(state->parseExprFromFile(resolvedPath));
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,50 @@ sed -e "s|@ENV_PROG@|$(type -P env)|" shell.shebang.nix > $TEST_ROOT/shell.sheba
|
||||||
chmod a+rx $TEST_ROOT/shell.shebang.nix
|
chmod a+rx $TEST_ROOT/shell.shebang.nix
|
||||||
$TEST_ROOT/shell.shebang.nix
|
$TEST_ROOT/shell.shebang.nix
|
||||||
|
|
||||||
|
mkdir $TEST_ROOT/lookup-test $TEST_ROOT/empty
|
||||||
|
|
||||||
|
echo "import $shellDotNix" > $TEST_ROOT/lookup-test/shell.nix
|
||||||
|
cp config.nix $TEST_ROOT/lookup-test/
|
||||||
|
echo 'abort "do not load default.nix!"' > $TEST_ROOT/lookup-test/default.nix
|
||||||
|
|
||||||
|
nix-shell $TEST_ROOT/lookup-test -A shellDrv --run 'echo "it works"' | grepQuiet "it works"
|
||||||
|
# https://github.com/NixOS/nix/issues/4529
|
||||||
|
nix-shell -I "testRoot=$TEST_ROOT" '<testRoot/lookup-test>' -A shellDrv --run 'echo "it works"' | grepQuiet "it works"
|
||||||
|
|
||||||
|
(
|
||||||
|
cd $TEST_ROOT/empty;
|
||||||
|
expectStderr 1 nix-shell | \
|
||||||
|
grepQuiet "error.*no argument specified and no .*shell\.nix.* or .*default\.nix.* file found in the working directory"
|
||||||
|
)
|
||||||
|
|
||||||
|
expectStderr 1 nix-shell -I "testRoot=$TEST_ROOT" '<testRoot/empty>' |
|
||||||
|
grepQuiet "error.*neither .*shell\.nix.* nor .*default\.nix.* found in .*/empty"
|
||||||
|
|
||||||
|
cat >$TEST_ROOT/lookup-test/shebangscript <<EOF
|
||||||
|
#!$(type -P env) nix-shell
|
||||||
|
#!nix-shell -A shellDrv -i bash
|
||||||
|
[[ \$VAR_FROM_NIX == bar ]]
|
||||||
|
echo "script works"
|
||||||
|
EOF
|
||||||
|
chmod +x $TEST_ROOT/lookup-test/shebangscript
|
||||||
|
|
||||||
|
$TEST_ROOT/lookup-test/shebangscript | grepQuiet "script works"
|
||||||
|
|
||||||
|
# https://github.com/NixOS/nix/issues/5431
|
||||||
|
mkdir $TEST_ROOT/marco{,/polo}
|
||||||
|
echo 'abort "marco/shell.nix must not be used, but its mere existence used to cause #5431"' > $TEST_ROOT/marco/shell.nix
|
||||||
|
cat >$TEST_ROOT/marco/polo/default.nix <<EOF
|
||||||
|
#!$(type -P env) nix-shell
|
||||||
|
(import $TEST_ROOT/lookup-test/shell.nix {}).polo
|
||||||
|
EOF
|
||||||
|
chmod a+x $TEST_ROOT/marco/polo/default.nix
|
||||||
|
(cd $TEST_ROOT/marco && ./polo/default.nix | grepQuiet "Polo")
|
||||||
|
|
||||||
|
|
||||||
|
#####################
|
||||||
|
# Flake equivalents #
|
||||||
|
#####################
|
||||||
|
|
||||||
# Test 'nix develop'.
|
# Test 'nix develop'.
|
||||||
nix develop -f "$shellDotNix" shellDrv -c bash -c '[[ -n $stdenv ]]'
|
nix develop -f "$shellDotNix" shellDrv -c bash -c '[[ -n $stdenv ]]'
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,17 @@ let pkgs = rec {
|
||||||
TEST_inNixShell = if inNixShell then "true" else "false";
|
TEST_inNixShell = if inNixShell then "true" else "false";
|
||||||
inherit stdenv;
|
inherit stdenv;
|
||||||
outputs = ["dev" "out"];
|
outputs = ["dev" "out"];
|
||||||
|
} // {
|
||||||
|
shellHook = abort "Ignore non-drv shellHook attr";
|
||||||
|
};
|
||||||
|
|
||||||
|
# https://github.com/NixOS/nix/issues/5431
|
||||||
|
# See nix-shell.sh
|
||||||
|
polo = mkDerivation {
|
||||||
|
name = "polo";
|
||||||
|
shellHook = ''
|
||||||
|
echo Polo
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Used by nix-shell -p
|
# Used by nix-shell -p
|
||||||
|
|
Loading…
Reference in a new issue