fix: perHost/perUser/perHome preserve aspect identity#410
Merged
Conversation
Return { includes = [fn] } instead of a bare function, matching the
POC pattern. The function result lives in includes where
parametric.applyIncludes handles it with withIdentity, preserving the
aspect name through resolution. Fixes #408.
b8bce20 to
e8c6bf2
Compare
Collaborator
Author
|
Don't merge yet, it fixed the test but theres one other edgecase I want to check. |
Owner
|
merge at your discretion |
Owner
|
please also include a deadbug test with the original code. |
Bare function aspects (e.g., { host, ... }: { nixos... }) merged with
static config from separate modules now work correctly. Fixes #408.
Three changes:
- take.nix: carryAttrs preserves name through successful take calls
- types.nix: coercedTo in aspectsType wraps non-module functions into
{ includes = [fn] } so they aren't treated as module functions
- perHost-perUser.nix: returns { includes = [fn] } matching the POC
pattern, so parametric.applyIncludes handles identity via withIdentity
Collaborator
Author
|
So this was an interaction with: providerFnType =
cnf:
let
eth = lib.types.either (leafProviderFnType cnf) (curriedProviderFnType cnf);
in
eth
// { # <-- This bit here was the culprit, the updated signatures allow us to keep it and should work now
merge =
loc: defs:
(aspectType cnf).merge loc [
{
file = (lib.last defs).file;
value = {
__functor = _: eth.merge loc defs;
};
}
];
};
``` |
vic
approved these changes
Apr 9, 2026
Owner
|
Thanks, @sini |
sini
added a commit
to sini/den
that referenced
this pull request
Apr 11, 2026
PR vic#410 added coercedProviderType to make `{host, ...}: {nixos = ...}` aspects merge with sibling static `.nixos = ...` defs (fixes vic#408). The predicate was too broad: any non-module function got wrapped into `{ includes = [fn] }`, which silently broke "factory" aspects like: den.aspects.facter = reportPath: { nixos = ...; }; den.aspects.igloo.includes = [ (den.aspects.facter "/path") ]; Coercing turns den.aspects.facter into a full aspect with the default functor. Calling `(facter "/path")` invokes the default functor in a non-static branch with the string as `ctx` — the user's `reportPath` is discarded and the config body never materializes. Narrow the predicate with `lib.functionArgs v != {}`. Context fns have destructured named args (non-empty functionArgs) and still get coerced. Factory fns with a bare positional arg stay typed as providerFnType, whose merge wraps the underlying function via `__functor = _: eth.merge loc defs` so `(aspect arg)` correctly dispatches to the user function. Bisected to d266c3a (PR vic#410). Minimal repro verified broken at that commit and working at v0.15.0. Fix passes the new deadbugs test plus all 278 existing CI tests including deadbugs-issue-408 (context-fn + static merge still works). Fixes vic#429.
vic
pushed a commit
that referenced
this pull request
Apr 11, 2026
PR #410 added coercedProviderType to make `{host, ...}: {nixos = ...}` aspects merge with sibling static `.nixos = ...` defs (fixes #408). The predicate was too broad: any non-module function got wrapped into `{ includes = [fn] }`, which silently broke "factory" aspects like: den.aspects.facter = reportPath: { nixos = ...; }; den.aspects.igloo.includes = [ (den.aspects.facter "/path") ]; Coercing turns den.aspects.facter into a full aspect with the default functor. Calling `(facter "/path")` invokes the default functor in a non-static branch with the string as `ctx` — the user's `reportPath` is discarded and the config body never materializes. Narrow the predicate with `lib.functionArgs v != {}`. Context fns have destructured named args (non-empty functionArgs) and still get coerced. Factory fns with a bare positional arg stay typed as providerFnType, whose merge wraps the underlying function via `__functor = _: eth.merge loc defs` so `(aspect arg)` correctly dispatches to the user function. Bisected to d266c3a (PR #410). Minimal repro verified broken at that commit and working at v0.15.0. Fix passes the new deadbugs test plus all 278 existing CI tests including deadbugs-issue-408 (`context-fn + static` merge still works). Fixes #429.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Return { includes = [fn] } instead of a bare function, matching the POC pattern. The function result lives in includes where parametric.applyIncludes handles it with withIdentity, preserving the aspect name through resolution. Fixes #408.