Skip to content
Merged
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
45 changes: 27 additions & 18 deletions nix/lib/aspects/fx/pipeline.nix
Original file line number Diff line number Diff line change
Expand Up @@ -119,28 +119,37 @@ let
# It defaults to `name`, so only kinds that rewrite `name` differ here.
# Synthetic context values (e.g. a bare `{ name = ...; }` host) carry no
# `__scopeName` and fall back to `name`.
# A ctx value that cannot be NAMED carries no identity: it can only render as
# its own type (`den=<set:den>`), which distinguishes nothing and splits one
# logical scope across two ids depending on which module args happened to be
# bound on the path. Such keys are dropped from the IDENTITY; they stay in the
# context itself, where binding still reads them.
nameScopeValue =
k: v:
if builtins.isAttrs v && v ? __scopeName then
v.__scopeName
else if builtins.isAttrs v && v ? name then
v.name
else if builtins.isString v then
v
else if builtins.isInt v || builtins.isFloat v then
toString v
else
null;

mkScopeId =
ctx:
lib.concatStringsSep "," (
lib.sort (a: b: a < b) (
map (
k:
let
v = ctx.${k};
in
"${k}=${
if builtins.isAttrs v && v ? __scopeName then
v.__scopeName
else if builtins.isAttrs v && v ? name then
v.name
else if builtins.isString v then
v
else if builtins.isInt v || builtins.isFloat v then
toString v
else
"<${builtins.typeOf v}:${k}>"
}"
) (builtins.attrNames ctx)
builtins.filter (s: s != null) (
map (
k:
let
named = nameScopeValue k ctx.${k};
in
if named == null then null else "${k}=${named}"
) (builtins.attrNames ctx)
)
)
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# theutz on #682: a quirk producer reached through `den.hosts.<name>.includes`
# yields an empty collection at the consumer, while the same producer reached
# through `den.aspects.<name>.includes` yields its value. Two screenshots, a
# two-byte diff (`hosts` -> `aspects`), same eval:
#
# den.hosts.kocaeli.includes = [ rootshell ]; => homebrew.taps == [ ]
# den.aspects.kocaeli.includes = [ rootshell ]; => homebrew.taps == [ {...} ]
#
# Distinct from #681: ONE definition of the collection, so nothing is being
# dropped by the registry merge. The reported config is darwin and uses the
# flat `den.hosts.<name>` spelling, neither of which the linux cells cover.
{ denTest, lib, ... }:
{
flake.tests.deadbugs.quirk-instance-includes-darwin = {

# CONTROL: the aspect spelling from the second screenshot.
test-darwin-aspect-includes = denTest (
{ den, apple, ... }:
{
den.hosts.aarch64-darwin.apple = { };
den.quirks.taps.description = "homebrew taps";

den.aspects.rootshell.taps = [ "kitknox/rootshell" ];
den.aspects.apple = {
includes = [ den.aspects.rootshell ];
darwin =
{
taps ? [ ],
...
}:
{
environment.etc."taps".text = lib.concatStringsSep "," (lib.flatten taps);
};
};

expr = apple.environment.etc."taps".text or "<dropped>";
expected = "kitknox/rootshell";
}
);

# The reported case, two-level spelling.
test-darwin-instance-includes = denTest (
{ den, apple, ... }:
{
den.quirks.taps.description = "homebrew taps";

den.aspects.rootshell.taps = [ "kitknox/rootshell" ];
den.aspects.apple.darwin =
{
taps ? [ ],
...
}:
{
environment.etc."taps".text = lib.concatStringsSep "," (lib.flatten taps);
};

den.hosts.aarch64-darwin.apple.includes = [ den.aspects.rootshell ];

expr = apple.environment.etc."taps".text or "<dropped>";
expected = "kitknox/rootshell";
}
);

# The reported case verbatim: flat spelling, and the host declared in one
# module with the collection added from another, as in the screenshots
# (`kocaeli.nix` declares the host, `rootshell.nix` adds the include).
test-darwin-flat-instance-includes-split = denTest (
{ den, apple, ... }:
{
den.quirks.taps.description = "homebrew taps";

den.aspects.rootshell.taps = [ "kitknox/rootshell" ];
den.aspects.apple.darwin =
{
taps ? [ ],
...
}:
{
environment.etc."taps".text = lib.concatStringsSep "," (lib.flatten taps);
};

imports = [
{ den.hosts.apple.system = "aarch64-darwin"; }
{ den.hosts.apple.includes = [ den.aspects.rootshell ]; }
];

expr = apple.environment.etc."taps".text or "<dropped>";
expected = "kitknox/rootshell";
}
);

};
}
Loading
Loading