lib/mkFlake: Test suite improvements and more#183
lib/mkFlake: Test suite improvements and more#183bb010g wants to merge 8 commits intohercules-ci:mainfrom
mkFlake: Test suite improvements and more#183Conversation
|
Reading divnix/call-flake@5828e08, it looks like both |
|
You mean NixOS/nix@5d834c4
I don't think we need
Sounds about right. I think Not sure if we should act on the "here" idea now. For most users it's probably better to get a change into Nix so we can improve this structurally without bothering them with an extra parameter. |
| weakEvalTests.callFlake = { ... } @ flake: | ||
| let | ||
| sourceInfo = flake.sourceInfo or { }; | ||
| inputs = flake.inputs or { }; | ||
| outputs = flake.outputs inputs; | ||
| result = outputs; | ||
| in | ||
| result; | ||
| strongEvalTests.callFlake = { ... } @ flake: | ||
| let | ||
| sourceInfo = { outPath = "/unknown_eval-tests_flake"; } // | ||
| flake.sourceInfo or { }; | ||
| inputs = flake.inputs or { }; | ||
| outputs = flake.outputs (inputs // { self = result; }); | ||
| result = outputs // sourceInfo // { | ||
| inherit inputs outputs sourceInfo; | ||
| _type = "flake"; | ||
| }; | ||
| in | ||
| assert builtins.isFunction flake.outputs; | ||
| result; |
There was a problem hiding this comment.
Do we really need weakEvalTests.callFlake?
Not happy about how complicated this got. Relying on laziness and overriding means that it's not immediately obvious what runs how.
| # for REPL exploration / debugging | ||
| config.allFlakeModuleArgs = args // config._module.args // specialArgs; | ||
| config.allRootModuleArgs = rootArgs // rootConfig._module.args // rootSpecialArgs; | ||
| config.transformFlakeModule = flakeModuleTransformer: | ||
| rootSpecialArgs.replaceSpecialArgs (prevSpecialArgs: prevSpecialArgs // { | ||
| inherit flakeModuleTransformer; | ||
| }); | ||
| options.mySystem = lib.mkOption { | ||
| default = rootConfig.allSystems.${builtins.currentSystem}; | ||
| }; |
There was a problem hiding this comment.
Can't we just set config.debug = true;?
dev is already overly complicated because it tries to work around the subflake problems. I'd like to simplify it instead of obfuscating it further.
Alright. Balancing this is hard when debug information is sourced the same as normal information.
I agree on this. A manual parameter that they have to set to |
This infinite recursion first appeared in 2cde01e.
| # This test case is a fun one. In the REPL, try `exhibitInfiniteRecursion.*`. | ||
| # In the case that `mkFlake` *isn't* called from a flake, `inputs.self` is | ||
| # unlikely to refer to the result of the `mkFlake` evaluation. If | ||
| # `inputs.self` isn't actually self-referential, evaluating attribute values | ||
| # of `self` is not divergent. Evaluation of `self.outPath` is useful for | ||
| # paths in documentation & error messages. However, if that evaluation occurs | ||
| # in a `builtins.addErrorContext` message forced by an erroring `self`, both | ||
| # `self` will never evaluate *and* `builtins.toString self.outPath` must | ||
| # evaluate, causing Nix to instead throw an infinite recursion error. Even | ||
| # just `inputs.self ? outPath` throws an infinite recursion error. | ||
| # (`builtins.tryEval` can only catch errors created by `builtins.throw` or | ||
| # `builtins.assert`, so evaluation is guarded with | ||
| # `exhibitingInfiniteRecursion` here to keep `runTests` from diverging.) | ||
| # In this particular case, `mkFlake` evaluates `self ? outPath` to know if the | ||
| # default module location it provides should be generic or specific. As | ||
| # explained, this evaluation is unsafe under an uncatchably divergent `self`. | ||
| # Thus, `outPath` cannot be safely sourced from `self` at the top-level. |
There was a problem hiding this comment.
🎉 I can confirm that this now works as it should, since #192 or #194.
The new, informative error message
«error: error:
… while evaluating the attribute 'strongEvalTests.nonexistentOption'
at /home/user/h/flake-parts/dev/tests/eval-tests.nix:209:3:
208| # exhibiting infinite recursion, the flake is made equivalent to `empty`.
209| strongEvalTests.nonexistentOption = evalTests.callFlake {
| ^
210| inputs.flake-parts = evalTests.flake-parts;
… in the left operand of the update (//) operator
at /home/user/h/flake-parts/dev/tests/eval-tests.nix:33:24:
32| outputs = flake.outputs (inputs // { self = result; });
33| result = outputs // sourceInfo // {
| ^
34| inherit inputs outputs sourceInfo;
(stack trace truncated; use '--show-trace' to show the full trace)
error: The option `nonexistentOption' does not exist. Definition values:
- In `/home/user/h/flake-parts/dev/tests/eval-tests.nix': null»
mkFlake: Document _file infinite recursionmkFlake: Test suite improvements and more
Split out from #137. Please read the individual commit messages.