-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
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
lib/modules: Allow an "anonymous" module with key in disabledModules #211855
lib/modules: Allow an "anonymous" module with key in disabledModules #211855
Conversation
14cf976
to
4d31a4e
Compare
lib/modules.nix
Outdated
else if isFunction m | ||
then | ||
let mAttrs = m fakeArgs; | ||
fakeArgs = | ||
mapAttrs | ||
(k: v: throw "If a module in 'disabledModules' is not referenced by its path, it must be identified by a 'key' attribute. Retrieving this attribute failed for ${theModule} in the 'disabledModules' of a module in '${file}', because its 'key' attribute requires the module argument '${lib.strings.escapeNixIdentifier k}' to be computed first. This is not possible, because the set of applicable modules must be determined before any configuration can be computed.") |
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.
I don't think keys behind functions should be allowed. Flake-aware code can map over nixosModules.*
, wrapping each using module: { key = "<flake>#<attr>"; imports = [ module ]; }
. Providing fake arguments won't be necessary like that.
Also by not allowing functions, this change can be seen as just allowing modules to be coerced to a string in a different way using .key
, similar to .outPath
and .__toString
, which sounds more reasonable to me, because evidently from this code here, disabledModules
and imports
are fundamentally different (disabledModules
only needs a reference to a module, while imports
needs the module itself).
However an alternative idea I'd be more in favor of is to require all imports
to have a key
. So you couldn't just do imports = [ {} ]
anymore, it would have to be imports = [ { key = "something"; } ]
, the key can't be behind the fixed point though. This then ensures that all modules have a stable reference that can be used to disable them. And it would also allow using all modules in both imports
and disabledModules
.
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.
I've removed the possibility to specify a key in a function. It's good to be careful like that, and I don't think it's a problem for users to remove this functionality.
However an alternative idea I'd be more in favor of is to require all
imports
to have akey
.
I don't see the benefit. The benefit comes from having more keys. Requiring those is a rather harsh incentive for such a small improvement.
Anyway, that's just future work if anything.
3cca12f
to
6f487fe
Compare
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.
It would be good to have some docs for this as well, otherwise this looks good to me.
1a3aa2b
to
eeda7a1
Compare
lib/modules.nix
Outdated
else if isPath m || isString m | ||
then toString m |
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.
I'm just noticing that the previous code allowed any string-coercible value to be used. So we should arguably keep that behavior.
else if isPath m || isString m | |
then toString m | |
else if isCoercibleToString m | |
then toString m |
I guess the previous string-coercing behavior wouldn't have worked for your use-case though, because neither outPath
nor __toString
are allowed attribute names in modules.
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.
I've added a test for this, refactoring the code a bit and rejecting ambiguities between toString
and .key
.
Also fyi that function will enter deprecation in summer.
isCoercibleToString = lib.warnIf (lib.isInOldestRelease 2305)
"lib.strings.isCoercibleToString is deprecated in favor of either isStringLike or isConvertibleWithToString. Only use the latter if it needs to return true for null, numbers, booleans and list of similarly coercibles."
isConvertibleWithToString;
a7730a5
to
4277605
Compare
lib/modules.nix
Outdated
else if isConvertibleWithToString m | ||
then | ||
if m?key | ||
then | ||
throw "Module `${file}` contains a disabledModules item that is an attribute set that can be converted to a string (${toString m}) but also has a `.key` attribute (${m.key}) with a different value. This makes it ambigous which module should be disabled." |
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.
else if isConvertibleWithToString m | |
then | |
if m?key | |
then | |
throw "Module `${file}` contains a disabledModules item that is an attribute set that can be converted to a string (${toString m}) but also has a `.key` attribute (${m.key}) with a different value. This makes it ambigous which module should be disabled." | |
else if isConvertibleWithToString m | |
then | |
if m ? key && m.key != toString m | |
then | |
throw "Module `${file}` contains a disabledModules item that is an attribute set that can be converted to a string (${toString m}) but also has a `.key` attribute (${m.key}) with a different value. This makes it ambigous which module should be disabled." |
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.
The other messages should technically also be adjusted to include the possibility of using any string-coercible values.
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.
Done.
The other error messages are already ok
- the one for non-string attrsets without key should keep recommending only the most explicit option:
.key
. It is also technically correct, even if it ignores the possibility of fixing the problem by making ittoString
-able. I'd like to keep the message simple and not explain what I consider irrelevant legacy behavior. If you disagree please leave a suggestion. - the final catch-all one already lists
value supported by toString
.
ebf6729
to
49ebf87
Compare
Do you want to keep the commits as-is or squash a bit? Squashing a bit would be my preference |
This makes the following work disabledModules = [ foo.nixosModules.bar ]; even if `bar` is not a path, but rather a module such as { key = "/path/to/foo#nixosModules.bar"; config = ...; } By supporting this, the user will often be able to use the same syntax for both importing and disabling a module. This is becoming more relevant because flakes promote the use of attributes to reference modules. Not all of these modules in flake attributes will be identifiable, but with the help of a framework such as flake-parts, these attributes can be guaranteed to be identifiable (by outPath + attribute path).
49ebf87
to
118bdf2
Compare
Description of changes
This makes the following work
even if
bar
is not a path, but rather a module such asBy supporting this, the user will often be able to use the same syntax for both importing and disabling a module. This is becoming more relevant because flakes promote the use of attributes to reference modules. Not all of these modules in flake attributes will be identifiable, but with the help of a framework such as flake-parts, these attributes can be guaranteed to be identifiable (by outPath + attribute path).
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