mirror of
https://github.com/mjallen18/snowfall-lib.git
synced 2026-04-18 09:05:58 -05:00
fix(home): forward exported hm args
Resolve exported home configurations against their parent system config so hosted and bare-name homes keep the same Home Manager specialArgs on package and homeConfiguration export paths. This restores arbitrary home-manager.extraSpecialArgs keys instead of only hardcoded aliases and adds regression coverage for the export resolver.
This commit is contained in:
72
flake.nix
72
flake.nix
@@ -107,6 +107,54 @@
|
|||||||
inherit system;
|
inherit system;
|
||||||
};
|
};
|
||||||
standalone-special-args = standalone-home.specialArgs;
|
standalone-special-args = standalone-home.specialArgs;
|
||||||
|
exported-home-name = "test@${system}";
|
||||||
|
resolved-exported-home = lib.snowfall.flake.resolve-exported-home {
|
||||||
|
home-name = exported-home-name;
|
||||||
|
home = {
|
||||||
|
modules = [ ];
|
||||||
|
inherit system;
|
||||||
|
specialArgs = {
|
||||||
|
host = "";
|
||||||
|
user = "test";
|
||||||
|
standaloneOnly = true;
|
||||||
|
};
|
||||||
|
builder = args: args.specialArgs;
|
||||||
|
};
|
||||||
|
systems = {
|
||||||
|
test-host = {
|
||||||
|
output = "nixosConfigurations";
|
||||||
|
inherit system;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
flake-outputs = {
|
||||||
|
nixosConfigurations = {
|
||||||
|
test-host = {
|
||||||
|
config = {
|
||||||
|
hostName = "test-host";
|
||||||
|
home-manager = {
|
||||||
|
users.test = { };
|
||||||
|
extraSpecialArgs = {
|
||||||
|
arbitraryName = "ok";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
homeConfigurations = {
|
||||||
|
${exported-home-name} = {
|
||||||
|
fallback = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
bare-name-package-alias =
|
||||||
|
"homeConfigurations-"
|
||||||
|
+ (
|
||||||
|
if pkgs.lib.hasSuffix "@${system}" exported-home-name then
|
||||||
|
pkgs.lib.removeSuffix "@${system}" exported-home-name
|
||||||
|
else
|
||||||
|
exported-home-name
|
||||||
|
);
|
||||||
eval = builtins.tryEval {
|
eval = builtins.tryEval {
|
||||||
snowfall-attrs = builtins.attrNames lib.snowfall;
|
snowfall-attrs = builtins.attrNames lib.snowfall;
|
||||||
has-standalone-home-placeholders =
|
has-standalone-home-placeholders =
|
||||||
@@ -115,13 +163,33 @@
|
|||||||
&& (standalone-special-args ? systemConfig)
|
&& (standalone-special-args ? systemConfig)
|
||||||
&& (standalone-special-args.systemConfig == null);
|
&& (standalone-special-args.systemConfig == null);
|
||||||
has-system-config-aliases =
|
has-system-config-aliases =
|
||||||
(builtins.length (builtins.split "systemConfig = config;" (builtins.readFile ./modules/nixos/user/default.nix)) > 1)
|
(
|
||||||
&& (builtins.length (builtins.split "systemConfig = config;" (builtins.readFile ./modules/darwin/user/default.nix)) > 1);
|
builtins.length (
|
||||||
|
builtins.split "systemConfig = config;" (builtins.readFile ./modules/nixos/user/default.nix)
|
||||||
|
) > 1
|
||||||
|
)
|
||||||
|
&& (
|
||||||
|
builtins.length (
|
||||||
|
builtins.split "systemConfig = config;" (builtins.readFile ./modules/darwin/user/default.nix)
|
||||||
|
) > 1
|
||||||
|
);
|
||||||
|
resolves-exported-home-extra-special-args =
|
||||||
|
resolved-exported-home ? arbitraryName
|
||||||
|
&& (resolved-exported-home.arbitraryName == "ok")
|
||||||
|
&& (resolved-exported-home ? systemConfig)
|
||||||
|
&& (resolved-exported-home.systemConfig.hostName == "test-host")
|
||||||
|
&& (resolved-exported-home ? osConfig)
|
||||||
|
&& (resolved-exported-home.osConfig.hostName == "test-host")
|
||||||
|
&& (resolved-exported-home ? standaloneOnly)
|
||||||
|
&& resolved-exported-home.standaloneOnly;
|
||||||
|
strips-bare-home-package-alias = bare-name-package-alias == "homeConfigurations-test";
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
assert eval.success;
|
assert eval.success;
|
||||||
assert eval.value.has-standalone-home-placeholders;
|
assert eval.value.has-standalone-home-placeholders;
|
||||||
assert eval.value.has-system-config-aliases;
|
assert eval.value.has-system-config-aliases;
|
||||||
|
assert eval.value.resolves-exported-home-extra-special-args;
|
||||||
|
assert eval.value.strips-bare-home-package-alias;
|
||||||
{
|
{
|
||||||
snowfall-lib-eval = pkgs.runCommand "snowfall-lib-eval" { } "mkdir -p $out";
|
snowfall-lib-eval = pkgs.runCommand "snowfall-lib-eval" { } "mkdir -p $out";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,89 @@ let
|
|||||||
"snowfall"
|
"snowfall"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
## Resolve the parent system config for an exported home configuration.
|
||||||
|
## Explicit `user@host` names map directly. Hostless names end up normalized
|
||||||
|
## to `user@system`, so fall back to a unique system-target match.
|
||||||
|
#@ Attrs -> Attrs | Null
|
||||||
|
resolve-exported-home-host-config =
|
||||||
|
{
|
||||||
|
home,
|
||||||
|
systems,
|
||||||
|
flake-outputs,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
get-host-config =
|
||||||
|
host-name:
|
||||||
|
let
|
||||||
|
system-output = systems.${host-name}.output;
|
||||||
|
in
|
||||||
|
flake-outputs.${system-output}.${host-name}.config;
|
||||||
|
|
||||||
|
requested-host = home.specialArgs.host or "";
|
||||||
|
requested-system = home.system or "";
|
||||||
|
requested-user = home.specialArgs.user or "";
|
||||||
|
host-candidates =
|
||||||
|
if requested-host != "" && systems ? ${requested-host} then
|
||||||
|
[ requested-host ]
|
||||||
|
else
|
||||||
|
pipe systems [
|
||||||
|
(filterAttrs (
|
||||||
|
host-name: system-config:
|
||||||
|
let
|
||||||
|
host-config = get-host-config host-name;
|
||||||
|
matches-explicit-target =
|
||||||
|
requested-host != ""
|
||||||
|
&& system-config.system == requested-host
|
||||||
|
&& requested-user != ""
|
||||||
|
&& builtins.hasAttr requested-user (host-config.home-manager.users or { });
|
||||||
|
matches-hostless-home =
|
||||||
|
requested-host == ""
|
||||||
|
&& system-config.system == requested-system
|
||||||
|
&& requested-user != ""
|
||||||
|
&& builtins.hasAttr requested-user (host-config.home-manager.users or { });
|
||||||
|
in
|
||||||
|
matches-explicit-target || matches-hostless-home
|
||||||
|
))
|
||||||
|
builtins.attrNames
|
||||||
|
];
|
||||||
|
in
|
||||||
|
if builtins.length host-candidates == 1 then
|
||||||
|
get-host-config (builtins.head host-candidates)
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
|
||||||
|
## Rebuild a hosted home export with the resolved parent system config so
|
||||||
|
## Home Manager module arguments stay consistent on export paths.
|
||||||
|
#@ Attrs -> Attrs
|
||||||
|
resolve-exported-home =
|
||||||
|
{
|
||||||
|
home-name,
|
||||||
|
home,
|
||||||
|
systems,
|
||||||
|
flake-outputs,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
host-config = flake.resolve-exported-home-host-config {
|
||||||
|
inherit home systems flake-outputs;
|
||||||
|
};
|
||||||
|
hosted-special-args =
|
||||||
|
if host-config != null then
|
||||||
|
{
|
||||||
|
osConfig = host-config;
|
||||||
|
systemConfig = host-config;
|
||||||
|
}
|
||||||
|
// (host-config.home-manager.extraSpecialArgs or { })
|
||||||
|
else
|
||||||
|
{ };
|
||||||
|
in
|
||||||
|
if host-config != null then
|
||||||
|
home.builder {
|
||||||
|
inherit (home) modules;
|
||||||
|
specialArgs = home.specialArgs // hosted-special-args;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
flake-outputs.homeConfigurations.${home-name};
|
||||||
|
|
||||||
## Transform an attribute set of inputs into an attribute set where the values are the inputs' `lib` attribute. Entries without a `lib` attribute are removed.
|
## Transform an attribute set of inputs into an attribute set where the values are the inputs' `lib` attribute. Entries without a `lib` attribute are removed.
|
||||||
## Example Usage:
|
## Example Usage:
|
||||||
## ```nix
|
## ```nix
|
||||||
@@ -208,30 +291,15 @@ let
|
|||||||
|
|
||||||
flake-utils-plus-outputs = core-inputs.flake-utils-plus.lib.mkFlake flake-options;
|
flake-utils-plus-outputs = core-inputs.flake-utils-plus.lib.mkFlake flake-options;
|
||||||
|
|
||||||
resolve-hosted-home =
|
|
||||||
home-name: home:
|
|
||||||
let
|
|
||||||
host = home.specialArgs.host or "";
|
|
||||||
has-hosted-system = host != "" && systems ? ${host};
|
|
||||||
in
|
|
||||||
if has-hosted-system then
|
|
||||||
let
|
|
||||||
system-output = systems.${host}.output;
|
|
||||||
host-config = flake-utils-plus-outputs.${system-output}.${host}.config;
|
|
||||||
in
|
|
||||||
home.builder {
|
|
||||||
inherit (home) modules;
|
|
||||||
specialArgs = home.specialArgs // {
|
|
||||||
osConfig = host-config;
|
|
||||||
systemConfig = host-config;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
flake-utils-plus-outputs.homeConfigurations.${home-name};
|
|
||||||
|
|
||||||
# Hosted homes need their parent system config injected before standalone
|
# Hosted homes need their parent system config injected before standalone
|
||||||
# homeConfigurations or activation packages are forced.
|
# homeConfigurations or activation packages are forced.
|
||||||
home-configurations = mapAttrs resolve-hosted-home homes;
|
home-configurations = mapAttrs (
|
||||||
|
home-name: home:
|
||||||
|
flake.resolve-exported-home {
|
||||||
|
inherit home-name home systems;
|
||||||
|
flake-outputs = flake-utils-plus-outputs;
|
||||||
|
}
|
||||||
|
) homes;
|
||||||
|
|
||||||
flake-outputs = flake-utils-plus-outputs // {
|
flake-outputs = flake-utils-plus-outputs // {
|
||||||
inherit overlays;
|
inherit overlays;
|
||||||
|
|||||||
Reference in New Issue
Block a user