diff --git a/modules/misc/specialization.nix b/modules/misc/specialization.nix new file mode 100644 index 00000000..67e593e2 --- /dev/null +++ b/modules/misc/specialization.nix @@ -0,0 +1,71 @@ +{ config, extendModules, lib, ... }: + +with lib; + +{ + options.specialization = mkOption { + type = types.attrsOf (types.submodule { + options = { + configuration = mkOption { + type = let + stopRecursion = { specialization = mkOverride 0 { }; }; + extended = extendModules { modules = [ stopRecursion ]; }; + in extended.type; + default = { }; + visible = "shallow"; + description = '' + Arbitrary Home Manager configuration settings. + ''; + }; + }; + }); + default = { }; + description = '' + A set of named specialized configurations. These can be used to extend + your base configuration with additional settings. For example, you can + have specializations named light and dark + that applies light and dark color theme configurations. + + + + Note, this is an experimental option for now and you therefore have to + activate the specialization by looking up and running the activation + script yourself. Note, running the activation script will create a new + Home Manager generation. + + + + For example, to activate the dark specialization. You can + first look up your current Home Manager generation by running + + + $ home-manager generations | head -1 + 2022-05-02 22:49 : id 1758 -> /nix/store/jy…ac-home-manager-generation + + + then run + + + $ /nix/store/jy…ac-home-manager-generation/specialization/dark/activate + Starting Home Manager activation + … + + + + + WARNING! Since this option is experimental, the activation process may + change in backwards incompatible ways. + ''; + }; + + config = mkIf (config.specialization != { }) { + home.extraBuilderCommands = let + link = n: v: + let pkg = v.configuration.home.activationPackage; + in "ln -s ${pkg} $out/specialization/${n}"; + in '' + mkdir $out/specialization + ${concatStringsSep "\n" (mapAttrsToList link config.specialization)} + ''; + }; +} diff --git a/modules/modules.nix b/modules/modules.nix index 91e1654d..51db04be 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -30,6 +30,7 @@ let ./misc/numlock.nix ./misc/pam.nix ./misc/qt.nix + ./misc/specialization.nix ./misc/submodule-support.nix ./misc/tmpfiles.nix ./misc/version.nix diff --git a/tests/default.nix b/tests/default.nix index 03a86aec..d89ebfbd 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -46,6 +46,7 @@ import nmt { ./modules/home-environment ./modules/misc/fontconfig ./modules/misc/nix + ./modules/misc/specialization ./modules/programs/alacritty ./modules/programs/alot ./modules/programs/aria2 diff --git a/tests/modules/misc/specialization/default.nix b/tests/modules/misc/specialization/default.nix new file mode 100644 index 00000000..ddbc22c6 --- /dev/null +++ b/tests/modules/misc/specialization/default.nix @@ -0,0 +1 @@ +{ specialization = ./specialization.nix; } diff --git a/tests/modules/misc/specialization/specialization.nix b/tests/modules/misc/specialization/specialization.nix new file mode 100644 index 00000000..9d6149a0 --- /dev/null +++ b/tests/modules/misc/specialization/specialization.nix @@ -0,0 +1,18 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + home.file.testfile.text = "not special"; + specialization.test.configuration = { + home.file.testfile.text = "very special"; + }; + + nmt.script = '' + assertFileExists home-files/testfile + assertFileContains home-files/testfile "not special" + + assertFileExists specialization/test/home-files/testfile + assertFileContains specialization/test/home-files/testfile "not special" + ''; +}