diff --git a/README.md b/README.md index ac508aca..726701cd 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,6 @@ These configurations become specific when applied to your particular infra entities (hosts/users), while allowing re-usable aspects to be shared between hosts, users, or across other flakes and non-flake projects. - -
| diff --git a/nix/lib/aspects/default.nix b/nix/lib/aspects/default.nix index 40ceb553..0379d65f 100644 --- a/nix/lib/aspects/default.nix +++ b/nix/lib/aspects/default.nix @@ -4,11 +4,12 @@ ... }: let + rawTypes = import ./types.nix { inherit den lib; }; + resolve = import ./resolve.nix { inherit den lib; }; + defaultFunctor = (den.lib.parametric { }).__functor; typesConf = { inherit defaultFunctor; }; - rawTypes = import ./types.nix lib; types = lib.mapAttrs (_: v: v typesConf) rawTypes; - resolve = import ./resolve.nix lib; in { inherit types resolve; diff --git a/nix/lib/aspects/resolve.nix b/nix/lib/aspects/resolve.nix index 3cabaace..537b129c 100644 --- a/nix/lib/aspects/resolve.nix +++ b/nix/lib/aspects/resolve.nix @@ -1,4 +1,4 @@ -lib: +{ lib, ... }: let resolve = diff --git a/nix/lib/aspects/types.nix b/nix/lib/aspects/types.nix index abe973ba..4978cf23 100644 --- a/nix/lib/aspects/types.nix +++ b/nix/lib/aspects/types.nix @@ -1,24 +1,6 @@ -lib: +{ lib, den, ... }: let - functorType = lib.types.mkOptionType { - name = "aspectFunctor"; - description = "aspect functor function"; - check = lib.isFunction; - merge = - _loc: defs: - let - lastDef = lib.last defs; - in - { - __functionArgs = lib.functionArgs lastDef.value; - __functor = - _: callerArgs: - let - result = lastDef.value callerArgs; - in - if builtins.isFunction result then result else _: result; - }; - }; + inherit (den.lib) lastFunctionTo; isSubmoduleFn = m: @@ -44,12 +26,11 @@ let in names != [ ] && builtins.all (n: builtins.elem n providerArgNames) names; - directProviderFn = - cnf: lib.types.addCheck (lib.types.functionTo (aspectSubmodule cnf)) isProviderFn; + directProviderFn = cnf: lib.types.addCheck (lastFunctionTo (aspectSubmodule cnf)) isProviderFn; curriedProviderFn = cnf: - lib.types.addCheck (lib.types.functionTo (providerType cnf)) ( + lib.types.addCheck (lastFunctionTo (providerType cnf)) ( f: builtins.isFunction f || @@ -109,7 +90,7 @@ let internal = true; visible = false; description = "Functor to default provider"; - type = functorType; + type = lastFunctionTo (providerType cnf); default = cnf.defaultFunctor or lib.const; }; }; diff --git a/nix/lib/default.nix b/nix/lib/default.nix index 101373c2..bca1ee64 100644 --- a/nix/lib/default.nix +++ b/nix/lib/default.nix @@ -31,6 +31,7 @@ let parametric = ./parametric.nix; statics = ./statics.nix; take = ./take.nix; + lastFunctionTo = ./last-function-to.nix; }; in den-lib diff --git a/nix/lib/last-function-to.nix b/nix/lib/last-function-to.nix new file mode 100644 index 00000000..4507836c --- /dev/null +++ b/nix/lib/last-function-to.nix @@ -0,0 +1,8 @@ +{ lib, ... }: +elemType: +lib.types.mkOptionType { + name = "lastFunctionTo"; + description = "last function to ${elemType.description}"; + check = (lib.types.functionTo elemType).check; + merge = _loc: defs: (lib.last defs).value; +} diff --git a/nix/lib/namespace.nix b/nix/lib/namespace.nix index a55edc14..d2e29e9a 100644 --- a/nix/lib/namespace.nix +++ b/nix/lib/namespace.nix @@ -8,54 +8,7 @@ let name ]) (builtins.filter builtins.isAttrs from); - internals = [ - "_" - "_module" - "__functor" - "__functionArgs" - ]; - - stripAspect = - v: - if !builtins.isAttrs v then - v - else - lib.mapAttrs ( - n: child: - if n == "provides" then - lib.mapAttrs (_: stripAspect) child - else if builtins.isAttrs child then - builtins.removeAttrs child internals - else - child - ) (builtins.removeAttrs v internals); - - stripNamespace = lib.mapAttrs (_: stripAspect); - - functorModules = - aspectPath: v: - lib.optionals (builtins.isAttrs v) ( - lib.optional (v ? __functor) { - config = lib.setAttrByPath aspectPath { __functor = v.__functor; }; - } - ++ lib.concatMap ( - pname: - functorModules ( - aspectPath - ++ [ - "provides" - pname - ] - ) v.provides.${pname} - ) (lib.attrNames (v.provides or { })) - ); - - namespaceFunctorModules = - ns: lib.concatMap (aname: functorModules [ "den" "ful" name aname ] ns.${aname}) (lib.attrNames ns); - - sourceModule = { - config.den.ful.${name} = lib.mkMerge (map stripNamespace denfuls); - }; + sourceModules = map (denful: { config.den.ful.${name} = denful; }) denfuls; aliasModule = lib.mkAliasOptionModule [ name ] [ "den" "ful" name ]; @@ -68,11 +21,9 @@ let { }; in { - imports = [ - sourceModule + imports = sourceModules ++ [ aliasModule outputModule - ] - ++ lib.concatMap namespaceFunctorModules denfuls; + ]; config._module.args.${name} = config.den.ful.${name}; } diff --git a/nix/lib/parametric.nix b/nix/lib/parametric.nix index cdbdc986..e8619cd8 100644 --- a/nix/lib/parametric.nix +++ b/nix/lib/parametric.nix @@ -17,7 +17,11 @@ let provided // { includes = map ( - include: if include ? includes then parametric.deep functor ctx include else include + include: + if include ? includes then + if include ? __functor then include else parametric.deep functor ctx include + else + include ) (provided.includes or [ ]); }; diff --git a/templates/ci/modules/features/deadbugs/issue-352-exported-providers-function-arg-reflection.nix b/templates/ci/modules/features/deadbugs/issue-352-exported-providers-function-arg-reflection.nix new file mode 100644 index 00000000..ab024add --- /dev/null +++ b/templates/ci/modules/features/deadbugs/issue-352-exported-providers-function-arg-reflection.nix @@ -0,0 +1,77 @@ +{ denTest, ... }: +{ + flake.tests.deadbugs-issue-352 = + let + module = + { inputs, ... }: + { + imports = [ + inputs.den.flakeModule + (inputs.den.namespace "test" true) + ]; + + test.aspect._.host = + { host, ... }: + { + nixos.environment.sessionVariables.TEST_HOST = host.name; + }; + }; + internal = module; + external = + inputs: + (inputs.nixpkgs.lib.evalModules { + specialArgs = { inherit inputs; }; + modules = [ module ]; + }).config.flake; + in + { + test-internal-exported-providers-function-arg-reflection = denTest ( + { + lib, + test, + ... + }: + { + imports = [ internal ]; + + expr = lib.functionArgs test.aspect._.host; + expected = { + host = false; + }; + } + ); + + test-raw-exported-providers-function-arg-reflection = denTest ( + { + inputs, + lib, + test, + ... + }: + { + expr = lib.functionArgs (external inputs).denful.test.aspect._.host; + expected = { + host = false; + }; + } + ); + + test-external-exported-providers-function-arg-reflection = denTest ( + { + inputs, + test, + lib, + ... + }: + + { + imports = [ (inputs.den.namespace "test" [ (external inputs) ]) ]; + + expr = lib.functionArgs test.aspect._.host; + expected = { + host = false; + }; + } + ); + }; +} |