lorri
lorri copied to clipboard
Lorri does not set `IN_NIX_SHELL` when realizing derivations
Describe the bug
In a regular nix-shell
, builds are evaluated with IN_NIX_SHELL
set. This allows you to, for instance, use your default.nix
directly, while adding some development dependencies when in a shell. Lorri doesn't do this, meaning expressions that work as expected in nix-shell
may provide a different environment in Lorri.
To Reproduce
Steps to reproduce the behavior:
v@january ~> cd (mktemp -d)
v@january /t/tmp.7nY21hGq4L> cat shell.nix
with import <nixpkgs> {};
let
foo = writeShellScriptBin "foo" ''
echo bar
'';
in mkShell {
packages = lib.optional lib.inNixShell foo;
}
v@january /t/tmp.7nY21hGq4L> nix-shell
these derivations will be built:
/nix/store/ghn3hhrabvy76jwr76pzxm3ynhw5qnqw-foo.drv
building '/nix/store/ghn3hhrabvy76jwr76pzxm3ynhw5qnqw-foo.drv'...
v@january /t/tmp.7nY21hGq4L> foo
bar
v@january /t/tmp.7nY21hGq4L> ^D
v@january /t/tmp.7nY21hGq4L> lorri init
Aug 14 04:23:01.863 INFO file already exists, skipping, message: Make sure shell.nix is of a form that works with nix-shell., path: ./shell.nix
Aug 14 04:23:01.863 INFO wrote file, path: ./.envrc
Aug 14 04:23:01.863 INFO done
direnv: error /tmp/tmp.7nY21hGq4L/.envrc is blocked. Run `direnv allow` to approve its content
v@january /t/tmp.7nY21hGq4L> direnv allow
direnv: loading /tmp/tmp.7nY21hGq4L/.envrc
Aug 14 04:23:14.186 INFO lorri has not completed an evaluation for this project yet, nix_file: /tmp/tmp.7nY21hGq4L/shell.nix
direnv: export +IN_NIX_SHELL
v@january /t/tmp.7nY21hGq4L>
direnv: loading /tmp/tmp.7nY21hGq4L/.envrc
direnv: export +AR +AS +CC +CONFIG_SHELL +CXX +HOST_PATH +IN_LORRI_SHELL +IN_NIX_SHELL +LD +NIX_BINTOOLS +NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_BUILD_CORES +NIX_BUILD_TOP +NIX_CC +NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_CFLAGS_COMPILE +NIX_ENFORCE_NO_NATIVE +NIX_HARDENING_ENABLE +NIX_INDENT_MAKE +NIX_LDFLAGS +NIX_LOG_FD +NIX_STORE +NM +OBJCOPY +OBJDUMP +RANLIB +READELF +SIZE +SOURCE_DATE_EPOCH +STRINGS +STRIP +allowSubstitutes +buildInputs +builder +configureFlags +depsBuildBuild +depsBuildBuildPropagated +depsBuildTarget +depsBuildTargetPropagated +depsHostHost +depsHostHostPropagated +depsTargetTarget +depsTargetTargetPropagated +doCheck +doInstallCheck +extraClosure +name +nativeBuildInputs +nobuildPhase +origArgs +origBuilder +origExtraClosure +origOutputs +origPATH +origSystem +out +outputs +patches +phases +preHook +preferLocalBuild +propagatedBuildInputs +propagatedNativeBuildInputs +shell +shellHook +stdenv +strictDeps +system ~PATH ~XDG_DATA_DIRS
v@january /t/tmp.7nY21hGq4L>
v@january /t/tmp.7nY21hGq4L> foo
foo: command not found
v@january /t/tmp.7nY21hGq4L [127]>
Expected behavior
Metadata
v@january /t/tmp.7nY21hGq4L> lorri info
error: The following required arguments were not provided:
--shell-file <nix_file>
USAGE:
lorri info --shell-file <nix_file>
For more information try --help
v@january /t/tmp.7nY21hGq4L [1]>
v@january /t/tmp.7nY21hGq4L> uname -a
Linux january 5.10.37 #1-NixOS SMP Fri May 14 07:50:46 UTC 2021 x86_64 GNU/Linux
Additional context
None, really. This feels like an edge case you're unlikely to run into unless you're weird.
Some example code (even generated code?) for haskell development environments also used this to switch between building drv
and drv.env
. Here the situation is even worse: The environment won't even work properly if drv.env
isn't used.
This is a little off-topic, but does direnv's use nix
handle this correctly? If not, we probably ought to report it there as well.
lorri shell
does set it iirc.
There was a reason why we don’t set it which should be documented somewhere in the code or git blame.
lorri shell
does set it iirc.
Just tried that, it doesn't seem to be any different?
IN_NIX_SHELL
is set within the shell itself, so if one were to do a nix-build
from within the shell (produced either via lorri direnv
, or lorri shell
, etc), it would build foo
as expected. So it is setting the variable, just not in enough places.
Looks like we are setting it in two places:
https://github.com/nix-community/lorri/blob/dfbf9b3d22474380ee5e096931dbf25b1c162d10/src/ops/direnv/envrc.bash#L163
https://github.com/nix-community/lorri/blob/b84602c7132293e23eb8957ba493f188ce89ea1c/src/logged-evaluation.nix#L144
This seems to have the side-effect of, in Haskell projects, tricking nix-build into building drv.env
, when what you'd really want is to build drv
.
Not sure what's the cleanest way to approach this, ideally instead of exporting IN_NIX_SHELL
it could be set and unset on lorri commands only. If not possible, create a lorri build command
?
As a band-aid, I've been using IN_NIX_SHELL= nix-build && lorri watch
because lorri loses it's connection after building.
This is my default.nix
for reference:
{ pkgs ? import <nixpkgs> {}}:
pkgs.haskellPackages.developPackage {
root = ./.;
}