From a2298d31c04b4c750d0a7f6c5f24a6d6c547e38c Mon Sep 17 00:00:00 2001 From: Igor Ponomarev Date: Mon, 30 May 2022 15:49:21 +0300 Subject: [PATCH 1/2] tools: Modernize generate-docs-nm-settings-docs-gir.py to 2022 standards * Create main() function and put its execution under __name__ == '__main__' guard. * Only one module import per line * Use required=True to check if necessary arguments have been passed. * Remove usage() as ArgumentParser handles that already --- tools/generate-docs-nm-settings-docs-gir.py | 214 +++++++++++--------- 1 file changed, 113 insertions(+), 101 deletions(-) diff --git a/tools/generate-docs-nm-settings-docs-gir.py b/tools/generate-docs-nm-settings-docs-gir.py index 8fc6db704c..62c4f2627e 100755 --- a/tools/generate-docs-nm-settings-docs-gir.py +++ b/tools/generate-docs-nm-settings-docs-gir.py @@ -3,16 +3,16 @@ # # Copyright (C) 2009 - 2017 Red Hat, Inc. # - -from __future__ import print_function - +from __future__ import print_function, unicode_literals +import argparse import os import gi import xml.sax.saxutils as saxutils +import re gi.require_version("GIRepository", "2.0") from gi.repository import GIRepository -import argparse, re, sys + import xml.etree.ElementTree as ET try: @@ -190,116 +190,128 @@ def xml_quoteattr(val): return saxutils.quoteattr(str(val)) -def usage(): - print("Usage: %s --gir FILE --output FILE" % sys.argv[0]) - exit() +def main(gir_path_str, output_path_str): + girxml = ET.parse(gir_path_str).getroot() + outfile = open(output_path_str, mode="w") + basexml = girxml.find('./gi:namespace/gi:class[@name="Setting"]', ns_map) + settings = girxml.findall('./gi:namespace/gi:class[@parent="Setting"]', ns_map) + # Hack. Need a better way to do this + ipxml = girxml.find('./gi:namespace/gi:class[@name="SettingIPConfig"]', ns_map) + settings.extend( + girxml.findall('./gi:namespace/gi:class[@parent="SettingIPConfig"]', ns_map) + ) + settings = sorted(settings, key=settings_sort_key) -parser = argparse.ArgumentParser() -parser.add_argument( - "-l", - "--lib-path", - metavar="PATH", - action="append", - help="path to scan for shared libraries", -) -parser.add_argument("-g", "--gir", metavar="FILE", help="NM-1.0.gir file") -parser.add_argument("-o", "--output", metavar="FILE", help="output file") + init_constants(girxml, settings) -args = parser.parse_args() -if args.gir is None or args.output is None: - usage() - -if args.lib_path: - for lib in args.lib_path: - GIRepository.Repository.prepend_library_path(lib) - -girxml = ET.parse(args.gir).getroot() -outfile = open(args.output, mode="w") - -basexml = girxml.find('./gi:namespace/gi:class[@name="Setting"]', ns_map) -settings = girxml.findall('./gi:namespace/gi:class[@parent="Setting"]', ns_map) -# Hack. Need a better way to do this -ipxml = girxml.find('./gi:namespace/gi:class[@name="SettingIPConfig"]', ns_map) -settings.extend( - girxml.findall('./gi:namespace/gi:class[@parent="SettingIPConfig"]', ns_map) -) -settings = sorted(settings, key=settings_sort_key) - -init_constants(girxml, settings) - -outfile.write( - """ - -]> - -""" -) - -for settingxml in settings: - if "abstract" in settingxml.attrib: - continue - - new_func = NM.__getattr__(settingxml.attrib["name"]) - setting = new_func() - - class_desc = get_docs(settingxml) - if class_desc is None: - raise Exception( - "%s needs a gtk-doc block with one-line description" % setting.props.name - ) outfile.write( - ' \n' - % ( - setting.props.name, - xml_quoteattr(class_desc), - get_setting_name_define(settingxml), - ) + """ + + ]> + + """ ) - setting_properties = { - prop.name: prop - for prop in GObject.list_properties(setting) - if prop.name != "name" - } + for settingxml in settings: + if "abstract" in settingxml.attrib: + continue - for prop in sorted(setting_properties): - pspec = setting_properties[prop] + new_func = NM.__getattr__(settingxml.attrib["name"]) + setting = new_func() - propxml = settingxml.find('./gi:property[@name="%s"]' % pspec.name, ns_map) - if propxml is None: - propxml = basexml.find('./gi:property[@name="%s"]' % pspec.name, ns_map) - if propxml is None: - propxml = ipxml.find('./gi:property[@name="%s"]' % pspec.name, ns_map) - - value_type = get_prop_type(setting, pspec) - value_desc = get_docs(propxml) - default_value = get_default_value(setting, pspec, propxml) - - prop_upper = prop.upper().replace("-", "_") - - if value_desc is None: + class_desc = get_docs(settingxml) + if class_desc is None: raise Exception( - "%s.%s needs a documentation description" % (setting.props.name, prop) + "%s needs a gtk-doc block with one-line description" + % setting.props.name ) - - default_value_as_xml = "" - if default_value is not None: - default_value_as_xml = " default=%s" % (xml_quoteattr(default_value)) - outfile.write( - ' \n' + ' \n' % ( - prop, - prop_upper, - value_type, - default_value_as_xml, - xml_quoteattr(value_desc), + setting.props.name, + xml_quoteattr(class_desc), + get_setting_name_define(settingxml), ) ) - outfile.write(" \n") + setting_properties = { + prop.name: prop + for prop in GObject.list_properties(setting) + if prop.name != "name" + } -outfile.write("\n") -outfile.close() + for prop in sorted(setting_properties): + pspec = setting_properties[prop] + + propxml = settingxml.find('./gi:property[@name="%s"]' % pspec.name, ns_map) + if propxml is None: + propxml = basexml.find('./gi:property[@name="%s"]' % pspec.name, ns_map) + if propxml is None: + propxml = ipxml.find('./gi:property[@name="%s"]' % pspec.name, ns_map) + + value_type = get_prop_type(setting, pspec) + value_desc = get_docs(propxml) + default_value = get_default_value(setting, pspec, propxml) + + prop_upper = prop.upper().replace("-", "_") + + if value_desc is None: + raise Exception( + "%s.%s needs a documentation description" + % (setting.props.name, prop) + ) + + default_value_as_xml = "" + if default_value is not None: + default_value_as_xml = " default=%s" % (xml_quoteattr(default_value)) + + outfile.write( + ' \n' + % ( + prop, + prop_upper, + value_type, + default_value_as_xml, + xml_quoteattr(value_desc), + ) + ) + + outfile.write(" \n") + + outfile.write("\n") + outfile.close() + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "-l", + "--lib-path", + metavar="PATH", + action="append", + help="path to scan for shared libraries", + ) + parser.add_argument( + "-g", + "--gir", + metavar="FILE", + help="NM-1.0.gir file", + required=True, + ) + parser.add_argument( + "-o", + "--output", + metavar="FILE", + help="output file", + required=True, + ) + + args = parser.parse_args() + + if args.lib_path: + for lib in args.lib_path: + GIRepository.Repository.prepend_library_path(lib) + + main(args.gir, args.output) From f00e90923c8c5715b32e06c1d6131b85e9a84a9e Mon Sep 17 00:00:00 2001 From: Igor Ponomarev Date: Mon, 30 May 2022 18:40:01 +0300 Subject: [PATCH 2/2] tools: Use ElementTree to write XML in generate-docs-nm-settings-docs-gir.py Instead of manually writting XML line by line. Quoting is automatic. Makes it much easier to modify. (just add new elements) Generated XML not indented at the moment. --- tools/generate-docs-nm-settings-docs-gir.py | 69 +++++++++------------ 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/tools/generate-docs-nm-settings-docs-gir.py b/tools/generate-docs-nm-settings-docs-gir.py index 62c4f2627e..a40234efbe 100755 --- a/tools/generate-docs-nm-settings-docs-gir.py +++ b/tools/generate-docs-nm-settings-docs-gir.py @@ -4,17 +4,15 @@ # Copyright (C) 2009 - 2017 Red Hat, Inc. # from __future__ import print_function, unicode_literals +import xml.etree.ElementTree as ET import argparse import os import gi -import xml.sax.saxutils as saxutils import re gi.require_version("GIRepository", "2.0") from gi.repository import GIRepository -import xml.etree.ElementTree as ET - try: libs = os.environ["LD_LIBRARY_PATH"].split(":") libs.reverse() @@ -186,13 +184,8 @@ def settings_sort_key(x): return (x_prefix != "setting_connection", x_prefix) -def xml_quoteattr(val): - return saxutils.quoteattr(str(val)) - - def main(gir_path_str, output_path_str): girxml = ET.parse(gir_path_str).getroot() - outfile = open(output_path_str, mode="w") basexml = girxml.find('./gi:namespace/gi:class[@name="Setting"]', ns_map) settings = girxml.findall('./gi:namespace/gi:class[@parent="Setting"]', ns_map) @@ -205,14 +198,8 @@ def main(gir_path_str, output_path_str): init_constants(girxml, settings) - outfile.write( - """ - - ]> - - """ - ) + nm_settings_docs_element = ET.Element("nm-setting-docs") + docs_gir = ET.ElementTree(nm_settings_docs_element) for settingxml in settings: if "abstract" in settingxml.attrib: @@ -227,13 +214,14 @@ def main(gir_path_str, output_path_str): "%s needs a gtk-doc block with one-line description" % setting.props.name ) - outfile.write( - ' \n' - % ( - setting.props.name, - xml_quoteattr(class_desc), - get_setting_name_define(settingxml), - ) + setting_element = ET.SubElement( + nm_settings_docs_element, + "setting", + attrib={ + "name": setting.props.name, + "description": class_desc, + "name_upper": get_setting_name_define(settingxml), + }, ) setting_properties = { @@ -263,25 +251,28 @@ def main(gir_path_str, output_path_str): % (setting.props.name, prop) ) - default_value_as_xml = "" - if default_value is not None: - default_value_as_xml = " default=%s" % (xml_quoteattr(default_value)) + property_attributes = { + "name": prop, + "name_upper": prop_upper, + "type": value_type, + "description": value_desc, + } - outfile.write( - ' \n' - % ( - prop, - prop_upper, - value_type, - default_value_as_xml, - xml_quoteattr(value_desc), - ) + if default_value is not None: + property_attributes["default"] = str(default_value) + + ET.SubElement( + setting_element, + "property", + attrib=property_attributes, ) - outfile.write(" \n") - - outfile.write("\n") - outfile.close() + with open(output_path_str, mode="w") as outfile: + docs_gir.write( + outfile, + encoding="unicode", + xml_declaration=True, + ) if __name__ == "__main__":