NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
12.74k stars 1.52k forks source link

flakes: some kind of auto-follows behavior #5576

Open nrdxp opened 2 years ago

nrdxp commented 2 years ago

Is your feature request related to a problem? Please describe. I quite often find myself with a flake.lock that has 10 or more nixpkgs references. I spend a lot of time attempting to remove these duplicates where appropriate and not only is it time consuming, it also pollutes the inputs attrs of the flake.nix, making it much more verbose.

Describe the solution you'd like I'd imagine something fairly simple, such as inputs.nixpkgs.following = true, when set, tells nix that any inputs in the chain named nixpkgs automatically follow this one. Perhaps an escape hatch can also be added in the cases where following this particular input would break something; maybe inputs.someFlake.inputs.nixpkgs.isfollowing = false.

Describe alternatives you've considered I've consider if a cli flag or argument could be added to Nix to achieve this, but it seems more appropriate to do it declaratively as part of the input spec.

Obviously, we could just leave it as is and require all follows to be manually specified, but I find that I typically want this following behavior in almost all cases, except where it breaks an evaluation or a package.

roberth commented 2 years ago

Another solution is to allow flakes to declare that they want some of their inputs to be injected by their users.

So if you have A depends on B and both depend on nixpkgs; if B declares inputs.nixpkgs.inject = true, flakes will automatically try to set B's nixpkgs to A's nixpkgs, if it exists. Otherwise nixpkgs is taken from B's lock.

Name could be improved perhaps. inject could be preferUserInput or unpin, idk.

nrdxp commented 2 years ago

That sounds nice, but how would it determine to use A's nixpkgs and not C's, etc?

roberth commented 2 years ago

Well, there is no C in my example ;) but really it's because B is a dependency of A.

It'd "look" inside the parent. That sounds sketchy from an implementation standpoint, so let me rephrase that a flake (here A) tries to inject its direct inputs into its inputs' inputs where inject = true.

roberth commented 2 years ago

There's a connection with #5570 here.

nrdxp commented 2 years ago

I think I found a slightly better wording for what I'm trying to get at here. Maybe inputs.nixpkgs.canonical = true, along with inputs.nixpkgs.aliases = [ "nixos" ] for inputs you wish to follow this one but have a different name. For inputs you wish not to follow the canonical one, you can do a inputs.foo.inputs.nixpkgs.dontCanonicalize.

I also really like the injection idea, as it's something I've actually been struggling to find a solution for in some of our larger work flakes. I don't think the two suggestions are entirely exclusive. Personally, I would want them both.

nixos-discourse commented 2 years ago

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

https://discourse.nixos.org/t/multi-branch-flake-update-performance-improvement/19310/2

mpoquet commented 8 months ago

I would also be very interested in such a feature.