diff --git a/examples/haumea.nix b/examples/haumea.nix index 716b759..3445a73 100755 --- a/examples/haumea.nix +++ b/examples/haumea.nix @@ -33,7 +33,7 @@ let self: super: { exports.mergedOutputs = with dmerge; - merge self.outputsForTarget.default { + merge self.outputs.default { treefmt.formatter.prettier.includes = append [ "*.jsl" ]; data.foo = "barzf"; }; @@ -65,7 +65,7 @@ let [ (extendPop pops.exporter ( self: super: { - exports.customModules = self.outputsForTarget.dmerge { + exports.customModules = self.outputs.dmerge { config.services.openssh.enable = false; config.services.openssh.customList = [ "1" ]; imports = with dmerge; append [ ]; @@ -77,8 +77,8 @@ let evalModules = l.evalModules { modules = [ g.exports.customModules.services.openssh - g.outputsForTarget.default.programs.emacs - g.outputsForTarget.default.programs.git + g.outputs.default.programs.emacs + g.outputs.default.programs.git ]; }; diff --git a/src/haumea/__targetOutputs.nix b/src/haumea/__targetOutputs.nix deleted file mode 100644 index e0aaeec..0000000 --- a/src/haumea/__targetOutputs.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ - haumeaOutputs, - type, - self, - lib, -}: -let - nixosModulesOutputs = - if (type == "nixosModules") then - rec { - nixosModules = { - options = haumeaOutputs.options or { }; - imports = (haumeaOutputs.imports or [ ]) ++ self.imports; - config = builtins.removeAttrs haumeaOutputs [ - "options" - "imports" - ]; - }; - default = nixosModules; - } - else - { } - ; -in -{ - default = haumeaOutputs; -} diff --git a/src/haumea/nixosModules.nix b/src/haumea/nixosModules.nix index 08b7da1..695839f 100644 --- a/src/haumea/nixosModules.nix +++ b/src/haumea/nixosModules.nix @@ -37,8 +37,7 @@ let )); base = { - attrs ? { }, - dmergePath ? [ ], + extenders ? [ ], }: haumea.lib.load { inherit (cfg) src inputs; @@ -55,6 +54,7 @@ let let mkModulePath = attrs': l.setAttrByPath (relModulePathWithoutDefault path) attrs'; + test = config._module.args.pkgs or { }; baseModuleArgs = ( inputs @@ -64,35 +64,67 @@ let cfg = l.attrByPath (relModulePathWithoutDefault path) { } config; opt = l.attrByPath (relModulePathWithoutDefault path) { } options; inherit mkModulePath; - } - // l.optionals (cfg.type == "nixosModules" || cfg.type == "nixosProfiles") { moduleArgs = config._module.args // config._module.specialArgs; } + // l.optionalAttrs (cfg == "nixosModules" || cfg.type == "nixosProfiles") { + pkgs = config._module.args.pkgs; + } ) ); moduleArgs = baseModuleArgs // { loadSubmodule = - path: - (x: mkDmergeModule (winnow path x lib.id)) ( - builtins.scopedImport baseModuleArgs path - ); + path: (mkExtenders (builtins.scopedImport baseModuleArgs path) path); }; - # reset the options to the demerged module - mkDmergeModule = x: x // (dmergeModuleFun (removeAttrs x [ "options" ])); + callArgsLazily = + attrs: extraArgs: + if (l.isFunction attrs) then + lazyArgsPerParameter attrs (moduleArgs // extraArgs) + else + attrs + ; + s3 = callModuleLazily moduleArgs path; # => { config = { }; imports = [... ]; _file } - s3Module = (mkDmergeModule (winnow path s3 mkModulePath)); - s3Profile = mkDmergeModule s3; + s3final = + let + s3Module = mkExtenders (winnow path s3 mkModulePath) path; + s3Profile = mkExtenders s3; + in + if cfg.type == "nixosModules" then s3Module else s3Profile; + + mkExtenders = + module: path: + let + removedOptionModule = removeAttrs module [ "options" ]; + filteredList = + l.filter (item: item.path == (trace (relModulePathWithoutDefault path))) + extenders; + + foundItem = + if (builtins.length filteredList) > 0 then + (builtins.head filteredList) + else + [ ] + ; + + loadExtendModuleFromValue = + if foundItem != [ ] then + (callArgsLazily foundItem.value { + self = module; + # add the options back in + # dmerge self' {} + self' = x: module // (x removedOptionModule); + # add dmerge support + inherit dmerge; + }) + else + module + ; + in + loadExtendModuleFromValue; - dmergeModuleFun = - module: - if ((relModulePathWithoutDefault path) == dmergePath) then - (dmerge module attrs') - else - module - ; winnow = path: module: fun: ({ @@ -114,9 +146,8 @@ let options = fun module.options or { }; } ; - attrs' = if (l.isFunction attrs) then attrs moduleArgs else attrs; in - if cfg.type == "nixosModules" then s3Module else s3Profile; + s3final; in module ); @@ -130,18 +161,7 @@ let in { default = base { }; - dmerge = - attrs: path: - l.getAttrFromPath path ( - base { - inherit attrs; - dmergePath = path; - } - ); + __extenders = extenders: base { inherit extenders; }; } -// ( - if (cfg.type == "nixosModules") then - { nixosModules = base { }; } - else - { nixosProfiles = base { }; } -) +// l.optionalAttrs (cfg.type == "nixosModules") { nixosModules = base { }; } +// l.optionalAttrs (cfg.type == "nixosProfiles") { nixosProfiles = base { }; } diff --git a/src/haumea/pops.nix b/src/haumea/pops.nix index 7da3f6e..b1ed885 100644 --- a/src/haumea/pops.nix +++ b/src/haumea/pops.nix @@ -42,39 +42,25 @@ let }; }; - targetExtender = pop { - defaults = { - outputsForTarget = { }; - }; + outputsExtender = pop { + defaults = { }; extension = self: super: { - setTargetOutputs = - outputsForTarget: extendPop self (self: super: { inherit outputsForTarget; }); - - addTargetExtender = targetExtender: self.addTargetExtenders [ targetExtender ]; - addTargetExtenders = - targetExtenders: + addOutputsExtender = + outputExtender: self.addOutputsExtenders [ outputExtender ]; + addOutputsExtenders = + outputsExtenders: extendPop self ( - self: super: { targetExtenders = super.targetExtenders ++ targetExtenders; } + self: super: { outputsExtenders = super.outputsExtenders ++ outputsExtenders; } ); }; }; - nixosModulesExtender = pop { - defaults = { - imports = [ ]; - }; - extension = self: super: { - setOutputsForTarger = - (outputsForTarget: extendPop self (self: super: { inherit outputsForTarget; })); - }; - }; - exporter = pop { defaults = { exports = { }; loadCfg = { }; }; - supers = [ targetExtender ]; + supers = [ outputsExtender ]; extension = self: super: { setLoad = defun @@ -115,7 +101,6 @@ let default = pop { supers = [ loadExtender - nixosModulesExtender exporter ]; defaults = { @@ -131,17 +116,14 @@ let ( acc: extender: let - ex' = - ((extender.setOutputs self.outputsForTarget.default).setTargetOutputs - self.outputsForTarget - ); + ex' = (extender.setOutputs self.outputs); in acc // ex'.exports ) { } self.exporters; in - generalExporters // self.outputsForTarget; + generalExporters; # -- exportersExtener -- addExporter = exporter: self.addExporters [ exporter ]; addExporters = @@ -196,38 +178,29 @@ let # laziest way to get the outputs # default is to merge the outputs with dmerege outputs = - defun - ( - with types; [ - (either function (attrs any)) - (attrs any) - ] - ) - ( - x: - if l.isFunction x then - x self.outputsForTarget.default - else if x != { } then - dmerge.merge self.outputsForTarget.default x - else - self.outputsForTarget.default - ); - outputsForTarget = - let - cfg = (exporter.setLoad self.loadCfg).loadCfg; - haumeaOutputs = - if (cfg.type == "nixosModules" || cfg.type == "nixosProfiles") then - nixosModules { inherit cfg; } - else - { default = haumea.lib.load (l.removeAttrs cfg [ "type" ]); } - ; - targetOutputs = import ./__targetOutputs.nix { - inherit (cfg) type; - inherit haumeaOutputs; - inherit self lib; - }; - in - haumeaOutputs; + ( + let + cfg = (exporter.setLoad self.loadCfg).loadCfg; + haumeaOutputs = + if (cfg.type == "nixosModules" || cfg.type == "nixosProfiles") then + nixosModules { inherit cfg; } + else + { default = haumea.lib.load (l.removeAttrs cfg [ "type" ]); } + ; + in + haumeaOutputs + // (l.optionalAttrs (!haumeaOutputs ? __extenders) { + __extender = + x: + if l.isFunction x then + x self.outputs.default + else if x != { } then + dmerge.merge self.outputs.default x + else + self.outputs.default + ; + }) + ); }; }; in diff --git a/src/haumea/structAttrs.nix b/src/haumea/structAttrs.nix index a9e11ae..3626296 100644 --- a/src/haumea/structAttrs.nix +++ b/src/haumea/structAttrs.nix @@ -64,6 +64,7 @@ let "nixosModules" "default" "nixosProfiles" + "evalModules" ] "type"; }; diff --git a/templates/default/flake.nix b/templates/default/flake.nix index 2ec15d7..6818c1d 100644 --- a/templates/default/flake.nix +++ b/templates/default/flake.nix @@ -22,12 +22,12 @@ in { eval = nixpkgs.lib.evalModules { - modules = [ self.loadModules.outputsForTarget.default.programs.git ]; + modules = [ self.loadModules.outputs.default.programs.git ]; }; nixos = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; - modules = [ self.loadModules.outputsForTarget.default.programs.git ]; + modules = [ self.loadModules.outputs.default.programs.git ]; }; loadModules = flops.lib.haumea.pops.default.setInit { src = ./nixosModules; diff --git a/tests/_snapshots/evalModules b/tests/_snapshots/evalModules index 8d1903c..317301a 100644 --- a/tests/_snapshots/evalModules +++ b/tests/_snapshots/evalModules @@ -4,26 +4,11 @@ programs = { git = { __profiles__ = { - enable = true; - name = "John Doe"; + enable = false; + name = "guangtao"; }; }; }; - services = { - openssh = { - customList = [ - "a" - "1" - ]; - customList2 = [ ]; - customList3 = [ ]; - customList4 = [ - "mkMerge" - ]; - enable = false; - enableCustom = false; - }; - }; }; default = { programs = { diff --git a/tests/_snapshots/haumeaData b/tests/_snapshots/haumeaData index e712d4e..b3806f4 100644 --- a/tests/_snapshots/haumeaData +++ b/tests/_snapshots/haumeaData @@ -28,24 +28,6 @@ }; }; }; - default = { - data = { - foo = "baz"; - }; - treefmt = { - formatter = { - nix = { - command = "alejandra"; - excludes = [ ]; - }; - }; - prettier = { - includes = [ - "*.toml" - ]; - }; - }; - }; }; }; outputs = { diff --git a/tests/_snapshots/haumeaNixOSModules b/tests/_snapshots/haumeaNixOSModules index a2a44a6..d15fec7 100644 --- a/tests/_snapshots/haumeaNixOSModules +++ b/tests/_snapshots/haumeaNixOSModules @@ -2,43 +2,12 @@ { exports = { success = true; - value = { - default = { - programs = { - emacs = ; - git = ; - }; - services = { - openssh = ; - }; - }; - dmerge = ; - nixosModules = { - programs = { - emacs = ; - git = ; - }; - services = { - openssh = ; - }; - }; - }; + value = { }; }; outputs = { success = true; value = { - programs = { - emacs = ; - git = ; - }; - services = { - openssh = ; - }; - }; - }; - outputsForTarget = { - success = true; - value = { + __extenders = ; default = { programs = { emacs = ; @@ -48,7 +17,6 @@ openssh = ; }; }; - dmerge = ; nixosModules = { programs = { emacs = ; diff --git a/tests/evalModules/__fixture/programs/git/opt.nix b/tests/evalModules/__fixture/programs/git/opt.nix index 7cb837e..9462c3a 100644 --- a/tests/evalModules/__fixture/programs/git/opt.nix +++ b/tests/evalModules/__fixture/programs/git/opt.nix @@ -1,4 +1,5 @@ { + config.programs.git.__profiles__.name = "John Doe"; options = with lib; (mkModulePath { @@ -6,7 +7,7 @@ enable = mkEnableOption (lib.mdDoc "Whether to enable git profile"); name = lib.mkOption { type = types.str; - default = "John Doe"; + default = ""; description = "Your name"; }; }; diff --git a/tests/evalModules/expr.nix b/tests/evalModules/expr.nix index f17312d..c3ced26 100644 --- a/tests/evalModules/expr.nix +++ b/tests/evalModules/expr.nix @@ -17,17 +17,31 @@ let [ (extendPop pops.exporter ( self: super: { - exports.customModules.git = - self.outputsForTarget.dmerge - { - config.services.openssh.enable = false; - config.services.openssh.customList = with dmerge; append [ "1" ]; - imports = with dmerge; append [ ]; - } - [ - "services" - "openssh" + exports.test = self.outputs.__extenders [ + ({ + value = + ( + { self' }: + self' (m: dmerge m { config.programs.git.__profiles__.enable = false; }) + ); + path = [ + "programs" + "git" ]; + }) + ({ + value = + ( + { self' }: + self' (m: dmerge m { config.programs.git.__profiles__.name = "guangtao"; }) + ); + path = [ + "programs" + "git" + "opt" + ]; + }) + ]; } )) ]; @@ -36,32 +50,16 @@ let default = (evalModules { modules = [ - loadModules.outputsForTarget.default.programs.git - loadModules.outputsForTarget.default.programs.emacs - loadModules.outputsForTarget.default.services.openssh + loadModules.outputs.default.programs.git + loadModules.outputs.default.programs.emacs + loadModules.outputs.default.services.openssh ]; }).config; custom = (evalModules { modules = [ - # ( - # { - # lib, - # config, - # options, - # ... - # }@args: - # { - # options = { - # __test__ = lib.mkOption { - # type = lib.types.unspecified; - # default = loadModules.exports.customModules.git args; - # }; - # }; - # } - # ) - loadModules.exports.customModules.git - loadModules.outputsForTarget.default.programs.git + loadModules.exports.test.programs.git + # loadModules.outputs.default.programs.git ]; }).config; }; diff --git a/tests/haumeaData/expr.nix b/tests/haumeaData/expr.nix index 829dd80..de9e1e5 100644 --- a/tests/haumeaData/expr.nix +++ b/tests/haumeaData/expr.nix @@ -26,7 +26,7 @@ let self: super: { exports.customData = with dmerge; - merge self.outputs { + self.outputs.__extender { treefmt.formatter.nix.excludes = append [ "data.nix" ]; treefmt.formatter.prettier.includes = append [ "*.jsl" ]; }; @@ -38,12 +38,12 @@ let in mapAttrs (_: x: tryEval (deepSeq x x)) { outputs = { - default = data.outputs { }; - dmergeOutputs = data.outputs { + default = data.outputs.default; + dmergeOutputs = data.outputs.__extender { treefmt.formatter.nix.command = "nixfmt"; treefmt.formatter.prettier.includes = with dmerge; append [ "*.dmergeOutputs" ]; }; - funOutputs = data.outputs ( + funOutputs = data.outputs.__extender ( x: x // { diff --git a/tests/haumeaNixOSModules/expr.nix b/tests/haumeaNixOSModules/expr.nix index 5c2b48b..8bf4fe1 100644 --- a/tests/haumeaNixOSModules/expr.nix +++ b/tests/haumeaNixOSModules/expr.nix @@ -42,9 +42,7 @@ let in mapAttrs (_: x: tryEval (deepSeq x x)) { - outputsForTarget = nixosModules.outputsForTarget; - - outputs = nixosModules.outputs { }; + outputs = nixosModules.outputs; exports = nixosModules.exports; }