Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow getFlake of in-store paths in pure mode. #6353

Open
tejing1 opened this issue Apr 2, 2022 · 5 comments
Open

Allow getFlake of in-store paths in pure mode. #6353

tejing1 opened this issue Apr 2, 2022 · 5 comments

Comments

@tejing1
Copy link

tejing1 commented Apr 2, 2022

Is your feature request related to a problem? Please describe.
flake.nix:

{
  outputs = {self}: {
    foo = (builtins.getFlake "path:./child").foo;
  };
}

child/flake.nix:

{
  outputs = {self}: {
    foo = 1;
  };
}
$ nix eval .\#foo
error: cannot call 'getFlake' on mutable flake reference 'path:./child', at /nix/store/2vnnhhpfx98xd3l1y3p9kxsvv7nqcr12-source/flake.nix:3:12 (use --impure to override)

But it isn't actually "mutable"... reproducibility isn't lost here.

Describe the solution you'd like
Nix should be aware that the source path of the flake is in fact immutable, locked by its inclusion in the parent flake, and allow it in pure mode.

Describe alternatives you've considered
Specifying a hash would get around this, but would suffer from the update problems of #6352.

Additional context
This originally came up in the context of creating tests for flake templates which are distributed as subflakes of a parent flake.

@tejing1
Copy link
Author

tejing1 commented Apr 2, 2022

A little more clarity with further thought:
path-type flake references are effectively locked, even without a narHash, if (after conversion to an absolute path) they point into a valid store path, since the hash portion of the path locks the contents anyway. This is why reproducibility is not lost in this case, and if nix takes account of that, the problem is solved.

@tomberek
Copy link
Contributor

tomberek commented Apr 3, 2022

A path input type is specifically a local directory or git tree, not a relative one to an existing flake. The relative support on the command line is a convenience, but per-documentation will not translate to git-type parent flakes. There is currently no dedicated syntax for getFlake that means "relative to the parent."

The options available seem to be:

  1. use the inputs syntax. This makes the parent responsible for tracking the lock file and any follows statements. This brings the danger of having different locks with the parent and in the child.
  2. import the child and send it inputs defined in the parent. This prevents a mismatch in locking (essentially callLocklessFlake from flake-compat
  3. other unsafediscardstringcontext hacks. These also make it easy to have stale or non-reproducible references in lock files.
  4. something new?

Added later: another way to think about it. An inputs block is clearly interpreted in the context of a flake and so there is a parent in the context, but a builtins.getFlake may be called from anywhere, therefore there may be no parent at all.

@ncfavier
Copy link
Member

ncfavier commented Apr 8, 2022

I ended up here because I tried to do builtins.getFlake "." in the REPL and got an error. I think

nix eval --expr 'builtins.getFlake "..."'

should behave the same as

nix eval --override-flake foo ... --expr 'builtins.getFlake "foo"'

I don't really understand the discussion about locking or flake inputs, pardon my ignorance.

@nrdxp
Copy link

nrdxp commented Jul 14, 2022

I just wanted to come back to this. It seems like this actually might be a nice interface for "private" flake inputs. As in, I want to keep my top-level flake.nix API clean and up to some standard, while maybe somewhere deep in some Nix file I just need a one-off module from some flake that isn't really related to the top-level project in any direct sense. Some flakes currently do not implement a "default.nix" compatibility layer so there may be no way to access this resource except via it's flake API; yet I don't really want to convolute the flake.nix with "ad-hoc" dependencies.

Tangentially related, this may also help avoid a mass buildup of inputs in the lock file leading eventually to #6626 (though I would hope a solution for that would emerge independantly, eventually)

For implementation, we could modify the API of getFlake to essentially mirror that of fetchTree. Where the latter just fetches a raw source path, the former assumes this path will contain a flake.nix and "import" it.

edit
While using the builtin would probably be the nicer solution, I experimented with call-flake.nix directly, and it actually works in pure eval, so I guess there is a way (although highly obscured) to pull "private" flake inputs right now.

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/private-flake-inputs/21277/1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants