From 7928669ef9d6a86dc16932722f3f2596763fd013 Mon Sep 17 00:00:00 2001 From: Ersei Saggi Date: Mon, 3 Mar 2025 11:37:56 -0500 Subject: [PATCH] Detect if in Nix3 shell This replicates behaviour found in the Nix2 commands, where IN_NIX_SHELL is set. This is for shells to determine whether they are inside of a Nix3 shell, and set a custom prompt accordingly. For example, Fish's Tide prompt framework checks for that environment variable and displays it in the prompt, indicating that the shell is in a Nix environment. This is not new behaviour, and the old Nix2 commands set the variable. If the shell that is created is a "pure" shell, ie --ignore-environment is passed, then IN_NIX_SHELL will be set to "pure". However, "nix develop" will always create an impure environment. Replicated from my Nix PR: https://github.com/NixOS/nix/pull/8885 Change-Id: I695cdc336f76541940a302835124fe7d8f7f39b2 Signed-off-by: Ersei Saggi --- doc/manual/change-authors.yml | 4 ++++ doc/manual/rl-next/detect-if-in-nix3-shell.md | 11 +++++++++++ lix/nix/run.cc | 1 + tests/functional/flakes/develop.sh | 4 ++++ tests/functional/shell.sh | 4 ++++ 5 files changed, 24 insertions(+) create mode 100644 doc/manual/rl-next/detect-if-in-nix3-shell.md diff --git a/doc/manual/change-authors.yml b/doc/manual/change-authors.yml index d62684598..91a4eb898 100644 --- a/doc/manual/change-authors.yml +++ b/doc/manual/change-authors.yml @@ -12,6 +12,10 @@ forgejo: rbt github: 9999years +9p4: + display_name: Ersei Saggi + github: 9p4 + Artturin: github: Artturin diff --git a/doc/manual/rl-next/detect-if-in-nix3-shell.md b/doc/manual/rl-next/detect-if-in-nix3-shell.md new file mode 100644 index 000000000..e3b947bb6 --- /dev/null +++ b/doc/manual/rl-next/detect-if-in-nix3-shell.md @@ -0,0 +1,11 @@ +--- +synopsis: Add a straightforward way to detect if in a Nix3 Shell +issues: [nix#6677, nix#3862] +cls: [2090] +category: Fixes +credits: [9p4] +--- + +Running `nix shell` or `nix develop` will now set `IN_NIX_SHELL` to +either `pure` or `impure`, depending on whether `--ignore-environment` +is passed. `nix develop` will always be an impure environment. diff --git a/lix/nix/run.cc b/lix/nix/run.cc index dcd81037b..f83107b10 100644 --- a/lix/nix/run.cc +++ b/lix/nix/run.cc @@ -149,6 +149,7 @@ struct CmdShell : InstallablesCommand, MixEnvironment unixPath.insert(unixPath.begin(), pathAdditions.begin(), pathAdditions.end()); auto unixPathString = concatStringsSep(":", unixPath); setenv("PATH", unixPathString.c_str(), 1); + setenv("IN_NIX_SHELL", ignoreEnvironment ? "pure" : "impure", 1); Strings args; for (auto & arg : command) args.push_back(arg); diff --git a/tests/functional/flakes/develop.sh b/tests/functional/flakes/develop.sh index 71d448a78..81b3e6b78 100644 --- a/tests/functional/flakes/develop.sh +++ b/tests/functional/flakes/develop.sh @@ -64,4 +64,8 @@ echo "\$SHELL" EOF )" -ef "$BASH_INTERACTIVE_EXECUTABLE" ]] +# Test whether `nix develop` sets `IN_NIX_SHELL` +[[ "$(nix develop --no-write-lock-file .#hello -c sh -c 'echo $IN_NIX_SHELL')" = "impure" ]] +[[ "$(nix develop --no-write-lock-file --ignore-environment .#hello -c /bin/sh -c 'echo $IN_NIX_SHELL')" = "impure" ]] + clearStore diff --git a/tests/functional/shell.sh b/tests/functional/shell.sh index 8bbeabedf..914cbc451 100644 --- a/tests/functional/shell.sh +++ b/tests/functional/shell.sh @@ -38,3 +38,7 @@ path2=$(nix shell --sandbox-paths '/nix? /bin? /lib? /lib64? /usr?' --store $TES [[ $path/bin/hello = $path2 ]] [[ -e $TEST_ROOT/store0/nix/store/$(basename $path)/bin/hello ]] + +# Test whether `nix shell` sets `IN_NIX_SHELL` appropriately +[[ "$(nix shell -f shell-hello.nix -c sh -c 'echo $IN_NIX_SHELL')" == impure ]] +[[ "$(nix shell --ignore-environment -f shell-hello.nix -c /bin/sh -c 'echo $IN_NIX_SHELL')" == pure ]]