diff --git a/modules/flake-parts/default.nix b/modules/flake-parts/default.nix index 2d6467da..0f0f450a 100644 --- a/modules/flake-parts/default.nix +++ b/modules/flake-parts/default.nix @@ -13,6 +13,7 @@ ./home-modules.nix ./nixvim-modules.nix ./nixvim-configurations.nix + ./wrapper-manager-packages.nix ./setups ]; } diff --git a/modules/flake-parts/setups/default.nix b/modules/flake-parts/setups/default.nix index 48a4e7db..27c3a147 100644 --- a/modules/flake-parts/setups/default.nix +++ b/modules/flake-parts/setups/default.nix @@ -11,6 +11,7 @@ ./nixos.nix ./nixvim.nix ./home-manager.nix + ./wrapper-manager.nix ]; options.setups.sharedNixpkgsConfig = lib.mkOption { diff --git a/modules/flake-parts/setups/nixos.nix b/modules/flake-parts/setups/nixos.nix index 8fe80657..cb57b278 100644 --- a/modules/flake-parts/setups/nixos.nix +++ b/modules/flake-parts/setups/nixos.nix @@ -409,6 +409,7 @@ in configs = lib.mkOption { type = with lib.types; attrsOf (submoduleWith { specialArgs = { inherit (config) systems; }; + shorthandOnlyDefinesConfig = true; modules = [ (import ./shared/nix-conf.nix { inherit inputs; }) ./shared/config-options.nix diff --git a/modules/flake-parts/setups/wrapper-manager.nix b/modules/flake-parts/setups/wrapper-manager.nix new file mode 100644 index 00000000..d06d050a --- /dev/null +++ b/modules/flake-parts/setups/wrapper-manager.nix @@ -0,0 +1,202 @@ +{ lib, config, options, inputs, ... }: + +let + partsConfig = config; + cfg = config.setups.wrapper-manager; + + mkWrapperManagerPackage = { + pkgs, + src, + modules, + specialArgs, + }: + let + wrapperManagerEntrypoint = import src { }; + in + wrapperManagerEntrypoint.lib.build { + inherit pkgs modules specialArgs; + }; + + wrapperManagerIntegrationModule = { name, config, lib, ... }: { + options.wrapper-manager = { + src = lib.mkOption { + type = lib.types.path; + default = ../../../subprojects/wrapper-manager-fds; + description = '' + The path of the wrapper-manager-fds to be used to properly initialize + to the environment. + ''; + }; + + additionalModules = lib.mkOption { + type = with lib.types; listOf deferredModule; + default = [ ]; + description = '' + Additional wrapper-manager modules to be included in the wider-scoped + environment. + ''; + }; + + packages = lib.mkOption { + type = with lib.types; attrsOf (submodule { + options.additionalModules = lib.mkOption { + type = with lib.types; listOf deferredModule; + description = '' + Additional wrapper-manager modules to be included into the given + declarative wrapper-manager configuration. + ''; + default = [ ]; + }; + }); + default = { }; + description = '' + Include declared wrapper-manager packages into the wider environment. + ''; + }; + }; + + config = lib.mkIf (config.wrapper-manager.packages != { }) { + modules = [ + ({ lib, ... }: { + wrapper-manager.sharedModules = + cfg.sharedModules ++ config.wrapper-manager.additionalModules; + + wrapper-manager.packages = + lib.mapAttrs (name: wmPackage: { + imports = + partsConfig.setups.wrapper-manager.configs.${name}.modules + ++ wmPackage.additionalModules; + }) config.wrapper-manager.packages; + }) + ]; + }; + }; + + wrapperManagerConfigModule = { name, config, lib, ... }: { + options.wrapper-manager.src = lib.mkOption { + type = lib.types.path; + default = ../../../subprojects/wrapper-manager-fds; + description = '' + The path containing wrapper-manager-fds source code to be used to + properly initialize and create the wrapper-manager environment. + ''; + }; + + config = { + nixpkgs.config = cfg.sharedNixpkgsConfig; + + modules = [ + ../../../configs/wrapper-manager/${config.configName} + ]; + }; + }; +in +{ + options.setups.wrapper-manager = { + sharedNixpkgsConfig = options.setups.sharedNixpkgsConfig // { + description = '' + The nixpkgs configuration to be passed to all of the declarative + wrapper-manager configurations. + ''; + }; + + configs = lib.mkOption { + type = with lib.types; attrsOf (submodule [ + ./shared/config-options.nix + ./shared/nixpkgs-options.nix + wrapperManagerConfigModule + ]); + default = { }; + description = '' + Declarative wrapper-manager packages to be exported into the flake. + ''; + example = lib.literalExpression '' + { + music-setup = { + modules = [ + { config.build.isBinary = false; } + ]; + }; + } + ''; + }; + + sharedModules = lib.mkOption { + type = with lib.types; listOf deferredModule; + default = [ ]; + description = '' + List of shared wrapper-manager modules in all of the declarative + wrapper-manager configurations. + ''; + }; + + standaloneModules = lib.mkOption { + type = with lib.types; listOf deferredModule; + default = [ ]; + description = '' + List of wrapper-manager modules only available at standalone mode. + ''; + }; + }; + + # Integrations with the composable environments such as NixOS and home-manager. + options.setups.nixos.configs = lib.mkOption { + type = with lib.types; attrsOf (submodule [ + wrapperManagerIntegrationModule + ({ config, lib, ... }: { + config = lib.mkIf (config.wrapper-manager.packages != { }) { + modules = [ + (import config.wrapper-manager.src { }).nixosModules.default + ]; + }; + }) + ]); + }; + + options.setups.home-manager.configs = lib.mkOption { + type = with lib.types; attrsOf (submodule [ + wrapperManagerIntegrationModule + ({ config, lib, ... }: { + config = lib.mkIf (config.wrapper-manager.packages != { }) { + modules = [ + (import config.wrapper-manager.src { }).homeModules.default + ]; + }; + }) + ]); + }; + + config = lib.mkIf (cfg.configs != { }) { + setups.wrapper-manager.sharedNixpkgsConfig = config.setups.sharedNixpkgsConfig; + + setups.wrapper-manager.sharedModules = [ + ../../wrapper-manager + ../../wrapper-manager/_private + ]; + + perSystem = { system, config, lib, ... }: let + validWrapperManagerConfigs = + lib.filterAttrs (_: metadata: lib.elem system metadata.systems) cfg.configs; + in { + wrapperManagerPackages = + lib.mapAttrs + (name: metadata: + let + pkgs = import inputs.${metadata.nixpkgs.branch} { + inherit (metadata.nixpkgs) config; + inherit system; + }; + in + mkWrapperManagerPackage { + inherit pkgs; + inherit (metadata) src; + modules = + cfg.sharedModules + ++ cfg.standaloneModules + ++ metadata.modules; + } + ) + validWrapperManagerConfigs; + }; + }; +} diff --git a/modules/flake-parts/wrapper-manager-packages.nix b/modules/flake-parts/wrapper-manager-packages.nix new file mode 100644 index 00000000..153fee2c --- /dev/null +++ b/modules/flake-parts/wrapper-manager-packages.nix @@ -0,0 +1,48 @@ +# A flake-parts module containing definition for my custom wrapper-manager +# packages which should have its own flake output attribute at +# `wrapperManagerPackages` containing the derivations that can be run or build. +{ config, lib, flake-parts-lib, ... }: + +let + inherit (flake-parts-lib) mkSubmoduleOptions mkPerSystemOption; +in +{ + options = { + flake = mkSubmoduleOptions { + wrapperManagerPackages = lib.mkOption { + type = with lib.types; lazyAttrsOf (attrsOf package); + default = { }; + description = '' + An attribute set of per-system wrapper-manager configurations. + ''; + }; + }; + + perSystem = mkPerSystemOption { + options = { + wrapperManagerPackages = lib.mkOption { + type = with lib.types; attrsOf package; + default = { }; + description = '' + An attribute set of wrapper-manager configurations. + ''; + }; + }; + }; + }; + + config = { + flake.wrapperManagerPackages = + lib.mapAttrs + (k: v: v.wrapperManagerPackages) + (lib.filterAttrs + (k: v: v.wrapperManagerPackages != { }) + config.allSystems + ); + + perInput = system: flake: + lib.optionalAttrs (flake ? wrapperManagerPackages.${system}) { + wrapperManagerPackages = flake.wrapperManagerPackages.${system}; + }; + }; +}