Skip to content

Commit e630e9d

Browse files
committed
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.
1 parent 46dacb5 commit e630e9d

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

flake-modules/tests.nix

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
makeNixvimWithModule,
1010
...
1111
}:
12+
let
13+
evaluatedNixvim = helpers.modules.evalNixvim { check = false; };
14+
in
1215
{
1316
checks = {
1417
extra-args-tests = import ../tests/extra-args.nix {
@@ -43,6 +46,8 @@
4346
maintainers = import ../tests/maintainers.nix { inherit pkgs; };
4447

4548
generated = pkgs.callPackage ../tests/generated.nix { };
49+
50+
package-options = pkgs.callPackage ../tests/package-options.nix { inherit evaluatedNixvim; };
4651
} // import ../tests { inherit pkgs pkgsUnfree helpers; };
4752
};
4853
}

tests/package-options.nix

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# This test ensures "package" options use a "literalExpression" in their defaultText
2+
# I.e. it validates `lib.mkPackageOption` was used to build the package options.
3+
{
4+
evaluatedNixvim,
5+
lib,
6+
runCommandNoCCLocal,
7+
}:
8+
let
9+
inherit (builtins)
10+
filter
11+
head
12+
map
13+
match
14+
;
15+
inherit (lib.strings) concatMapStringsSep removePrefix removeSuffix;
16+
inherit (lib.attrsets) isDerivation;
17+
inherit (lib.options)
18+
isOption
19+
renderOptionValue
20+
showOption
21+
;
22+
23+
# This doesn't collect any submodule sub-options,
24+
# but that's fine since most of our "package" options are in the top level module eval
25+
options = lib.collect isOption evaluatedNixvim.options;
26+
27+
# All visible non-sub options that default to a derivation
28+
drvOptions = filter (
29+
{
30+
default ? null,
31+
visible ? true,
32+
internal ? false,
33+
...
34+
}:
35+
visible && !internal && isDerivation default
36+
) options;
37+
38+
# Bad options do not use `literalExpression` in their `defaultText`,
39+
# or have a `defaultText` that doesn't start with "pkgs."
40+
badOptions = filter (
41+
opt:
42+
opt.defaultText._type or null != "literalExpression"
43+
|| match ''pkgs[.].*'' (opt.defaultText.text or "") == null
44+
) drvOptions;
45+
in
46+
runCommandNoCCLocal "validate-package-options"
47+
{
48+
# Use structuredAttrs to avoid "Argument List Too Long" errors
49+
# and get proper bash array support.
50+
__structuredAttrs = true;
51+
52+
# Passthroughs for debugging purposes
53+
passthru = {
54+
inherit evaluatedNixvim drvOptions badOptions;
55+
};
56+
57+
# Error strings to print
58+
errors =
59+
let
60+
# A little hack to get the flake's source in the nix store
61+
# We will use this to make the option declaration sources more readable
62+
src = removeSuffix "modules/top-level/output.nix" (
63+
head evaluatedNixvim.options.package.declarations
64+
);
65+
in
66+
map (
67+
opt:
68+
let
69+
# The default, as rendered in documentation. Will always be a literalExpression.
70+
default = builtins.addErrorContext "while evaluating the default text for `${showOption opt.loc}`" (
71+
renderOptionValue (opt.defaultText or opt.default)
72+
);
73+
in
74+
''
75+
- ${showOption opt.loc} (${default.text}), declared in:
76+
${concatMapStringsSep "\n" (file: " - ${removePrefix src file}") opt.declarations}
77+
''
78+
) badOptions;
79+
}
80+
''
81+
if [ -n "$errors" ]; then
82+
echo "Found ''${#errors[@]} errors:"
83+
for err in "''${errors[@]}"; do
84+
echo "$err"
85+
done
86+
echo "(''${#errors[@]} options with errors)"
87+
exit 1
88+
fi
89+
touch $out
90+
''

0 commit comments

Comments
 (0)