-
Notifications
You must be signed in to change notification settings - Fork 41
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/mkFlake
: Test suite improvements and more
#183
base: main
Are you sure you want to change the base?
Conversation
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 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.