diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix index 9bc63686fa3a..52d500c64d33 100644 --- a/nixos/doc/manual/default.nix +++ b/nixos/doc/manual/default.nix @@ -1,4 +1,13 @@ -{ pkgs, options, config, version, revision, extraSources ? [], baseOptionsJSON ? null, prefix ? ../../.. }: +{ pkgs +, options +, config +, version +, revision +, extraSources ? [] +, baseOptionsJSON ? null +, warningsAreErrors ? true +, prefix ? ../../.. +}: with pkgs; @@ -15,7 +24,7 @@ let stripAnyPrefixes = lib.flip (lib.foldr lib.removePrefix) prefixesToStrip; optionsDoc = buildPackages.nixosOptionsDoc { - inherit options revision baseOptionsJSON; + inherit options revision baseOptionsJSON warningsAreErrors; transformOptions = opt: opt // { # Clean up declaration sites to not refer to the NixOS source tree. declarations = map stripAnyPrefixes opt.declarations; diff --git a/nixos/lib/make-options-doc/default.nix b/nixos/lib/make-options-doc/default.nix index cc4ddd55d026..57652dd5db1e 100644 --- a/nixos/lib/make-options-doc/default.nix +++ b/nixos/lib/make-options-doc/default.nix @@ -25,6 +25,9 @@ # used to split the options doc build into a static part (nixos/modules) and a dynamic part # (non-nixos modules imported via configuration.nix, other module sources). , baseOptionsJSON ? null +# instead of printing warnings for eg options with missing descriptions (which may be lost +# by nix build unless -L is given), emit errors instead and fail the build +, warningsAreErrors ? true }: let @@ -121,6 +124,7 @@ in rec { then "cp $options $dst/options.json" else '' ${pkgs.python3Minimal}/bin/python ${./mergeJSON.py} \ + ${lib.optionalString warningsAreErrors "--warnings-are-errors"} \ ${baseOptionsJSON} $options \ > $dst/options.json '' diff --git a/nixos/lib/make-options-doc/mergeJSON.py b/nixos/lib/make-options-doc/mergeJSON.py index b7dfe2b88e7a..029787a31586 100644 --- a/nixos/lib/make-options-doc/mergeJSON.py +++ b/nixos/lib/make-options-doc/mergeJSON.py @@ -41,8 +41,10 @@ def unpivot(options: Dict[Key, Option]) -> Dict[str, JSON]: result[opt.name] = opt.value return result -options = pivot(json.load(open(sys.argv[1], 'r'))) -overrides = pivot(json.load(open(sys.argv[2], 'r'))) +warningsAreErrors = sys.argv[1] == "--warnings-are-errors" +optOffset = 1 if warningsAreErrors else 0 +options = pivot(json.load(open(sys.argv[1 + optOffset], 'r'))) +overrides = pivot(json.load(open(sys.argv[2 + optOffset], 'r'))) # fix up declaration paths in lazy options, since we don't eval them from a full nixpkgs dir for (k, v) in options.items(): @@ -65,10 +67,20 @@ for (k, v) in overrides.items(): cur[ok] = ov # check that every option has a description -# TODO: nixos-rebuild with flakes may hide the warning, maybe turn on -L by default for those? +hasWarnings = False for (k, v) in options.items(): if v.value.get('description', None) is None: - print(f"\x1b[1;31mwarning: option {v.name} has no description\x1b[0m", file=sys.stderr) + severity = "error" if warningsAreErrors else "warning" + hasWarnings = True + print(f"\x1b[1;31m{severity}: option {v.name} has no description\x1b[0m", file=sys.stderr) v.value['description'] = "This option has no description." +if hasWarnings and warningsAreErrors: + print( + "\x1b[1;31m" + + "Treating warnings as errors. Set documentation.nixos.options.warningsAreErrors " + + "to false to ignore these warnings." + + "\x1b[0m", + file=sys.stderr) + sys.exit(1) json.dump(unpivot(options), fp=sys.stdout) diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix index f868e4b709a6..4451f3026f85 100644 --- a/nixos/modules/misc/documentation.nix +++ b/nixos/modules/misc/documentation.nix @@ -15,7 +15,7 @@ let f = import m; instance = f (mapAttrs (n: _: abort "evaluating ${n} for `meta` failed") (functionArgs f)); in - cfg.nixos.splitOptionDocBuild + cfg.nixos.options.splitBuild && builtins.isPath m && isFunction f && instance ? options @@ -101,6 +101,7 @@ let exit 1 } >&2 ''; + inherit (cfg.nixos.options) warningsAreErrors; }; @@ -256,7 +257,7 @@ in ''; }; - nixos.splitOptionDocBuild = mkOption { + nixos.options.splitBuild = mkOption { type = types.bool; default = true; description = '' @@ -266,6 +267,15 @@ in ''; }; + nixos.options.warningsAreErrors = mkOption { + type = types.bool; + default = true; + description = '' + Treat warning emitted during the option documentation build (eg for missing option + descriptions) as errors. + ''; + }; + nixos.includeAllModules = mkOption { type = types.bool; default = false;