-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
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
nixos/nixpkgs: make nixpkgs.config
mergeable
#194207
Conversation
This kinda looks good, but I think we should address a deeper issue, which is the (worse) duplication of the same logic from Nixpkgs. I think we could give |
@roberth AFAIU |
You are technically correct, but what I'm trying to achieve by suggesting this is to clean up the custom merging code, and move the responsibility for merging from two places to one. The By representing the merging behavior with the module system, it can be understood more easily without having to dig through the custom code. Code of such complexity needs tests and I don't want to ask you to write tests for an unnecessary solution. And it does have at least two subtle problems because |
OK, I played around with it a little bit more: importing However:
|
I agree
We should have a type for overlays. That'd be something worth testing. |
So, your suggestion is to just use
Is that related to this change? Overlays are IIRC not passed into |
Yes. We can use
I guess technically
Correct. The type for |
fe288f2
to
f45dd29
Compare
@roberth I pushed a different implementation which makes Also, I implemented a fairly simple option-type for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is starting to look good.
After adding a test for the type, I think this will be ready to merge.
Closes NixOS#194056 Alternative implementation to NixOS#80582 `nixpkgs.config` is now a freeform-type which imports the `<nixpkgs/pkgs/top-level/config.nix>`-module. This brings the following benefits: * Proper merging (to a certain degree, more details later) of several `nixpkgs.config` declarations. * `allowUnfree` and friends appear in the NixOS manual. To be precise, this means that something like this is now possible: { nixpkgs = mkMerge [ { allowUnfree = false; } { allowUnfree = mkForce true; } ]; } Previously this would lead to a bogus attr-set, namely { _type = "override"; content = true; priority = 50; } since no merging for this option-type was implemented. This however has certain limitations. For instance nixpkgs.config.allowUnfree = mkForce false; works fine whereas nixpkgs.config.virtualbox.enableExtensionPack = mkForce true; doesn't. This is because we use `types.raw` inside the config-module for `nixpkgs` which doesn't merge undeclared attribute-sets (such as `virtualbox`). This is because we don't know if any attribute-set is actually mergeable, for further details see the previous discussion[1]. A basic type has been implemented for the (actually deprecated) mechanisms `packageOverrides`/`perlPackageOverrides`. This one basically applies the `pkgs` argument onto each definition of this function, so e.g. the following expression { nixpkgs.config = mkMerge [ { packageOverrides = pkgs: { randomattr = 23; }; } { packageOverrides = pkgs: { randomattr = pkgs.randomattr + 19; }; } ]; } adds an attribute `randomattr` of value `42` to `_module.args.pkgs`. [1] NixOS#194207 (comment)
ab3174e
to
7b2f9a5
Compare
@roberth anything else to get this merged? :) |
merge = const | ||
(foldl' | ||
(final: override: pkgs: | ||
let | ||
final' = final pkgs; | ||
in final' // (override.value (pkgs // final'))) | ||
(const {})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changes the merging behavior from before. Most notably the old merging function didn't propagate changes from earlier overrides to later ones, there's only one pkgs
that is reused as the input for all override functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that functionTo attrs
then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost. I think not because of the optCall
, which allows either functions or attribute sets directly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, then it needs a coercedTo
.
optCall
can be replaced by lib.toFunction
, but I guess we'll only need lib.const
anyway.
default = const {}; | ||
type = types.overrideFnType; | ||
description = lib.mdDoc '' | ||
A function that takes the final set of Perl packages and returns an attribute set of packages to add or change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition, the perlPackageOverrides
is super weird, in that it doesn't even take the perl packages as an argument, but rather the main pkgs
package set!
❯ nix-instantiate '<nixpkgs>' --arg config '{ perlPackageOverrides = pkgs: builtins.trace (builtins.head (builtins.attrNames pkgs)) {}; }' -A perlPackages.FileFinder
trace: AAAAAASomeThingsFailToEvaluate
trace: AAAAAASomeThingsFailToEvaluate
trace: AAAAAASomeThingsFailToEvaluate
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
/nix/store/sf3bji32b4xw77xjh7w452pj15jq8gh6-perl5.34.1-File-Finder-0.53.drv
(this shows that the first attribute in the passed pkgs
is pkgs.AAAAAASomeThingsFailToEvaluate
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yikes, but it also kinda makes sense, because how else would you access pkgs
. Actually doing your own fixpoint might work, but not with features like pkgsCross.
Anyway, thanks @infinisil for catching this and sorry @Ma27 for making a wrong suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no worries, I also missed that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uhm... I obseve the same behavior on my local master
(dfae1c1 currently):
❯ ~/Projects/nixpkgs master → nix-instantiate './.' --arg config '{ perlPackageOverrides = pkgs: builtins.trace (builtins.head (builtins.attrNames pkgs)) {}; }' -A perlPackages.FileFinder
trace: AAAAAASomeThingsFailToEvaluate
trace: AAAAAASomeThingsFailToEvaluate
trace: AAAAAASomeThingsFailToEvaluate
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
/nix/store/f9qgccfq4p6n161jlkdf05qikmq4l9jj-perl5.36.0-File-Finder-0.53.drv
Am I missing something? oO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's as expected. This just demonstrates that perlPackageOverrides
gets the pkgs
as an argument and not pkgs.perlPackages
, since there's only pkgs.AAAAAASomeThingsFailToEvaluate
and no pkgs.perlPackages.AAAAAASomeThingsFailToEvaluate
. Don't mind this specific attribute name, it's not related to this issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition, the
perlPackageOverrides
is super weird, in that it doesn't even take the perl packages as an argument, but rather the mainpkgs
package set!
It's funny. In a discussion today the inverse came up. Without a way to reference pkgs
, mere two-function overlays are not good enough for distributing additions/changes to language-specific package sets, because those inevitably tend to need some things from pkgs
... but which one?
So without a pkgs
parameter it's not suitable for distributed use, and without a prev
or self
, it's not an overlay.
We need both! ... or do we? self
is actually available in pkgs
.
But yes, we do, because the location may be ambiguous. Is it haskellPackages
or haskell.packages.ghc943
?
We could change the Nixpkgs entrypoint to allow multiple |
Actually, that's a pretty good idea and way better than effectively doing two rounds of evaluations of
It'd be nice to ensure that users get a somewhat usable eval error (or warning at least) when referencing Will close this PR for now. Adding this suggestion to my todo list, but it'll take a moment until I get to it, so feel free to go ahead if you have the motivation & capacity currently 😄 |
Description of changes
Closes #194056
Alternative implementation to #80582
nixpkgs.config
is now a freeform-type which imports the<nixpkgs/pkgs/top-level/config.nix>
-module. This brings the followingbenefits:
Proper merging (to a certain degree, more details later) of several
nixpkgs.config
declarations.allowUnfree
and friends appear in the NixOS manual.To be precise, this means that something like this is now possible:
Previously this would lead to a bogus attr-set, namely
since no merging for this option-type was implemented.
This however has certain limitations. For instance
works fine whereas
doesn't. This is because we use
types.raw
inside the config-module fornixpkgs
which doesn't merge undeclared attribute-sets (such asvirtualbox
). This is because we don't know if any attribute-set isactually mergeable, for further details see the previous discussion[1].
A basic type has been implemented for the (actually deprecated)
mechanisms
packageOverrides
/perlPackageOverrides
. This one basicallyapplies the
pkgs
argument onto each definition of this function, soe.g. the following expression
adds an attribute
randomattr
of value42
to_module.args.pkgs
.[1] #194207 (comment)
Things done
sandbox = true
set innix.conf
? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)nixos/doc/manual/md-to-db.sh
to update generated release notes