mirror of
https://github.com/systemd/systemd
synced 2024-07-21 02:05:05 +00:00
tools: pylint update-dbus-docs.py
This commit is contained in:
parent
c6041b8bf8
commit
019e726958
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
# pylint: disable=superfluous-parens,consider-using-with
|
||||
|
||||
import argparse
|
||||
import collections
|
||||
|
@ -36,6 +37,8 @@ GREEN = '\x1b[32m'
|
|||
YELLOW = '\x1b[33m'
|
||||
RESET = '\x1b[39m'
|
||||
|
||||
arguments = None
|
||||
|
||||
def xml_parser():
|
||||
return etree.XMLParser(no_network=True,
|
||||
remove_comments=False,
|
||||
|
@ -62,38 +65,38 @@ def print_method(declarations, elem, *, prefix, file, is_signal=False):
|
|||
argname = arg.get('name')
|
||||
|
||||
if argname is None:
|
||||
if opts.print_errors:
|
||||
if arguments.print_errors:
|
||||
print(f'method {name}: argument {num+1} has no name', file=sys.stderr)
|
||||
argname = 'UNNAMED'
|
||||
|
||||
type = arg.get('type')
|
||||
argtype = arg.get('type')
|
||||
if not is_signal:
|
||||
direction = arg.get('direction')
|
||||
print(f'''{lead if num > 0 else ''}{direction:3} {type} {argname}''', file=file, end='')
|
||||
print(f'''{lead if num > 0 else ''}{direction:3} {argtype} {argname}''', file=file, end='')
|
||||
else:
|
||||
print(f'''{lead if num > 0 else ''}{type} {argname}''', file=file, end='')
|
||||
print(f'''{lead if num > 0 else ''}{argtype} {argname}''', file=file, end='')
|
||||
|
||||
print(f');', file=file)
|
||||
print(');', file=file)
|
||||
|
||||
ACCESS_MAP = {
|
||||
'read' : 'readonly',
|
||||
'write' : 'readwrite',
|
||||
}
|
||||
|
||||
def value_ellipsis(type):
|
||||
if type == 's':
|
||||
return "'...'";
|
||||
if type[0] == 'a':
|
||||
inner = value_ellipsis(type[1:])
|
||||
return f"[{inner}{', ...' if inner != '...' else ''}]";
|
||||
def value_ellipsis(prop_type):
|
||||
if prop_type == 's':
|
||||
return "'...'"
|
||||
if prop_type[0] == 'a':
|
||||
inner = value_ellipsis(prop_type[1:])
|
||||
return f"[{inner}{', ...' if inner != '...' else ''}]"
|
||||
return '...'
|
||||
|
||||
def print_property(declarations, elem, *, prefix, file):
|
||||
name = elem.get('name')
|
||||
type = elem.get('type')
|
||||
access = elem.get('access')
|
||||
prop_name = elem.get('name')
|
||||
prop_type = elem.get('type')
|
||||
prop_access = elem.get('access')
|
||||
|
||||
declarations['property'].append(name)
|
||||
declarations['property'].append(prop_name)
|
||||
|
||||
# @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
# @org.freedesktop.systemd1.Privileged("true")
|
||||
|
@ -104,8 +107,8 @@ def print_property(declarations, elem, *, prefix, file):
|
|||
anno_value = anno.get('value')
|
||||
print(f'''{prefix}@{anno_name}("{anno_value}")''', file=file)
|
||||
|
||||
access = ACCESS_MAP.get(access, access)
|
||||
print(f'''{prefix}{access} {type} {name} = {value_ellipsis(type)};''', file=file)
|
||||
prop_access = ACCESS_MAP.get(prop_access, prop_access)
|
||||
print(f'''{prefix}{prop_access} {prop_type} {prop_name} = {value_ellipsis(prop_type)};''', file=file)
|
||||
|
||||
def print_interface(iface, *, prefix, file, print_boring, only_interface, declarations):
|
||||
name = iface.get('name')
|
||||
|
@ -163,7 +166,7 @@ def check_documented(document, declarations, stats):
|
|||
assert False, (klass, item)
|
||||
|
||||
if not document_has_elem_with_text(document, elem, item_repr):
|
||||
if opts.print_errors:
|
||||
if arguments.print_errors:
|
||||
print(f'{klass} {item} is not documented :(')
|
||||
missing.append((klass, item))
|
||||
|
||||
|
@ -189,7 +192,7 @@ def xml_to_text(destination, xml, *, only_interface=None):
|
|||
if not name in BORING_INTERFACES:
|
||||
interfaces.append(name)
|
||||
|
||||
print(f'''}};''', file=file)
|
||||
print('''};''', file=file)
|
||||
|
||||
return file.getvalue(), declarations, interfaces
|
||||
|
||||
|
@ -202,7 +205,7 @@ def subst_output(document, programlisting, stats):
|
|||
node = programlisting.get('node')
|
||||
interface = programlisting.get('interface')
|
||||
|
||||
argv = [f'{opts.build_dir}/{executable}', f'--bus-introspect={interface}']
|
||||
argv = [f'{arguments.build_dir}/{executable}', f'--bus-introspect={interface}']
|
||||
if isinstance(shlex_join, Exception):
|
||||
print(f'COMMAND: {" ".join(shlex_quote(arg) for arg in argv)}')
|
||||
else:
|
||||
|
@ -225,14 +228,11 @@ def subst_output(document, programlisting, stats):
|
|||
|
||||
# delete old comments
|
||||
for child in parent:
|
||||
if (child.tag == etree.Comment
|
||||
and 'Autogenerated' in child.text):
|
||||
if child.tag is etree.Comment and 'Autogenerated' in child.text:
|
||||
parent.remove(child)
|
||||
if (child.tag == etree.Comment
|
||||
and 'not documented' in child.text):
|
||||
if child.tag is etree.Comment and 'not documented' in child.text:
|
||||
parent.remove(child)
|
||||
if (child.tag == "variablelist"
|
||||
and child.attrib.get("generated",False) == "True"):
|
||||
if child.tag == "variablelist" and child.attrib.get("generated", False) == "True":
|
||||
parent.remove(child)
|
||||
|
||||
# insert pointer for systemd-directives generation
|
||||
|
@ -282,7 +282,7 @@ def process(page):
|
|||
|
||||
# print('parsing {}'.format(name), file=sys.stderr)
|
||||
if xml.tag != 'refentry':
|
||||
return
|
||||
return None
|
||||
|
||||
stats = collections.Counter()
|
||||
|
||||
|
@ -297,11 +297,11 @@ def process(page):
|
|||
out_text[out_text.find('<refentryinfo'):] +
|
||||
'\n')
|
||||
|
||||
if not opts.test:
|
||||
if not arguments.test:
|
||||
with open(page, 'w') as out:
|
||||
out.write(out_text)
|
||||
|
||||
return dict(stats=stats, modified=(out_text != src))
|
||||
return { "stats" : stats, "modified" : out_text != src }
|
||||
|
||||
def parse_args():
|
||||
p = argparse.ArgumentParser()
|
||||
|
@ -313,25 +313,27 @@ def parse_args():
|
|||
opts.print_errors = not opts.test
|
||||
return opts
|
||||
|
||||
if __name__ == '__main__':
|
||||
opts = parse_args()
|
||||
def main():
|
||||
# pylint: disable=global-statement
|
||||
global arguments
|
||||
arguments = parse_args()
|
||||
|
||||
for item in (etree, shlex_quote):
|
||||
if isinstance(item, Exception):
|
||||
print(item, file=sys.stderr)
|
||||
exit(77 if opts.test else 1)
|
||||
sys.exit(77 if arguments.test else 1)
|
||||
|
||||
if not os.path.exists(f'{opts.build_dir}/systemd'):
|
||||
exit(f"{opts.build_dir}/systemd doesn't exist. Use --build-dir=.")
|
||||
if not os.path.exists(f'{arguments.build_dir}/systemd'):
|
||||
sys.exit(f"{arguments.build_dir}/systemd doesn't exist. Use --build-dir=.")
|
||||
|
||||
stats = {page.split('/')[-1] : process(page) for page in opts.pages}
|
||||
stats = {page.split('/')[-1] : process(page) for page in arguments.pages}
|
||||
|
||||
# Let's print all statistics at the end
|
||||
mlen = max(len(page) for page in stats)
|
||||
total = sum((item['stats'] for item in stats.values()), collections.Counter())
|
||||
total = 'total', dict(stats=total, modified=False)
|
||||
total = 'total', { "stats" : total, "modified" : False }
|
||||
modified = []
|
||||
classification = 'OUTDATED' if opts.test else 'MODIFIED'
|
||||
classification = 'OUTDATED' if arguments.test else 'MODIFIED'
|
||||
for page, info in sorted(stats.items()) + [total]:
|
||||
m = info['stats']['missing']
|
||||
t = info['stats']['total']
|
||||
|
@ -342,6 +344,9 @@ if __name__ == '__main__':
|
|||
color = RED if m > t/2 else (YELLOW if m else GREEN)
|
||||
print(f'{color}{p:{mlen + 1}} {t - m}/{t} {c}{RESET}')
|
||||
|
||||
if opts.test and modified:
|
||||
exit(f'Outdated pages: {", ".join(modified)}\n'
|
||||
f'Hint: ninja -C {opts.build_dir} update-dbus-docs')
|
||||
if arguments.test and modified:
|
||||
sys.exit(f'Outdated pages: {", ".join(modified)}\n'
|
||||
f'Hint: ninja -C {arguments.build_dir} update-dbus-docs')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
Loading…
Reference in a new issue