nix-shell: Add NIX_SHELL_LEVEL variable

This contains the depth of nix shells nesting.

Fixes #826

Co-authored-by: Qyriad <qyriad@qyriad.me>

Change-Id: If584c9d02730d6c857636dafdeab0c01f4ec8e0f
This commit is contained in:
Tom Hubrecht
2025-12-01 12:02:45 +00:00
parent 0c6d299e16
commit 1bfbbe2415
4 changed files with 33 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
---
synopsis: "Add an indication of nix-shell nesting depth"
cls: [4657]
issues: [fj#826]
category: "Improvements"
credits: [thubrecht]
---
When in a nix shell (either via a `nix-shell` or a `nix develop` invocation), a variable `NIX_SHELL_LEVEL` is exported to indicate the nesting depth of nix shells.
+9
View File
@@ -25,6 +25,7 @@
#include "lix/libutil/shlex.hh"
#include "nix-build.hh"
#include "lix/libstore/temporary-dir.hh"
#include "lix/libutil/strings.hh"
extern char * * environ __attribute__((weak)); // Man what even is this
@@ -425,6 +426,14 @@ static int main_nix_build(AsyncIoRoot & aio, std::string programName, Strings ar
env["__ETC_PROFILE_SOURCED"] = "1";
}
// Set NIX_SHELL_LEVEL
env["NIX_SHELL_LEVEL"] = std::to_string(
getEnvNonEmpty("NIX_SHELL_LEVEL")
.and_then([](std::string lvl) { return string2Int<size_t>(lvl); })
.value_or(0)
+ 1
);
// Don't use defaultTempDir() here! We want to preserve the user's TMPDIR for the shell
env["NIX_BUILD_TOP"] = env["TMPDIR"] = env["TEMPDIR"] = env["TMP"] = env["TEMP"] =
getEnvNonEmpty("TMPDIR").value_or(buildTopTmpDir);
+4
View File
@@ -356,6 +356,10 @@ struct Common : InstallableCommand, MixProfile
buildEnvironment.toBash(out, ignoreVars);
// Add NIX_SHELL_LEVEL
out << "printf -v NIX_SHELL_LEVEL \"%d\" \"${NIX_SHELL_LEVEL:-0}\" || NIX_SHELL_LEVEL=0\n";
out << "export NIX_SHELL_LEVEL=$(( NIX_SHELL_LEVEL + 1 ))\n";
for (auto & var : savedVars)
out << fmt("%s=\"$%s${nix_saved_%s:+:$nix_saved_%s}\"\n", var, var, var, var);
+11
View File
@@ -150,6 +150,17 @@ struct CmdShell : InstallablesCommand, MixEnvironment
auto unixPathString = concatStringsSep(":", unixPath);
(void) sys::setenv("PATH", unixPathString, 1);
(void) sys::setenv("IN_NIX_SHELL", ignoreEnvironment ? "pure" : "impure", 1);
// Set NIX_SHELL_LEVEL
(void) sys::setenv(
"NIX_SHELL_LEVEL",
std::to_string(
getEnvNonEmpty("NIX_SHELL_LEVEL")
.and_then([](std::string lvl) { return string2Int<size_t>(lvl); })
.value_or(0)
+ 1
),
1
);
Strings args;
for (auto & arg : command) args.push_back(arg);