]> git.ipfire.org Git - thirdparty/systemd.git/blame - tools/update-man-rules.py
build(deps): bump redhat-plumbers-in-action/differential-shellcheck
[thirdparty/systemd.git] / tools / update-man-rules.py
CommitLineData
3e67e5c9 1#!/usr/bin/env python3
db9ecf05 2# SPDX-License-Identifier: LGPL-2.1-or-later
56ba3c78 3
56ba3c78 4import collections
77d45f1f 5import glob
234909f9 6import pprint
56ba3c78 7import sys
77d45f1f 8from pathlib import Path
234909f9 9
1c6c3ef0 10from xml_helper import xml_parse
56ba3c78 11
234909f9 12
56ba3c78 13def man(page, number):
234909f9 14 return f'{page}.{number}'
56ba3c78
ZJS
15
16def add_rules(rules, name):
1a13e31d 17 xml = xml_parse(name)
56ba3c78 18 # print('parsing {}'.format(name), file=sys.stderr)
c0652d45
ZJS
19 if xml.getroot().tag != 'refentry':
20 return
56ba3c78
ZJS
21 conditional = xml.getroot().get('conditional') or ''
22 rulegroup = rules[conditional]
23 refmeta = xml.find('./refmeta')
24 title = refmeta.find('./refentrytitle').text
25 number = refmeta.find('./manvolnum').text
26 refnames = xml.findall('./refnamediv/refname')
27 target = man(refnames[0].text, number)
28 if title != refnames[0].text:
29 raise ValueError('refmeta and refnamediv disagree: ' + name)
30 for refname in refnames:
31 assert all(refname not in group
32 for group in rules.values()), "duplicate page name"
33 alias = man(refname.text, number)
34 rulegroup[alias] = target
35 # print('{} => {} [{}]'.format(alias, target, conditional), file=sys.stderr)
36
40be878a 37def create_rules(xml_files):
56ba3c78
ZJS
38 " {conditional => {alias-name => source-name}} "
39 rules = collections.defaultdict(dict)
40 for name in xml_files:
c0652d45
ZJS
41 try:
42 add_rules(rules, name)
43 except Exception:
44 print("Failed to process", name, file=sys.stderr)
45 raise
56ba3c78
ZJS
46 return rules
47
48def mjoin(files):
49 return ' \\\n\t'.join(sorted(files) or '#')
50
e2bb4105 51MESON_HEADER = '''\
a0e150b2
YW
52# SPDX-License-Identifier: LGPL-2.1-or-later
53
06689b8d 54# Do not edit. Generated by update-man-rules.py.
34d2f920 55# Update with:
e3c368f6 56# ninja -C build update-man-rules
e2bb4105
ZJS
57manpages = ['''
58
59MESON_FOOTER = '''\
60]
77d45f1f
ZJS
61# Really, do not edit.
62'''
e2bb4105 63
234909f9 64def make_mesonfile(rules, _dist_files):
e2bb4105
ZJS
65 # reformat rules as
66 # grouped = [ [name, section, [alias...], condition], ...]
67 #
68 # but first create a dictionary like
69 # lists = { (name, condition) => [alias...]
70 grouped = collections.defaultdict(list)
71 for condition, items in rules.items():
72 for alias, name in items.items():
73 group = grouped[(name, condition)]
74 if name != alias:
75 group.append(alias)
76
77 lines = [ [p[0][:-2], p[0][-1], sorted(a[:-2] for a in aliases), p[1]]
78 for p, aliases in sorted(grouped.items()) ]
79 return '\n'.join((MESON_HEADER, pprint.pformat(lines)[1:-1], MESON_FOOTER))
80
234909f9 81def main():
77d45f1f
ZJS
82 source_glob = sys.argv[1]
83 target = Path(sys.argv[2])
84
85 pages = glob.glob(source_glob)
a2095c06 86 pages = (p for p in pages
77d45f1f 87 if Path(p).name not in {
25cb4c1d 88 'standard-conf.xml',
a2095c06
ZJS
89 'systemd.directives.xml',
90 'systemd.index.xml',
91 'directives-template.xml'})
e2bb4105
ZJS
92
93 rules = create_rules(pages)
77d45f1f
ZJS
94 dist_files = (Path(p).name for p in pages)
95 text = make_mesonfile(rules, dist_files)
96
97 tmp = target.with_suffix('.tmp')
98 tmp.write_text(text)
99 tmp.rename(target)
234909f9
FS
100
101if __name__ == '__main__':
102 main()