#!/usr/bin/python3 import os import sys import pathlib import tempfile import subprocess from argparse import ArgumentParser from lxml import etree def parse_args(): parser = ArgumentParser(description='Generate DocBook documentation from D-Bus IDL.') parser.add_argument( '--idl', action='store', help='IDL file', required=True, type=str, metavar='FILE', ) parser.add_argument( '--output-directory', action='store', help='Output directory where DocBook files will be saved', required=True, type=str, metavar='DIR', ) parser.add_argument( '--tmp', action='store', help='Temporary directory for intermediate files', required=True, type=str, metavar='DIR', ) return parser.parse_args() ARGS = parse_args() pathlib.Path(ARGS.output_directory).mkdir(parents=True, exist_ok=True) REF_ENTRY_INFO = '''\ stafctl nvme-stas Mr Martin Belanger Dell, Inc. ''' MANVOLNUM = '5' PURPOSE = 'DBus interface' PARSER = etree.XMLParser(remove_blank_text=True) def add_missing_info(fname, stem): xml = etree.parse(fname, PARSER) root = xml.getroot() if root.tag != 'refentry': return if xml.find('refentryinfo'): return root.insert(0, etree.fromstring(REF_ENTRY_INFO)) refmeta = xml.find('refmeta') if refmeta is not None: if refmeta.find('refentrytitle') is None: refmeta.append(etree.fromstring(f'{stem}')) refmeta.append(etree.fromstring(MANVOLNUM)) refnamediv = xml.find('refnamediv') if refnamediv is not None: refpurpose = refnamediv.find('refpurpose') if refpurpose is not None: refnamediv.remove(refpurpose) refnamediv.append(etree.fromstring(PURPOSE)) et = etree.ElementTree(root) et.write(fname, pretty_print=True) FILE_PREFIX = 'nvme-stas' FINAL_PREFIX = FILE_PREFIX + '-' pathlib.Path(ARGS.tmp).mkdir(parents=True, exist_ok=True) with tempfile.TemporaryDirectory(dir=ARGS.tmp) as tmpdirname: try: subprocess.run(['gdbus-codegen', '--output-directory', tmpdirname, '--generate-docbook', FILE_PREFIX, ARGS.idl]) except subprocess.CalledProcessError as ex: sys.exit(f'Failed to generate DocBook file. {ex}') stems = [] with os.scandir(tmpdirname) as it: for entry in it: if entry.is_file() and entry.name.endswith('.xml') and entry.name.startswith(FINAL_PREFIX): fname = entry.name[len(FINAL_PREFIX) :] # Strip prefix stem = fname[0:-4] # Strip '.xml' suffix stems.append(stem) tmp_file = os.path.join(tmpdirname, entry.name) add_missing_info(tmp_file, stem) os.replace(tmp_file, os.path.join(ARGS.output_directory, fname)) print(';'.join(stems))