Sure.
Got it. I’ve since taken to looking at the function arguments as an alternative.
The same thing, the check happens after module collection, so the specifics of how and where the module that defines these options exists should not impact how the checks work. If you want to play around with my example or another without having to type everything for every iteration you could wrap the evalModules call in a thin function in the repl like:
f = module: (lib.evalModules { modules = [ { ... } module ]).config
and use
:p f { ... }
to quickly get feedback on what configuration the evaluation results in (:p recursively prints attrsets). Either attrsets, functions or paths can all be valid modules.
Got it. So neither are technically supposed to work, correct…? I’d have to find an alternative.
With checks added to disqualify definitions for all but the last submodule type passed to either or oneOf using either of them is supposed to and does work.
Interesting… If I modify your example to look at the config attribute, I get the following error:
{ x = «error: The option `x.z' does not exist. Definition values:
- In `<unknown-file>': "bye"»; }
That’s right, because it’s specifying both x.y and x.z, which belong to typeA and typeB respectively, but if you remove either x.y or x.z it should work. The point of having both is just to demonstrate that it will not accept both options simultaneously, however will accept one.
The second module passed to evalModules in my example is what you would replace with your module argument if you’re making a function to test what different definitions yield.
Ah; got it. My problem is that I need to create a superset of features based on whether additional options are used. What I’m doing instead is looking at the function arguments and evaluating the module accordingly.
You can also do that by altering the check to something else. You could discriminate based on the defined value of an option, or multiple options, not just the presence.
If the modules need to share some set of options you could import a common module and base the checks on the definitions of those options.
I read the code you sent and I’m not sure I understand exactly what high level problem you’re trying to solve, tho I do get the impression you may be overcomplicating some logic around the specifics of what data type a module is. Types like submodule, or deferredModule if you’ll be evaluating it separately, will work with anything that is a module, i.e. an attribute set, a function that takes a deconstructed attribute set and returns an attribute set or a path which when imported results in either. Relying on this existing nixpkgs code, if not solving your problem directly, may at least be less error-prone.
Oh, without a doubt. I seem to have a habit of that. If you’d like to see my current implementation, here’s the link. For whatever reason, I’m trying to build my own version of flake-parts and flakelight, though I’m giving users the option to choose their own output builders, like flake-parts.