diff --git a/flakeModules/clan.nix b/flakeModules/clan.nix index e50192dee..07e84dbf4 100644 --- a/flakeModules/clan.nix +++ b/flakeModules/clan.nix @@ -11,9 +11,24 @@ let inherit (lib) types; buildClanModule = clan-core.clanLib.buildClanModule; + + publicAttrs = import ../lib/build-clan/public.nix; + # Create output options only for listed attributes + outputModule = { + clan = lib.genAttrs publicAttrs.clan ( + name: + config.clan.clanInternals.${name} + or (throw "Output: clanInternals.${name} not found. Check: ${config.file}") + ); + topLevel = { + options = lib.genAttrs publicAttrs.topLevel (_: lib.mkOption { }); + config = lib.genAttrs publicAttrs.topLevel ( + name: config.clan.${name} or (throw "Output: clan.${name} not found. See: ${config.file}") + ); + }; + }; in { - options.clan = lib.mkOption { default = { }; type = types.submoduleWith { @@ -27,16 +42,16 @@ in }; }; - options.flake = flake-parts-lib.mkSubmoduleOptions { - clan = lib.mkOption { type = types.raw; }; - clanInternals = lib.mkOption { type = types.raw; }; - }; + options.flake = + flake-parts-lib.mkSubmoduleOptions { + clan = lib.mkOption { type = types.raw; }; + } + // outputModule.topLevel.options; config = { - flake.clan = { - inherit (config.clan.clanInternals) templates; - }; - flake.clanInternals = config.clan.clanInternals; - flake.nixosConfigurations = config.clan.nixosConfigurations; + flake = { + clan = outputModule.clan; + } // outputModule.topLevel.config; }; + _file = __curPos.file; } diff --git a/lib/README.md b/lib/README.md index fb987247a..bbe24ed65 100644 --- a/lib/README.md +++ b/lib/README.md @@ -44,15 +44,15 @@ Example filetree ```sh . ├── default.nix -├── feature_foo +├── build-clan │ ├── impl.nix │ └── test.nix -└── feature_bar +└── inventory ├── impl.nix - ├── complex-subfeature + ├── services-subfeature │ ├── impl.nix │ └── test.nix - ├── testless-subfeature # <- We immediately see that this feature is not tested on itself. + ├── instances-subfeature # <- We immediately see that this feature is not tested on itself. │ └── impl.nix └── test.nix ``` diff --git a/lib/build-clan/computed-tags.nix b/lib/build-clan/computed-tags.nix index f3ec6a36d..920e984c4 100644 --- a/lib/build-clan/computed-tags.nix +++ b/lib/build-clan/computed-tags.nix @@ -23,7 +23,7 @@ { name, ... }: { tags = builtins.attrNames ( - lib.filterAttrs (_t: tagMemers: builtins.elem name tagMemers) config.inventory.tags + lib.filterAttrs (_t: tagMembers: builtins.elem name tagMembers) config.inventory.tags ); } ) diff --git a/lib/build-clan/default.nix b/lib/build-clan/default.nix index f412bd038..35a0d7753 100644 --- a/lib/build-clan/default.nix +++ b/lib/build-clan/default.nix @@ -4,26 +4,37 @@ { lib, nixpkgs, - clan-core, }: -let - clanResultAttributes = [ - "clanInternals" - "nixosConfigurations" - ]; -in { - inherit clanResultAttributes; flakePartsModule = { imports = [ ./interface.nix ./module.nix ]; }; + /** - Function that returns the same result as the correlated flake-parts module + A function that takes some arguments such as 'clan-core' and returns the 'buildClan' function. + + # Arguments of the first function + - clan-core: Self, provided by our flake-parts module + - publicAttrs: { clan :: List Str, topLevel :: List Str } Publicly exported attribute names + + # Arguments of the second function (aka 'buildClan') + - self: Reference to the users flake + - inventory: An "Inventory" attribute set, see the docs, for how to construct one + - specialArgs: Extra arguments to pass to nixosSystem i.e. useful to make self available + - ...: Any other argument of the 'clan' submodule. See the docs for all available options + + # Returns + + Public attributes of buildClan. As specified in publicAttrs. */ - buildClan = + buildClanWith = + { + clan-core, + publicAttrs ? import ./public.nix, + }: { ## Inputs self ? lib.warn "Argument: 'self' must be set when using 'buildClan'." null, # Reference to the current flake @@ -33,7 +44,7 @@ in # deadnix: skip inventory ? { }, ## Special inputs (not passed to the module system as config) - specialArgs ? { }, # Extra arguments to pass to nixosSystem i.e. useful to make self available # A set containing clan meta: name :: string, icon :: string, description :: string + specialArgs ? { }, # Extra arguments to pass to nixosSystem i.e. useful to make self available ## ... }@attrs: @@ -48,12 +59,20 @@ in inherit specialArgs; }; rest = builtins.removeAttrs attrs [ "specialArgs" ]; + result = eval { + imports = [ + rest + # implementation + ./module.nix + ]; + }; in - eval { - imports = [ - rest - # implementation - ./module.nix - ]; - }; + { + clan = lib.genAttrs publicAttrs.clan ( + name: + result.clanInternals.${name} + or (throw "Output: clanInternals.${name} not found. Check: ${result.file}") + ); + } + // lib.filterAttrs (name: _v: builtins.elem name publicAttrs.topLevel) result; } diff --git a/lib/build-clan/module.nix b/lib/build-clan/module.nix index 29eafe838..9311c53c4 100644 --- a/lib/build-clan/module.nix +++ b/lib/build-clan/module.nix @@ -208,7 +208,7 @@ in # TODO: unify this interface # We should have only clan.modules. (consistent with clan.templates) inherit (clan-core) clanModules clanLib; - modules = clan-core.modules; + modules = clan-core.clanModules; inherit inventoryFile; inventoryValuesPrios = diff --git a/lib/build-clan/public.nix b/lib/build-clan/public.nix new file mode 100644 index 000000000..493ac1cc0 --- /dev/null +++ b/lib/build-clan/public.nix @@ -0,0 +1,17 @@ +/** + Publicly exported attribute names + These are mapped from 'options.clan.{name}' into 'flake.{name}' + For example "clanInternals" will be exposed as "flake.clan.clanInternals" + This list is used to guarantee equivalent attribute sets for both flake-parts and buildClan users. +*/ +{ + # flake.clan.{name} <- clanInternals.{name} + clan = [ + "templates" + ]; + # flake.{name} <- clan.{name} + topLevel = [ + "clanInternals" + "nixosConfigurations" + ]; +} diff --git a/lib/default.nix b/lib/default.nix index 1190541bd..53fd23021 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -23,9 +23,8 @@ lib.fix (clanLib: { buildClanModule = import ./build-clan { inherit lib nixpkgs; - clan-core = self; }; - buildClan = clanLib.buildClanModule.buildClan; + buildClan = clanLib.buildClanModule.buildClanWith { clan-core = self; }; # ------------------------------------ # Lib functions that don't depend on 'self' inventory = clanLib.callLib ./inventory { }; diff --git a/nixosModules/clanCore/vars/flake-module.nix b/nixosModules/clanCore/vars/flake-module.nix index 32093e7f6..9473e4161 100644 --- a/nixosModules/clanCore/vars/flake-module.nix +++ b/nixosModules/clanCore/vars/flake-module.nix @@ -29,6 +29,7 @@ in include = [ "flakeModules" "nixosModules" + "lib" ]; } }#legacyPackages.${system}.evalTests-module-clan-vars