-
-
Notifications
You must be signed in to change notification settings - Fork 16.6k
lib.modules: Expose the freeform results readonly via '_module.freeformConfig' #390952
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
base: master
Are you sure you want to change the base?
Conversation
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.
Reviewed together in a meeting with @hsjobeki. Overall looking fine!
_module.freeform
should be renamed to something that clearly indicates what it is- It should also get some better docs
- Why can't we add
readOnly
? (becausemkMerge
assigns multiple) - Why is the
default
necessary? (???) - Clean history
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 not available a lot, so don't feel blocked on me, just left a very quick review :)
6ef0759
to
adbdb8a
Compare
LGTM, but let's not risk interrupting work on the release, so merge this after branch-off. |
After discussing this with @hsjobeki in a call today, we discovered that this PR currently doesn't work well for @hsjobeki's usecase, because while the freeform definitions would be exposed, the priorities of individual attributes would have to be recalculated outside the module evaluation. This would notably also be a problem for standard non-freeform options with nested priorities. Instead, the diff --git a/lib/modules.nix b/lib/modules.nix
index 4691018c68a0..611f6e46aac9 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -226,6 +226,10 @@ let
'';
};
+ _module.freeformMerged = mkOption {
+ internal = true;
+ visible = false;
+ readOnly = true;
+ type = types.raw;
+ };
+
_module.specialArgs = mkOption {
readOnly = true;
internal = true;
@@ -242,6 +246,8 @@ let
moduleType = type;
};
_module.specialArgs = specialArgs;
+
+ _module.freeformMerged = freeformMerged;
};
};
@@ -266,21 +272,26 @@ let
options = merged.matchedOptions;
+ # For definitions that have an associated option
+ declaredConfig = mapAttrsRecursiveCond (v: !isOption v) (_: v: v.value) options;
+
+ freeformDefs = map (def: {
+ file = def.file;
+ value = setAttrByPath def.prefix def.value;
+ }) merged.unmatchedDefns;
+
+ freeformMerged = declaredConfig._module.freeformType.merge.v2 {
+ loc = prefix;
+ defs = freeformDefs;
+ };
+
config =
let
- # For definitions that have an associated option
- declaredConfig = mapAttrsRecursiveCond (v: !isOption v) (_: v: v.value) options;
# If freeformType is set, this is for definitions that don't have an associated option
freeformConfig =
- let
- defs = map (def: {
- file = def.file;
- value = setAttrByPath def.prefix def.value;
- }) merged.unmatchedDefns;
- in
- if defs == [ ] then { } else declaredConfig._module.freeformType.merge prefix defs;
+ # Probably can be simplified with freeformMerged.isDefined or so?
+ if freeformDefs == [ ] then { } else freeformMerged.value;
in
if declaredConfig._module.freeformType == null then
diff --git a/lib/types.nix b/lib/types.nix
index 35171b28c799..07fa9d03e88b 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -852,6 +852,7 @@ let
v.optionalValue.value
) evals;
valueMeta.attrs = mapAttrs (n: v: v.checkedAndMerged.valueMeta) evals;
+ valueMeta.evals = evals;
};
};
|
This looks redundant or wrong.
Floating this stuff out causes a space leak. |
Thanks, thats good to know. i'll try move it back into the let binding again after we are done with #391544 We've basically discovered, that it would be better to integrate with merge.v2 because that would give us the new merge interface that natively allows exposing metadata |
For any kind of Introspection tooling we needed access to the definitions and the highestPrio of options.
Definitions via freeform are not accessible / observable at all which makes building debuggers, frontends, or introspection tools in general impossible. Also manual debugging by looking into freeform to see what was matched is nice and makes peoples life easier.
Overall:
Thx @roberth who helped me out finding a design that works quite a bit.
Things done
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.