Is there anyway for a flake to get it’s local path? I know this breaks the intended deterministic properties of flakes but what about with the
I’m writing a wrapper for Matlab to create isolated environments, analogous to
python.withPackages. Packages are built by copying the source code to
symlinkJoin is used to link each package directory in the nix store to the wrapper’s
This works but for developing new packages, I would like to have the package set up as a flake and pass a Matlab environment with it’s dependencies and itself to
devShell. By default, Matlab will watch for changes to source code and automatically reload functions that have changed. But since the version of the package Matlab sees is actually a copy of the source code in the nix store, it doesn’t notice changes and would require a rebuild and restart of Matlab anytime changes are made.
As part of the solution, in addition to the
packages attribute in the Matlab wrapper, I’ve added an optional
devPackages list. This list accepts the local path of the package and creates a symlink in the wrapper that points to the local package. But I cannot get the local path to the flake to pass directly into the Matlab wrapper. Instead, I have to hard code the full path, which reduces portability.
Looking at https://discourse.nixos.org/t/how-to-refer-to-current-directory-in-shell-nix/9526 and https://github.com/nix-community/home-manager/issues/2660 it sounds like it is not possible. Using the
--impure flag seems like it should work but based on “Flakes are also copied to the Nix store, so the relative directory is always relative to the store.”
builtins.toString ./. will always return a path in under
/nix/store and my own attempts verify that. Without the
--impure flag I get a double hashed path and with it I get a single hashed path. So it seems like without the flag, the flake copy to the store before being evaluated then copies the contents of itself to the nix store with using the previous hash as the base name and prepending a second hash onto that. Which seems like odd behavior.
Is there anyway to get around this?
Did you ever figure something out for this? I’m trying to figure out how to set an environment variable based on the project directory in
devShell in a
I’m not 100% certain if op was looking for this, but the
self input (that is always implicitly passed to a flake) refers to the directory of the flake.
So to get the
flake.nix file to refer to itself in a string you can use
This will point to its copy in the nix store, though, because that’s how flakes work. I think op didn’t want that in this case, but I don’t understand the idea well enough for lack of MATLAB admin experience.
No, I don’t think it’s possible due to wanting to ensure flakes are completely reproducible. But again think reducing the restriction purely for the development stage would make things much easier.
self seemed promising but as you said it refers to the path in
/nix/store/ where the flake is copied to. I want to be able to create a wrapper around MATLAB so only the builtins + passed package’s are on MATLAB’s path. Same as with
python.withPackages or using
R with specific packages. But I would like to also be able to pass local versions of packages so I can confirm everything is working before pushing commits and without needing to rebuild and reload MATLAB after every changes. I have the same issues with working in python but at least python has the
PYTHONPATH variable that I can add
. to which is a reasonably good hack work around so that tests can actually find the current package.
Let’s put it this way, if there was ever discovered a way to do this, it would probably be patched as it breaks the intention of pure evaluation. That said, if you really need something like this, the closest you could get is to put it in a well known location on the filesystem.
This is only in the case for pure evaluation though, and only during evaluation. There is nothing stopping you from setting an environmental variable in the
ROOT_PATH=$(git rev-parse --show-toplevel), since this happens outside of the context of a build, or you could pass
--impure if you really need it during evaluation, and use
builtins.getEnv which is only available in impure eval, but this breaks a lot of nice guarantees and I would discourage it unless absolutely necessary.
Not sure if it helps, but as I said earlier, it is also possible to refer to and even import well known directories inside pure evaluation with
builtins.fetchurl with a
file:// url, so if placing the flake in some well known directly would solve the problem, that’s another option.
Using the shell hook is a good idea, and I’m not particularly concerned about hermetic purity of the dev environment. Using well-known directories and assigning environment variables based on the flake name is another potential solution, although it might be a bit impure if we need to create those directories.
The use case for me is wanting to set
CARGO_HOME for rust projects to a unique
.cargo directory (currently within the project directory and gitignored), to avoid mixing with any global cargo stuff the user may have installed. Either the shell hook or the well-known directory option should work well for that. Thanks for the reply!