diff --git a/lib/mkFlake/evalArgs.nix b/lib/mkFlake/evalArgs.nix index cb90f614..5884dcfb 100644 --- a/lib/mkFlake/evalArgs.nix +++ b/lib/mkFlake/evalArgs.nix @@ -1,11 +1,12 @@ { lib }: -{ nixos, args }: +{ args }: let argOpts = with lib; { config, ... }: let inherit (lib) os; + cfg = config; inherit (config) self; maybeImport = obj: @@ -33,23 +34,19 @@ let # To simplify apply keys and improve type checking pathTo = elemType: with types; coercedTo path maybeImport elemType; - # Accepts single item or a list - # apply keys end up with a list - # This should not be used if expecting a nested list - # all lists will get flattened by this - coercedListOf = elemType: - let coerceToList = x: flatten (singleton x); in - with types; coercedTo elemType coerceToList (listOf elemType); + pathToListOf = elemType: with types; pathTo (listOf elemType); - pathToListOf = x: pathTo (coercedListOf x); + coercedListOf = elemType: with types; + coercedTo elemType (x: flatten (singleton x)) (listOf elemType); /* Submodules needed for API containers */ - channelsModule = { + channelsModule = { name, ... }: { options = with types; { input = mkOption { type = flakeType; - default = nixos; + default = cfg.inputs.${name}; + defaultText = escape [ "<" ">" ] "inputs."; description = '' nixpkgs flake input to use for this channel ''; @@ -57,22 +54,15 @@ let overlays = mkOption { type = pathToListOf overlayType; default = [ ]; - description = '' + description = escape [ "<" ">" ] '' overlays to apply to this channel these will get exported under the 'overlays' flake output as / ''; }; - externalOverlays = mkOption { - type = pathToListOf overlayType; - default = [ ]; - description = '' - overlays to apply to the channel that don't get exported to the flake output - useful to include overlays from inputs - ''; - }; config = mkOption { type = pathTo attrs; default = { }; + apply = lib.recursiveUpdate cfg.channelsConfig; description = '' nixpkgs config for this channel ''; @@ -82,21 +72,21 @@ let hostModule = { options = with types; { + # anything null in hosts gets filtered out by mkFlake system = mkOption { - type = systemType; - default = "x86_64-linux"; + type = nullOr systemType; + default = null; description = '' system for this host ''; }; channelName = mkOption { - type = types.enum (builtins.attrValues config.channels); - default = "nixpkgs"; + type = nullOr (types.enum (builtins.attrNames config.channels)); + default = null; description = '' Channel this host should follow ''; }; - }; }; @@ -105,7 +95,7 @@ let externalModulesModule = { options = { externalModules = mkOption { - type = pathToListOf moduleType; + type = with types; listOf moduleType; default = [ ]; description = '' The configuration for this host @@ -117,7 +107,7 @@ let modulesModule = { options = { modules = mkOption { - type = pathToListOf moduleType; + type = with types; coercedListOf moduleType; default = [ ]; description = '' modules to include @@ -126,13 +116,34 @@ let }; }; + exportModulesModule = name: { + options = { + modules = mkOption { + type = with types; pathToListOf + # check if the path evaluates to a proper module + # but this must be a path for the export to work + (addCheck path (x: moduleType.check (import x))); + default = [ ]; + description = '' + modules to include in all hosts and export to ${name}Modules output + ''; + }; + }; + }; + + + # Home-manager's configs get exported automatically from nixos.hosts # So there is no need for a host options in the home namespace # This is only needed for nixos - includeHostsModule = { name, ... }: { + includeHostsModule = name: { options = with types; { hostDefaults = mkOption { - type = submodule [ hostModule externalModulesModule modulesModule ]; + type = submodule [ + hostModule + externalModulesModule + (exportModulesModule name) + ]; default = { }; description = '' Defaults for all hosts. @@ -152,15 +163,11 @@ let }; # profiles and suites - which are profile collections - profilesModule = { name, ... }: { + profilesModule = { config, ... }: { options = with types; { profiles = mkOption { - type = coercedListOf path; + type = listOf path; default = [ ]; - apply = list: - # Merge a list of profiles to one set - let profileList = map (x: os.mkProfileAttrs (toString x)) list; in - foldl (a: b: a // b) { } profileList; description = "path to profiles folder that can be collected into suites"; }; suites = mkOption { @@ -185,6 +192,13 @@ let type = flakeType; description = "The flake to create the devos outputs for"; }; + inputs = mkOption { + type = attrsOf flakeType; + description = '' + inputs for this flake + used to set channel defaults and create registry + ''; + }; supportedSystems = mkOption { type = listOf str; default = lib.defaultSystems; @@ -192,31 +206,33 @@ let The systems supported by this flake ''; }; - channels = - let - default = { - nixpkgs = { - input = nixos; - }; - }; - in - mkOption { - type = attrsOf (submodule channelsModule); - inherit default; - apply = x: default // x; - description = '' - nixpkgs channels to create - ''; - }; - os = mkOption { - type = submodule [ includeHostsModule profilesModule ]; + channelsConfig = mkOption { + type = pathTo attrs; + default = { }; + description = '' + nixpkgs config for all channels + ''; + }; + channels = mkOption { + type = attrsOf (submodule channelsModule); + default = { }; + description = '' + nixpkgs channels to create + ''; + }; + nixos = mkOption { + type = submodule [ (includeHostsModule "nixos") profilesModule ]; default = { }; description = '' hosts, modules, suites, and profiles for nixos ''; }; home = mkOption { - type = submodule [ profilesModule modulesModule ]; + type = submodule [ + profilesModule + (exportModulesModule "home") + externalModulesModule + ]; default = { }; description = '' hosts, modules, suites, and profiles for home-manager