I believe the best solution, long term, would be to use a self reference for inputs, just as in outputs.
Original Post
I’d like to use a flake.nix in a subdir of an existing flake as an input. This is mainly because of the evaluation restrictions on the inputs attribute.
Since you can’t do any real computation on inputs, without evaluation complaining about thunks instead of values, I was wanting to manage a series of sources for overlays via another flake in a subdirectory.
This is mainly so I no longer have to specify revisions and hashes manually, but can rely on nix flake update to update derivation sources when desired.
The only other alternative is to put the inputs directly in the main flake, which mixes concerns a little bit. I originally was going to simply specify the inputs in a separate file and import and merge it with the inputs attribute set, but that’s when I discovered that you can’t really run any computation over the inputs.
Problem is, input urls expect a full path. So I can’t just say inputs.pkgSrcs.url = "./pkgs" like I want to. Is there a way to solve this? Possibly an input type I am not aware of? If not, is this behavior desirable enough to others to open an issue on nix issue tracker.
I think this behavior should still be pure as long as we disallow files from the top flakes root.
Indeed, we could liken it to private interfaces from the world of OOP.
Really, anything that would allow us to specify inputs in more than one place would solve my immediate problem. I just feel like private subflakes would be a good way to organize projects into the various concerns.
Perhaps we could add some logic that disallows them to be referenced directly from the outside world, ensuring they are only available internally.
perhaps:
{
inputs.<flake>.private = true;
}
And if this is set, then the flake ref must resolve to a flake directly inside the toplevel flake
The top-level flake.lock pins also the inputs for the subflake. If the subflake has its own flake.lock, updates on its inputs only propagate to the top-level flake using nix flake update --update-input subflake. A simple nix flake update doesn’t do it. Is this probably a bug or does it make sense (i.e. shall I open an issue if there exists none)?
This is perfect. Thanks a ton! I did notice that the lock didn’t update when changing the revision, so perhaps this is a bug.
edit
Unfortunately, this doesn’t actually solve the problem, it pushes the error down the chain. After actually attempting to use them from within my configuration I get the following error:
41| else if info.type == "path" then
42| { outPath = builtins.path { path = info.path; };
| ^
43| narHash = info.narHash;
string './pkgs' doesn't represent an absolute path
Your error only appears when using flake-compat, doesn’t it? The path fetcher in Nix allows relative paths, but coerceToPath, which builtins.path uses does not. So flake-compat is more restrictive than flakes are. Maybe this is a bug in flake-compat, but according to line 87 in https://github.com/NixOS/nix/blob/6548b89cc4eb214cb4632fd4332c610f2d1f0a9d/src/libfetchers/path.cc#L87 maybe this restriction is just not yet implemented in the path fetcher.
Thanks for this, I usually pull the flake into a repl using flake-compat (less typing than builtins.getFlake "/full/path/to/flake"). Never would have guess it was less compatible, but your right, the error does not occur in the flake proper. So guess this is a workable solution after all. Thanks you!
I usually have a repl.nix with builtins.getFlake (toString ./.) around, so i just nix repl ./repl.nix…
Really wish there was a better way to do that though.