From d5887823c87e15d3b98de55b47eb4a807f78bb8f Mon Sep 17 00:00:00 2001 From: Damnjelly Date: Sat, 28 Mar 2026 10:57:18 +0100 Subject: [PATCH 1/4] feat(core): support functionArgs in IntoPath --- modules/aspects/provides/forward.nix | 21 ++- .../ci/modules/features/dynamic-intopath.nix | 123 ++++++++++++++++++ 2 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 templates/ci/modules/features/dynamic-intopath.nix diff --git a/modules/aspects/provides/forward.nix b/modules/aspects/provides/forward.nix index bb690867..e50fcab0 100644 --- a/modules/aspects/provides/forward.nix +++ b/modules/aspects/provides/forward.nix @@ -49,7 +49,17 @@ let let fromClass = fwd.fromClass item; intoClass = fwd.intoClass item; - intoPath = fwd.intoPath item; + intoPath = + let + raw = + builtins.trace item + fwd.intoPath; + in + if lib.functionArgs raw != { } then raw else raw item; + + intoPathArgs = if builtins.isFunction intoPath then lib.functionArgs intoPath else { }; + intoPathFn = if builtins.isFunction intoPath then intoPath else _: intoPath; + staticIntoPath = if builtins.isFunction intoPath then [ ] else intoPath; asp = fwd.fromAspect item; sourceModule = den.lib.aspects.resolve fromClass asp; @@ -76,7 +86,7 @@ let fromClass intoClass ] - ++ intoPath + ++ staticIntoPath ); guardArgs = if guard == null then { } else lib.functionArgs guard; @@ -99,7 +109,7 @@ let ]) ]; ${intoClass} = { - __functionArgs = guardArgs; + __functionArgs = guardArgs // intoPathArgs; __functor = _: args: { options.den.fwd.${adapterKey} = lib.mkOption { default = { }; @@ -108,7 +118,7 @@ let modules = adapterMods; }; }; - config = guardFn args (lib.setAttrByPath intoPath args.config.den.fwd.${adapterKey}); + config = guardFn args (lib.setAttrByPath (intoPathFn args) args.config.den.fwd.${adapterKey}); }; }; }; @@ -161,7 +171,8 @@ let evalImport args; }; - needsAdapter = guard != null || adaptArgs != null || adapterModule != null; + needsAdapter = + guard != null || adaptArgs != null || adapterModule != null || builtins.isFunction intoPath; needsTopLevelAdapter = needsAdapter && intoPath == [ ]; forwarded = forward intoPath; diff --git a/templates/ci/modules/features/dynamic-intopath.nix b/templates/ci/modules/features/dynamic-intopath.nix new file mode 100644 index 00000000..8529a568 --- /dev/null +++ b/templates/ci/modules/features/dynamic-intopath.nix @@ -0,0 +1,123 @@ +{ denTest, ... }: +{ + flake.tests.dynamic-intopath = { + + test-dynamic-intoPath-host-scope = denTest ( + { + den, + lib, + igloo, + ... + }: + let + slotMod = + { lib, ... }: + { + options.my-slot = lib.mkOption { + type = lib.types.str; + default = "slot-a"; + }; + options.my-box = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submoduleWith { + modules = [ + { + config._module.freeformType = lib.types.lazyAttrsOf lib.types.anything; + } + ]; + } + ); + default = { }; + }; + }; + + forwarded = + { class, aspect-chain }: + den._.forward { + each = lib.singleton class; + fromClass = _: "src"; + intoClass = _: "nixos"; + intoPath = + { config, ... }: + [ + "my-box" + config.my-slot + ]; + fromAspect = _: lib.head aspect-chain; + }; + in + { + den.hosts.x86_64-linux.igloo.users.tux = { }; + den.aspects.igloo = { + includes = [ forwarded ]; + nixos.imports = [ slotMod ]; + nixos.my-slot = "slot-b"; + src.my-data = "hello-from-src"; + }; + + expr = igloo.my-box.slot-b.my-data; + expected = "hello-from-src"; + } + ); + + test-dynamic-intoPath-user-scope = denTest ( + { + den, + lib, + igloo, + ... + }: + let + slotMod = + { lib, ... }: + { + options.my-slot = lib.mkOption { + type = lib.types.str; + default = "slot-a"; + }; + options.my-box = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submoduleWith { + modules = [ + { + config._module.freeformType = lib.types.lazyAttrsOf lib.types.anything; + } + ]; + } + ); + default = { }; + }; + }; + + forwarded = + { class, aspect-chain }: + den._.forward { + each = lib.singleton class; + fromClass = _: "src"; + intoClass = _: "homeManager"; + intoPath = + { config, ... }: + [ + "my-box" + config.my-slot + ]; + fromAspect = _: lib.head aspect-chain; + }; + in + { + den.hosts.x86_64-linux.igloo.users.tux = { }; + den.aspects.igloo.homeManager.home.stateVersion = "25.11"; + den.aspects.tux = { + includes = [ forwarded ]; + homeManager.imports = [ slotMod ]; + homeManager.my-slot = "slot-b"; + src.my-data = "hello-from-src"; + }; + + expr = igloo.home-manager.users.tux.my-box.slot-b.my-data; + expected = "hello-from-src"; + } + ); + + }; +} From 69b59d6375fc1984177615efeb141b1ee8a06307 Mon Sep 17 00:00:00 2001 From: Damnjelly Date: Sat, 28 Mar 2026 10:57:49 +0100 Subject: [PATCH 2/4] fix(docs): typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7f8468a8..08960bec 100644 --- a/README.md +++ b/README.md @@ -416,9 +416,9 @@ persys = { host }: den._.forward { each = lib.singleton true; fromClass = _: "persys"; intoClass = _: host.class; - intoPath = _: [ "environment" "persistance" "/nix/persist/system" ]; + intoPath = _: [ "environment" "persistence" "/nix/persist/system" ]; fromAspect = _: den.aspects.${host.aspect}; - guard = { options, config, ... }: options ? environment.persistance; + guard = { options, config, ... }: options ? environment.persistence; }; # enable on all hosts From bd98ccaaa13b4c71dd006f7bcb296348eea461a6 Mon Sep 17 00:00:00 2001 From: Gelei Date: Sat, 28 Mar 2026 11:30:14 +0100 Subject: [PATCH 3/4] remove leftover trace from commit Signed-off-by: Gelei --- modules/aspects/provides/forward.nix | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/aspects/provides/forward.nix b/modules/aspects/provides/forward.nix index e50fcab0..d0fad800 100644 --- a/modules/aspects/provides/forward.nix +++ b/modules/aspects/provides/forward.nix @@ -51,9 +51,7 @@ let intoClass = fwd.intoClass item; intoPath = let - raw = - builtins.trace item - fwd.intoPath; + raw = fwd.intoPath; in if lib.functionArgs raw != { } then raw else raw item; From 29df6c11053ee765663cc3f87956a955cd57b9a0 Mon Sep 17 00:00:00 2001 From: Victor Borja Date: Sat, 28 Mar 2026 22:05:04 -0600 Subject: [PATCH 4/4] allow intoPath be `item: moduleArgs:` --- modules/aspects/provides/forward.nix | 12 ++++-------- templates/ci/modules/features/dynamic-intopath.nix | 2 ++ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/modules/aspects/provides/forward.nix b/modules/aspects/provides/forward.nix index d0fad800..8c66c07a 100644 --- a/modules/aspects/provides/forward.nix +++ b/modules/aspects/provides/forward.nix @@ -49,15 +49,11 @@ let let fromClass = fwd.fromClass item; intoClass = fwd.intoClass item; - intoPath = - let - raw = fwd.intoPath; - in - if lib.functionArgs raw != { } then raw else raw item; + intoPath = fwd.intoPath item; - intoPathArgs = if builtins.isFunction intoPath then lib.functionArgs intoPath else { }; - intoPathFn = if builtins.isFunction intoPath then intoPath else _: intoPath; - staticIntoPath = if builtins.isFunction intoPath then [ ] else intoPath; + intoPathArgs = if lib.isFunction intoPath then lib.functionArgs intoPath else { }; + intoPathFn = if lib.isFunction intoPath then intoPath else _: intoPath; + staticIntoPath = if lib.isFunction intoPath then [ ] else intoPath; asp = fwd.fromAspect item; sourceModule = den.lib.aspects.resolve fromClass asp; diff --git a/templates/ci/modules/features/dynamic-intopath.nix b/templates/ci/modules/features/dynamic-intopath.nix index 8529a568..7fdb2510 100644 --- a/templates/ci/modules/features/dynamic-intopath.nix +++ b/templates/ci/modules/features/dynamic-intopath.nix @@ -38,6 +38,7 @@ fromClass = _: "src"; intoClass = _: "nixos"; intoPath = + _: { config, ... }: [ "my-box" @@ -96,6 +97,7 @@ fromClass = _: "src"; intoClass = _: "homeManager"; intoPath = + _: { config, ... }: [ "my-box"