From 5113479d69e6881ae142bf05084d05adddc27111 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Wed, 21 May 2025 09:58:22 +0100 Subject: [PATCH] stylix: improve how discord testbed is disabled (#1291) Link: https://github.com/nix-community/stylix/pull/1291 Reviewed-by: awwpotato Reviewed-by: Flameopathic <64027365+Flameopathic@users.noreply.github.com> Reviewed-by: NAHO <90870942+trueNAHO@users.noreply.github.com> --- flake/packages.nix | 50 ++++++------------ modules/discord/testbeds/vencord.nix | 11 ++-- stylix/testbed.nix | 79 +++++++++++++++++++++++----- 3 files changed, 91 insertions(+), 49 deletions(-) diff --git a/flake/packages.nix b/flake/packages.nix index 75a040b8..2c2afe87 100644 --- a/flake/packages.nix +++ b/flake/packages.nix @@ -7,46 +7,28 @@ { perSystem = - { - pkgs, - system, - config, - ... - }: + { pkgs, config, ... }: { # Build all packages with 'nix flake check' instead of only verifying they # are derivations. checks = config.packages; - packages = - let - testbedPackages = import "${self}/stylix/testbed.nix" { + packages = lib.mkMerge [ + # Testbeds are virtual machines based on NixOS, therefore they are + # only available for Linux systems. + (lib.mkIf pkgs.stdenv.hostPlatform.isLinux ( + import "${self}/stylix/testbed.nix" { inherit pkgs inputs lib; - }; - - # Discord is not available on arm64. This workaround filters out - # testbeds using that package, until we have a better way to handle - # this. - testbedPackages' = - if system == "aarch64-linux" then - lib.filterAttrs ( - name: _: !lib.hasPrefix "testbed:discord:vencord" name - ) testbedPackages - else - testbedPackages; - in - lib.mkMerge [ - # Testbeds are virtual machines based on NixOS, therefore they are - # only available for Linux systems. - (lib.mkIf pkgs.stdenv.hostPlatform.isLinux testbedPackages') - { - docs = pkgs.callPackage "${self}/doc" { - inherit inputs; - inherit (inputs.nixpkgs.lib) nixosSystem; - inherit (inputs.home-manager.lib) homeManagerConfiguration; - }; - palette-generator = pkgs.callPackage "${self}/palette-generator" { }; } - ]; + )) + { + docs = pkgs.callPackage "${self}/doc" { + inherit inputs; + inherit (inputs.nixpkgs.lib) nixosSystem; + inherit (inputs.home-manager.lib) homeManagerConfiguration; + }; + palette-generator = pkgs.callPackage "${self}/palette-generator" { }; + } + ]; }; } diff --git a/modules/discord/testbeds/vencord.nix b/modules/discord/testbeds/vencord.nix index f090acfd..41168160 100644 --- a/modules/discord/testbeds/vencord.nix +++ b/modules/discord/testbeds/vencord.nix @@ -6,9 +6,14 @@ let }; in { - stylix.testbed.ui.application = { - name = "discord"; - inherit package; + stylix.testbed = { + # Discord is not available on arm64. + enable = lib.meta.availableOn pkgs.stdenv.hostPlatform package; + + ui.application = { + name = "discord"; + inherit package; + }; }; environment.systemPackages = [ package ]; diff --git a/stylix/testbed.nix b/stylix/testbed.nix index 6e5a4f26..5b2e84aa 100644 --- a/stylix/testbed.nix +++ b/stylix/testbed.nix @@ -37,6 +37,36 @@ let }; }; + enableModule = + { lib, config, ... }: + { + options.stylix.testbed.enable = lib.mkOption { + type = lib.types.bool; + default = true; + example = lib.literalExpression "lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.discord"; + description = '' + Whether to enable this testbed. + + The testbed will not be included as a flake output if set to false. + + > [!CAUTION] + > + > This option can only access `lib` and `pkgs` inputs. Attempting to + > read other inputs, like `config` or `options`, will cause the + > testbed evaluation to fail. + > + > This is a performance-driven restriction, as noted in `isEnabled`. + ''; + }; + + config.assertions = [ + { + assertion = config.stylix.testbed.enable; + message = "Building a disabled testbed. This testbed should have been filtered out!"; + } + ]; + }; + applicationModule = { config, lib, ... }: { @@ -153,16 +183,41 @@ let }; }; + # Creates a minimal configuration to extract the `stylix.testbed.enable` + # option value. + # + # This is for performance reasons. Primarily, to avoid fully evaluating + # testbed system configurations to determine flake outputs. + # E.g., when running `nix flake show`. + isEnabled = + module: + let + minimal = lib.evalModules { + modules = [ + module + enableModule + { _module.check = false; } + { _module.args = { inherit pkgs; }; } + ]; + }; + in + minimal.config.stylix.testbed.enable; + autoload = let directory = "testbeds"; modules = "${inputs.self}/modules"; in - lib.flatten ( - lib.mapAttrsToList ( - module: _: + lib.pipe modules [ + builtins.readDir + builtins.attrNames + (builtins.concatMap ( + module: let testbeds = "${modules}/${module}/${directory}"; + files = lib.optionalAttrs (builtins.pathExists testbeds) ( + builtins.readDir testbeds + ); in lib.mapAttrsToList ( testbed: type: @@ -182,15 +237,15 @@ let name = lib.removeSuffix ".nix" testbed; path = "${testbeds}/${testbed}"; } - ) (lib.optionalAttrs (builtins.pathExists testbeds) (builtins.readDir testbeds)) - ) (builtins.readDir modules) - ); + ) files + )) + ]; makeTestbed = testbed: stylix: let - name = builtins.concatStringsSep testbedFieldSeparator ( - map + name = + lib.concatMapStringsSep testbedFieldSeparator ( field: lib.throwIf (lib.hasInfix testbedFieldSeparator field) @@ -205,14 +260,14 @@ let "image${lib.optionalString (stylix.image or null == null) "less"}" "scheme${lib.optionalString (stylix.base16Scheme or null == null) "less"}" "cursor${lib.optionalString (stylix.cursor or null == null) "less"}" - ] - ); + ]; system = lib.nixosSystem { inherit (pkgs) system; modules = [ commonModule + enableModule applicationModule inputs.self.nixosModules.stylix inputs.home-manager.nixosModules.home-manager @@ -244,7 +299,7 @@ let ''; }; in - { + lib.optionalAttrs (isEnabled testbed.path) { ${name} = script; }; @@ -306,5 +361,5 @@ in # Testbeds are merged using lib.attrsets.unionOfDisjoint to throw an error if # testbed names collide. builtins.foldl' lib.attrsets.unionOfDisjoint { } ( - lib.flatten (map makeTestbeds autoload) + builtins.concatMap makeTestbeds autoload )