Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion nix/lib/parametric.nix
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,26 @@ let
# wrappers have __functor. Re-resolving either would double-apply
# context and duplicate modules.
isBareResult = builtins.isAttrs r && r ? includes && !(r ? meta) && !(r ? __functor);
# Full aspect objects have meta set by aspectMeta.
isFullAspect = sub: builtins.isAttrs sub && sub ? meta;
# Extract only owned class-module keys from a full aspect,
# stripping all aspect infrastructure / metadata keys.
# If the result is non-empty the sub has static owned class configs
# (e.g. nixos = { ... }) that withOwn would skip in a parametric ctx.
# Keys declared as options in aspectSubmodule (types.nix).
# Everything else in a merged aspect attrset is freeform class config.
classConfig =
sub:
builtins.removeAttrs sub [
"includes"
"__functor"
"__functionArgs"
"name"
"description"
"meta"
"provides"
"_"
];
in
if r == { } then
r
Expand All @@ -43,9 +63,25 @@ let
includes = map (
sub:
let
cc = classConfig sub;
sr = takeFn sub ctx;
subIncludes = builtins.filter (x: x != { }) (
map (applyDeep takeFn ctx) (sub.includes or [ ])
);
in
if sr != { } then sr else sub
if isFullAspect sub && cc != { } then
# Static sub-aspect: withOwn skips owned class configs in parametric
# contexts (it only returns the functor branch). Extract and include
# the class configs explicitly, then recurse into sub.includes so any
# nested parametric includes also receive the context.
{ includes = [ cc ] ++ subIncludes; }
else if sr != { } then
# Parametric sub-aspect (bare fn coerced to { includes = [fn] }):
# takeFn fires the functor which captures the context and propagates
# it into the sub's includes, so sr already contains everything needed.
sr
else
sub
) r.includes;
}
else
Expand Down
32 changes: 16 additions & 16 deletions templates/bogus/flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 30 additions & 15 deletions templates/bogus/modules/bug.nix
Original file line number Diff line number Diff line change
@@ -1,26 +1,41 @@
{ denTest, ... }:
{ denTest, lib, ... }:
{
flake.tests.bogus = {

test-something = denTest (
{ den, igloo, ... }:
{
den,
lib,
igloo, # igloo = nixosConfigurations.igloo.config
tuxHm, # tuxHm = igloo.home-manager.users.tux
...
}:
{
# replace <system> if you are reporting a bug in MacOS
den.hosts.x86_64-linux.igloo.users.tux = { };

# do something for testing
den.aspects.tux.user.description = "The Penguin";
imports =
let

b = {
den.aspects.role = { host, ... }: {
includes = [
den.aspects.role._.sub
];
};
};

expr = igloo.users.users.tux.description;
expected = "The Penguin";
c = {
den.aspects.role._.sub.nixos.networking.networkmanager.enable = true;
};
# Change c to the below, and it works.
# c = {
# den.aspects.role._.sub = { ... }: {
# nixos.networking.networkmanager.enable = true;
# };
# };

e = {
den.aspects.igloo.includes = [ den.aspects.role ];
};
in
[ b c e ];

expr = igloo.networking.networkmanager.enable;
expected = true;
}
);

};
}
Loading