How to refer to current directory in shell.nix?

I’m developing a package that includes some Lua library files. Supposing my git repository is in /home/dan/src/example/, this means I need to set the environment variable LUA_PATH to /home/dan/src/example/lib/?.lua - and I’d like to do this in shell.nix

My first thought was to use ./. but that expands to a store path not to the “local” directory. I’d rather be able to use an absolute path here than just lib/?.lua which will fail as soon as I cd into a subdirectory

Any ideas?

4 Likes

Maybe it’s easier than I thought it was:

with import <nixpkgs> {};
(callPackage ./default.nix {}).overrideAttrs(o: rec {
  SWARM_BASE_PATH = "/tmp/services";
  PROJECT_ROOT = builtins.getEnv "PWD";
  LUA_PATH = "${PROJECT_ROOT}/lib/?.lua";
  nativeBuildInputs = [ pkgs.foreman ] ;
})

although it would be even better if I could find the path of the shell.nix file itself, then I can run nix-shell from other directories as well as .

3 Likes
...
  PROJECT_ROOT = builtins.toString ./.;
...
5 Likes

I was not expecting that to work, but … thank you very much!

Why does toString work there? For anyone skimming the thread:

FOO = builtins.toString ./.;
FOO2 = ./.;

nix-shell:~/src/swarm]$ echo $FOO
/home/dan/src/swarm

[nix-shell:~/src/swarm]$ echo $FOO2
/nix/store/3ll5lrn0cys4rfq0asvxz0jar2z24c21-swarm

Magic!

5 Likes

nix paths work like that:
If you reference something as a path and not a string it gets copied to the nix-store so it doesn’t change it output when you run it multiple times.
when you convert the current directory to a string you skip to copy to nix-store step and get the current directory as string.

7 Likes

:joy: I always end up looking for the same piece of information and almost always end here:

3 Likes

Just FYI, for those who put the devShell in their flake.nix, you will need to add --impure

$ nix develop --impure

to prevent the path from being copied to /nix/store.

5 Likes

OT but shouldn’t --impure rather be a default for develop then ?

1 Like

Note that this isn’t true with flakes. builtins.toString ./. still makes a path to /nix/store for purity.

See bug: mkOutOfStoreSymlink still links inside nix store for flake and toString input · Issue #2660 · nix-community/home-manager · GitHub

3 Likes

I think so too, it’s a pitfall many of my nix-muggle colleagues run into when using dev shells. At least there should be a something one can set directly in flake.nix (or mkShell) to have it default to impure like:

# flake.nix

#...

nixConfig.devShell.impure = true;  # or something