diff --git a/flake.nix b/flake.nix index 2af7520..71d449b 100644 --- a/flake.nix +++ b/flake.nix @@ -28,79 +28,26 @@ pkgs.inputs.nixpkgs.follows = "nixos"; }; - outputs = inputs@{ deploy, nixos, nur, self, utils, ... }: - let - inherit (self) lib; - inherit (lib) os; - - extern = import ./extern { inherit inputs; }; - overrides = import ./overrides; - - multiPkgs = os.mkPkgs { - inherit extern overrides; - }; - - suites = os.mkSuites { - suites = import ./suites; - users = os.mkProfileAttrs "${self}/users"; - profiles = os.mkProfileAttrs "${self}/profiles"; - userProfiles = os.mkProfileAttrs "${self}/users/profiles"; - }; - - outputs = { - nixosConfigurations = os.mkHosts { - dir = "${self}/hosts"; + outputs = inputs@{ deploy, nixos, nur, self, utils, ... }: + let + lib = import ./lib { inherit self nixos inputs; }; + in + lib.mkFlake { + inherit self; + hosts = ./hosts; + packages = import ./pkgs; + suites = import ./suites; + extern = import ./extern; overrides = import ./overrides; - inherit multiPkgs suites extern; + overlays = ./overlays; + profiles = ./profiles; + userProfiles = ./users/profiles; + modules = import ./modules/module-list.nix; + userModules = import ./users/modules/module-list.nix; + } // { + inherit lib; + defaultTemplate = self.templates.flk; + templates.flk.path = ./.; + templates.flk.description = "flk template"; }; - - homeConfigurations = os.mkHomeConfigurations; - - nixosModules = - let moduleList = import ./modules/module-list.nix; - in lib.pathsToImportedAttrs moduleList; - - homeModules = - let moduleList = import ./users/modules/module-list.nix; - in lib.pathsToImportedAttrs moduleList; - - overlay = import ./pkgs; - overlays = lib.pathsToImportedAttrs (lib.pathsIn ./overlays); - - lib = import ./lib { inherit nixos self inputs; }; - - templates.flk.path = ./.; - templates.flk.description = "flk template"; - defaultTemplate = self.templates.flk; - - deploy.nodes = os.mkNodes deploy self.nixosConfigurations; - }; - - systemOutputs = utils.lib.eachDefaultSystem (system: - let - pkgs = multiPkgs.${system}; - # all packages that are defined in ./pkgs - legacyPackages = os.mkPackages { inherit pkgs; }; - in - { - checks = - let - tests = nixos.lib.optionalAttrs (system == "x86_64-linux") - (import ./tests { inherit self pkgs; }); - deployHosts = nixos.lib.filterAttrs - (n: _: self.nixosConfigurations.${n}.config.nixpkgs.system == system) self.deploy.nodes; - deployChecks = deploy.lib.${system}.deployChecks { nodes = deployHosts; }; - in - nixos.lib.recursiveUpdate tests deployChecks; - - inherit legacyPackages; - packages = lib.filterPackages system legacyPackages; - - devShell = import ./shell { - inherit self system extern overrides; - }; - } - ); - in - nixos.lib.recursiveUpdate outputs systemOutputs; } diff --git a/lib/default.nix b/lib/default.nix index 8ed28a4..61fe6dd 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -17,6 +17,8 @@ lib.makeExtensible (final: lists = callLibs ./lists.nix; strings = callLibs ./strings.nix; + mkFlake = callLibs ./mkFlake; + inherit (attrs) mapFilterAttrs genAttrs' safeReadDir pathsToImportedAttrs concatAttrs filterPackages; inherit (lists) pathsIn; diff --git a/lib/lists.nix b/lib/lists.nix index b6530f1..c5823d3 100644 --- a/lib/lists.nix +++ b/lib/lists.nix @@ -2,7 +2,7 @@ { pathsIn = dir: let - fullPath = name: "${toString dir}/${name}"; + fullPath = name: "${dir}/${name}"; in map fullPath (lib.attrNames (dev.safeReadDir dir)); } diff --git a/lib/mkFlake/default.nix b/lib/mkFlake/default.nix new file mode 100644 index 0000000..4ff3cd4 --- /dev/null +++ b/lib/mkFlake/default.nix @@ -0,0 +1,60 @@ +{ dev, nixos, inputs, ... }: +let + inherit (dev) os; + inherit (inputs) utils deploy; + evalFlakeArgs = dev.callLibs ./evalArgs.nix; +in + +{ self, ... } @ args: +let + + cfg = (evalFlakeArgs { inherit args; }).config; + + multiPkgs = os.mkPkgs { inherit (cfg) extern overrides; }; + + outputs = { + nixosConfigurations = os.mkHosts { + inherit self multiPkgs; + inherit (cfg) extern suites overrides; + dir = cfg.hosts; + }; + + homeConfigurations = os.mkHomeConfigurations; + + nixosModules = cfg.modules; + + homeModules = cfg.userModules; + + overlay = cfg.packages; + inherit (cfg) overlays; + + deploy.nodes = os.mkNodes deploy self.nixosConfigurations; + }; + + systemOutputs = utils.lib.eachDefaultSystem (system: + let + pkgs = multiPkgs.${system}; + # all packages that are defined in ./pkgs + legacyPackages = os.mkPackages { inherit pkgs; }; + in + { + checks = + let + tests = nixos.lib.optionalAttrs (system == "x86_64-linux") + (import "${self}/tests" { inherit self pkgs; }); + deployHosts = nixos.lib.filterAttrs + (n: _: self.nixosConfigurations.${n}.config.nixpkgs.system == system) self.deploy.nodes; + deployChecks = deploy.lib.${system}.deployChecks { nodes = deployHosts; }; + in + nixos.lib.recursiveUpdate tests deployChecks; + + inherit legacyPackages; + packages = dev.filterPackages system legacyPackages; + + devShell = import "${self}/shell" { + inherit self system; + }; + }); +in + outputs // systemOutputs + diff --git a/lib/mkFlake/evalArgs.nix b/lib/mkFlake/evalArgs.nix new file mode 100644 index 0000000..5e9bb40 --- /dev/null +++ b/lib/mkFlake/evalArgs.nix @@ -0,0 +1,151 @@ +{ self, dev, nixos, inputs, ... }: + +{ args }: +let + argOpts = with nixos.lib; { config, options, ... }: + let + inherit (dev) os; + + inherit (config) self; + + inputAttrs = with types; functionTo attrs; + moduleType = with types; anything // { + inherit (submodule {}) check; + description = "valid module"; + }; + in + { + options = with types; { + self = mkOption { + type = addCheck attrs nixos.lib.isStorePath; + description = "The flake to create the devos outputs for"; + }; + hosts = mkOption { + type = path; + default = "${self}/hosts"; + defaultText = "\${self}/hosts"; + apply = toString; + description = '' + Path to directory containing host configurations that will be exported + to the 'nixosConfigurations' output. + ''; + }; + packages = mkOption { + # functionTo changes arg names which breaks flake check + type = types.anything // { + check = builtins.isFunction; + description = "Nixpkgs overlay"; + }; + default = (final: prev: {}); + defaultText = "(final: prev: {})"; + description = '' + Overlay for custom packages that will be included in treewide 'pkgs'. + This should follow the standard nixpkgs overlay format - two argument function + that returns an attrset. + These packages will be exported to the 'packages' and 'legacyPackages' outputs. + ''; + }; + modules = mkOption { + type = listOf moduleType; + default = []; + apply = dev.pathsToImportedAttrs; + description = '' + list of modules to include in confgurations and export in 'nixosModules' output + ''; + }; + userModules = mkOption { + type = listOf moduleType; + default = []; + apply = dev.pathsToImportedAttrs; + description = '' + list of modules to include in home-manager configurations and export in + 'homeModules' output + ''; + }; + profiles = mkOption { + type = path; + default = "${self}/profiles"; + defaultText = "\${self}/profiles"; + apply = x: os.mkProfileAttrs (x); + description = "path to profiles folder that can be collected into suites"; + }; + userProfiles = mkOption { + type = path; + default = "${self}/users/profiles"; + defaultText = "\${self}/users/profiles"; + apply = x: os.mkProfileAttrs (toString x); + description = "path to user profiles folder that can be collected into userSuites"; + }; + suites = + let + defaults = { user = {}; system = {}; }; + in + mkOption { + type = inputAttrs; + default = { ... }: defaults; + defaultText = "{ user = {}; system = {}; }"; + apply = suites: defaults // os.mkSuites { + inherit suites; + inherit (config) profiles users userProfiles; + }; + description = '' + Function with inputs 'users' and 'profiles' that returns attribute set + with user and system suites. The former for Home Manager and the latter + for nixos configurations. + These can be accessed through the 'suites' specialArg in each config system. + ''; + }; + users = mkOption { + type = path; + default = "${self}/users"; + defaultText = "\${self}/users"; + apply = x: os.mkProfileAttrs (toString x); + description = '' + path to folder containing profiles that define system users + ''; + }; + extern = + let + defaults = { + modules = []; overlays = []; specialArgs = {}; + userModules = []; userSpecialArgs = []; + }; + in + mkOption { + type = inputAttrs; + default = { ... }: defaults; + defaultText = '' + { modules = []; overlays = []; specialArgs = []; userModules = []; userSpecialArgs = []; } + ''; + # So unneeded extern attributes can safely be deleted + apply = x: defaults // (x { inputs = inputs // self.inputs; }); + description = '' + Function with argument 'inputs' that contains all devos and ''${self}'s inputs. + The function should return an attribute set with modules, overlays, and + specialArgs to be included across nixos and home manager configurations. + Only attributes that are used should be returned. + ''; + }; + overlays = mkOption { + type = path; + default = "${self}/overlays"; + defaultText = "\${self}/overlays"; + apply = x: dev.pathsToImportedAttrs (dev.pathsIn (toString x)); + description = '' + path to folder containing overlays which will be applied to pkgs and exported in + the 'overlays' output + ''; + }; + overrides = mkOption rec { + type = attrs; + default = { modules = []; disabledModules = []; packages = _: _: _: {}; }; + defaultText = "{ modules = []; disabledModules = []; packages = {}; }"; + apply = x: default // x; + description = "attrset of packages and modules that will be pulled from nixpkgs master"; + }; + }; + }; +in + nixos.lib.evalModules { + modules = [ argOpts args ]; + }