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 diff --git a/modules/aspects/provides/forward.nix b/modules/aspects/provides/forward.nix index bb690867..8c66c07a 100644 --- a/modules/aspects/provides/forward.nix +++ b/modules/aspects/provides/forward.nix @@ -51,6 +51,10 @@ let intoClass = fwd.intoClass item; intoPath = fwd.intoPath item; + 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; @@ -76,7 +80,7 @@ let fromClass intoClass ] - ++ intoPath + ++ staticIntoPath ); guardArgs = if guard == null then { } else lib.functionArgs guard; @@ -99,7 +103,7 @@ let ]) ]; ${intoClass} = { - __functionArgs = guardArgs; + __functionArgs = guardArgs // intoPathArgs; __functor = _: args: { options.den.fwd.${adapterKey} = lib.mkOption { default = { }; @@ -108,7 +112,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 +165,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..7fdb2510 --- /dev/null +++ b/templates/ci/modules/features/dynamic-intopath.nix @@ -0,0 +1,125 @@ +{ 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"; + } + ); + + }; +}