diff --git a/tools/update-dbus-docs.py b/tools/update-dbus-docs.py index 99c3db5744..287d378205 100755 --- a/tools/update-dbus-docs.py +++ b/tools/update-dbus-docs.py @@ -4,10 +4,10 @@ import argparse import collections -import sys +import io import os import subprocess -import io +import sys try: from lxml import etree @@ -19,9 +19,11 @@ try: except ImportError as e: shlex_join = e + class NoCommand(Exception): pass + BORING_INTERFACES = [ 'org.freedesktop.DBus.Peer', 'org.freedesktop.DBus.Introspectable', @@ -34,11 +36,10 @@ RESET = '\x1b[39m' arguments = None + def xml_parser(): - return etree.XMLParser(no_network=True, - remove_comments=False, - strip_cdata=False, - resolve_entities=False) + return etree.XMLParser(no_network=True, remove_comments=False, strip_cdata=False, resolve_entities=False) + def print_method(declarations, elem, *, prefix, file, is_signal=False): name = elem.get('name') @@ -61,7 +62,7 @@ def print_method(declarations, elem, *, prefix, file, is_signal=False): if argname is None: if arguments.print_errors: - print(f'method {name}: argument {num+1} has no name', file=sys.stderr) + print(f'method {name}: argument {num + 1} has no name', file=sys.stderr) argname = 'UNNAMED' argtype = arg.get('type') @@ -73,19 +74,22 @@ def print_method(declarations, elem, *, prefix, file, is_signal=False): print(');', file=file) + ACCESS_MAP = { - 'read' : 'readonly', - 'write' : 'readwrite', + 'read': 'readonly', + 'write': 'readwrite', } + 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 f'[{inner}{", ..." if inner != "..." else ""}]' return '...' + def print_property(declarations, elem, *, prefix, file): prop_name = elem.get('name') prop_type = elem.get('type') @@ -105,11 +109,11 @@ def print_property(declarations, elem, *, prefix, 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') - is_boring = (name in BORING_INTERFACES or - only_interface is not None and name != only_interface) + is_boring = name in BORING_INTERFACES or only_interface is not None and name != only_interface if is_boring and print_boring: print(f'''{prefix}interface {name} {{ ... }};''', file=file) @@ -135,10 +139,11 @@ def print_interface(iface, *, prefix, file, print_boring, only_interface, declar print(f'''{prefix}}};''', file=file) + def check_documented(document, declarations, stats, interface, missing_version): missing = [] - sections = document.findall("refsect1") + sections = document.findall('refsect1') history_section = document.find("refsect1[title = 'History']") if history_section is not None: sections.remove(history_section) @@ -171,12 +176,13 @@ def check_documented(document, declarations, stats, interface, missing_version): missing.append((klass, item)) if history_section is None or history_section.find(predicate) is None: - missing_version.append(f"{interface}.{item_repr}") + missing_version.append(f'{interface}.{item_repr}') stats['missing'] += len(missing) return missing + def xml_to_text(destination, xml, *, only_interface=None): file = io.StringIO() @@ -187,18 +193,23 @@ def xml_to_text(destination, xml, *, only_interface=None): for print_boring in [False, True]: for iface in xml.findall('./interface'): - print_interface(iface, prefix=' ', file=file, - print_boring=print_boring, - only_interface=only_interface, - declarations=declarations) + print_interface( + iface, + prefix=' ', + file=file, + print_boring=print_boring, + only_interface=only_interface, + declarations=declarations, + ) name = iface.get('name') - if not name in BORING_INTERFACES: + if name not in BORING_INTERFACES: interfaces.append(name) print('''};''', file=file) return file.getvalue(), declarations, interfaces + def subst_output(document, programlisting, stats, missing_version): executable = programlisting.get('executable', None) if executable is None: @@ -232,17 +243,17 @@ def subst_output(document, programlisting, stats, missing_version): parent.remove(child) 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 - the_tail = programlisting.tail #tail is erased by addnext, so save it here. - prev_element = etree.Comment("Autogenerated cross-references for systemd.directives, do not edit") + the_tail = programlisting.tail # tail is erased by addnext, so save it here. + prev_element = etree.Comment('Autogenerated cross-references for systemd.directives, do not edit') programlisting.addnext(prev_element) programlisting.tail = the_tail for interface in interfaces: - variablelist = etree.Element("variablelist") + variablelist = etree.Element('variablelist') variablelist.attrib['class'] = 'dbus-interface' variablelist.attrib['generated'] = 'True' variablelist.attrib['extra-ref'] = interface @@ -251,10 +262,10 @@ def subst_output(document, programlisting, stats, missing_version): prev_element.tail = the_tail prev_element = variablelist - for decl_type,decl_list in declarations.items(): + for decl_type, decl_list in declarations.items(): for declaration in decl_list: - variablelist = etree.Element("variablelist") - variablelist.attrib['class'] = 'dbus-'+decl_type + variablelist = etree.Element('variablelist') + variablelist.attrib['class'] = 'dbus-' + decl_type variablelist.attrib['generated'] = 'True' if decl_type in ('method', 'signal'): variablelist.attrib['extra-ref'] = declaration + '()' @@ -265,7 +276,7 @@ def subst_output(document, programlisting, stats, missing_version): prev_element.tail = the_tail prev_element = variablelist - last_element = etree.Comment("End of Autogenerated section") + last_element = etree.Comment('End of Autogenerated section') prev_element.addnext(last_element) prev_element.tail = the_tail last_element.tail = the_tail @@ -276,6 +287,7 @@ def subst_output(document, programlisting, stats, missing_version): comment.tail = programlisting.tail parent.insert(parent.index(programlisting) + 1, comment) + def process(page, missing_version): src = open(page).read() xml = etree.fromstring(src, parser=xml_parser()) @@ -293,26 +305,35 @@ def process(page, missing_version): out_text = etree.tostring(xml, encoding='unicode') # massage format to avoid some lxml whitespace handling idiosyncrasies # https://bugs.launchpad.net/lxml/+bug/526799 - out_text = (src[:src.find(' t/2 else (YELLOW if m else GREEN) + color = RED if m > t / 2 else (YELLOW if m else GREEN) print(f'{color}{p:{mlen + 1}} {t - m}/{t} {c}{RESET}') if arguments.test and modified: - sys.exit(f'Outdated pages: {", ".join(modified)}\n' - f'Hint: ninja -C {arguments.build_dir} update-dbus-docs') + sys.exit( + f'Outdated pages: {", ".join(modified)}\n' + f'Hint: ninja -C {arguments.build_dir} update-dbus-docs' + ) # fmt: skip + if __name__ == '__main__': main()