The nix language supports using paths that start with ~/
, which are relative to the user’s home directory. It looks like this is implemented by using the $HOME environment variable:
$ HOME=/tmp nix eval --expr '~/foo'
/tmp/foo
However, this functionality isn’t disabled when evaluating a flake, meaning that flakes can produce different results depending on what $HOME is set to at evaluation time.
I had a brief look through public flakes on github that might be affected by this (with the query path:flake.nix " ~/"
in github code search), and I could only find one, kmein/niveum:
This is a very similar example to what led me to realise this fact in the first place – I was running sudo nixos-rebuild
and was confused why something using a ~/
-path wasn’t working as I expected, until I realised that probably it was evaluating to /root/...
rather than /home/ash/...
.
A concrete example of this is the following flake.nix:
{
description = "A very basic flake";
outputs = { self, nixpkgs }: {
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
shellHook = ''
echo my path is: ${toString ./.}
echo your home directory is: ${toString ~/.}
'';
};
};
}
If I run nix develop
as two different users, the flake prints different home directories:
$ nix develop
my path is: /nix/store/c6c50m39qyfb94iix44352a8pj3yz22d-source
your home directory is: /home/ash
$ sudo nix develop
[sudo] password for ash:
my path is: /nix/store/c6c50m39qyfb94iix44352a8pj3yz22d-source
your home directory is: /root
This seems unideal. Since nix eval --expr 'builtins.getEnv "HOME"'
produces the empty string unless --impure
is used, I suspect it is also unintentional. I’m honestly not familiar enough with flakes to declare it a bug outright, though, which is why I’m posting about it here rather than filing an issue about it on the nix repo.