5 from typing
import Any
, Dict
, List
10 def __init__(self
, path
: List
[str]):
17 def __eq__(self
, other
):
18 return type(self
) is type(other
) and self
.path
== other
.path
20 Option
= collections
.namedtuple('Option', ['name', 'value'])
22 # pivot a dict of options keyed by their display name to a dict keyed by their path
23 def pivot(options
: Dict
[str, JSON
]) -> Dict
[Key
, Option
]:
24 result
: Dict
[Key
, Option
] = dict()
25 for (name
, opt
) in options
.items():
26 result
[Key(opt
['loc'])] = Option(name
, opt
)
29 # pivot back to indexed-by-full-name
30 # like the docbook build we'll just fail if multiple options with differing locs
31 # render to the same option name.
32 def unpivot(options
: Dict
[Key
, Option
]) -> Dict
[str, JSON
]:
33 result
: Dict
[str, Dict
] = dict()
34 for (key
, opt
) in options
.items():
35 if opt
.name
in result
:
37 'multiple options with colliding ids found',
39 result
[opt
.name
]['loc'],
42 result
[opt
.name
] = opt
.value
45 warningsAreErrors
= False
47 for arg
in sys
.argv
[1:]:
48 if arg
== "--warnings-are-errors":
50 warningsAreErrors
= True
52 options
= pivot(json
.load(open(sys
.argv
[1 + optOffset
], 'r')))
53 overrides
= pivot(json
.load(open(sys
.argv
[2 + optOffset
], 'r')))
55 # fix up declaration paths in lazy options, since we don't eval them from a full nixpkgs dir
56 for (k
, v
) in options
.items():
57 # The _module options are not declared in nixos/modules
58 if v
.value
['loc'][0] != "_module":
59 v
.value
['declarations'] = list(map(lambda s
: f
'nixos/modules/{s}' if isinstance(s
, str) else s
, v
.value
['declarations']))
61 # merge both descriptions
62 for (k
, v
) in overrides
.items():
63 cur
= options
.setdefault(k
, v
).value
64 for (ok
, ov
) in v
.value
.items():
65 if ok
== 'declarations':
71 # ignore types of placeholder options
72 if ov
!= "_unspecified" or cur
[ok
] == "_unspecified":
74 elif ov
is not None or cur
.get(ok
, None) is None:
77 severity
= "error" if warningsAreErrors
else "warning"
79 # check that every option has a description
82 for (k
, v
) in options
.items():
83 if v
.value
.get('description', None) is None:
85 print(f
"\x1b[1;31m{severity}: option {v.name} has no description\x1b[0m", file=sys
.stderr
)
86 v
.value
['description'] = "This option has no description."
87 if v
.value
.get('type', "unspecified") == "unspecified":
90 f
"\x1b[1;31m{severity}: option {v.name} has no type. Please specify a valid type, see " +
91 "https://nixos.org/manual/nixos/stable/index.html#sec-option-types\x1b[0m", file=sys
.stderr
)
95 if hasWarnings
and warningsAreErrors
:
98 "Treating warnings as errors. Set documentation.nixos.options.warningsAreErrors " +
99 "to false to ignore these warnings." +
104 json
.dump(unpivot(options
), fp
=sys
.stdout
)