tests/package-options: init

The test ensures "package" options use a "literalExpression" in their
defaultText; i.e. it validates `lib.mkPackageOption` was used to build
the package options.

All options whose `default` is a derivation are covered by the test,
other than submodule sub-options.
This commit is contained in:
Matt Sturgeon 2024-09-03 01:54:18 +01:00
parent fd923a3dd3
commit e48da949cf
No known key found for this signature in database
GPG key ID: 4F91844CED1A8299
2 changed files with 95 additions and 0 deletions

View file

@ -9,6 +9,9 @@
makeNixvimWithModule, makeNixvimWithModule,
... ...
}: }:
let
evaluatedNixvim = helpers.modules.evalNixvim { check = false; };
in
{ {
checks = { checks = {
extra-args-tests = import ../tests/extra-args.nix { extra-args-tests = import ../tests/extra-args.nix {
@ -43,6 +46,8 @@
maintainers = import ../tests/maintainers.nix { inherit pkgs; }; maintainers = import ../tests/maintainers.nix { inherit pkgs; };
generated = pkgs.callPackage ../tests/generated.nix { }; generated = pkgs.callPackage ../tests/generated.nix { };
package-options = pkgs.callPackage ../tests/package-options.nix { inherit evaluatedNixvim; };
} // import ../tests { inherit pkgs pkgsUnfree helpers; }; } // import ../tests { inherit pkgs pkgsUnfree helpers; };
}; };
} }

90
tests/package-options.nix Normal file
View file

@ -0,0 +1,90 @@
# This test ensures "package" options use a "literalExpression" in their defaultText
# I.e. it validates `lib.mkPackageOption` was used to build the package options.
{
evaluatedNixvim,
lib,
runCommandNoCCLocal,
}:
let
inherit (builtins)
filter
head
map
match
;
inherit (lib.strings) concatMapStringsSep removePrefix removeSuffix;
inherit (lib.attrsets) isDerivation;
inherit (lib.options)
isOption
renderOptionValue
showOption
;
# This doesn't collect any submodule sub-options,
# but that's fine since most of our "package" options are in the top level module eval
options = lib.collect isOption evaluatedNixvim.options;
# All visible non-sub options that default to a derivation
drvOptions = filter (
{
default ? null,
visible ? true,
internal ? false,
...
}:
visible && !internal && isDerivation default
) options;
# Bad options do not use `literalExpression` in their `defaultText`,
# or have a `defaultText` that doesn't start with "pkgs."
badOptions = filter (
opt:
opt.defaultText._type or null != "literalExpression"
|| match ''pkgs[.].*'' (opt.defaultText.text or "") == null
) drvOptions;
in
runCommandNoCCLocal "validate-package-options"
{
# Use structuredAttrs to avoid "Argument List Too Long" errors
# and get proper bash array support.
__structuredAttrs = true;
# Passthroughs for debugging purposes
passthru = {
inherit evaluatedNixvim drvOptions badOptions;
};
# Error strings to print
errors =
let
# A little hack to get the flake's source in the nix store
# We will use this to make the option declaration sources more readable
src = removeSuffix "modules/top-level/output.nix" (
head evaluatedNixvim.options.package.declarations
);
in
map (
opt:
let
# The default, as rendered in documentation. Will always be a literalExpression.
default = builtins.addErrorContext "while evaluating the default text for `${showOption opt.loc}`" (
renderOptionValue (opt.defaultText or opt.default)
);
in
''
- ${showOption opt.loc} (${default.text}), declared in:
${concatMapStringsSep "\n" (file: " - ${removePrefix src file}") opt.declarations}
''
) badOptions;
}
''
if [ -n "$errors" ]; then
echo "Found ''${#errors[@]} errors:"
for err in "''${errors[@]}"; do
echo "$err"
done
echo "(''${#errors[@]} options with errors)"
exit 1
fi
touch $out
''