| #!/usr/bin/env python |
| # |
| # SPDX-License-Identifier: GPL-2.0-only |
| # |
| # documentation.conf update script |
| # |
| # Author: Paul Eggleton <paul.eggleton@linux.intel.com> |
| # |
| # Copyright (C) 2015 Intel Corporation |
| # |
| |
| |
| import sys |
| import os |
| import argparse |
| import re |
| from lxml import etree |
| import logging |
| |
| def logger_create(name): |
| logger = logging.getLogger(name) |
| loggerhandler = logging.StreamHandler() |
| loggerhandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s")) |
| logger.addHandler(loggerhandler) |
| logger.setLevel(logging.INFO) |
| return logger |
| logger = logger_create('docconfupdater') |
| |
| def main(): |
| parser = argparse.ArgumentParser(description="documentation.conf updater") |
| parser.add_argument('basepath', help='Path to OE-Core base directory') |
| parser.add_argument('-q', '--quiet', help='Print only warnings/errors', action='store_true') |
| |
| args = parser.parse_args() |
| |
| if args.quiet: |
| logger.setLevel(logging.WARN) |
| |
| if not os.path.isdir(args.basepath): |
| logger.error('Specified base path %s not found') |
| return 1 |
| |
| doc_conf = os.path.join(args.basepath, 'meta', 'conf', 'documentation.conf') |
| if not os.path.exists(doc_conf): |
| logger.error('Unable to find %s' % doc_conf) |
| return 1 |
| |
| allowed_flags = ['doc'] |
| flag_re = re.compile(r'\[(.+?)\]') |
| |
| infos = {} |
| tree = etree.parse('ref-manual/ref-variables.xml') |
| root = tree.getroot() |
| for glossary in root.findall('glossary'): |
| for glossdiv in glossary.findall('glossdiv'): |
| for glossentry in glossdiv.findall('glossentry'): |
| info = glossentry.find('info') |
| if info is not None: |
| infoline = ' '.join(info.text.split()) |
| infolinesplit = infoline.split('=', 1) |
| if len(infoline) < 2: |
| logger.warn('Invalid info line (no = character), ignoring: %s' % infoline) |
| continue |
| flags = flag_re.findall(infolinesplit[0]) |
| if not flags: |
| logger.warn('Invalid info line (no varflag), ignoring: %s' % infoline) |
| continue |
| for flag in flags: |
| if flag not in allowed_flags: |
| logger.warn('Invalid info line (varflag %s not in allowed list), ignoring: %s' % (flag, infoline)) |
| continue |
| infos[infolinesplit[0].rstrip()] = infolinesplit[1].lstrip() |
| |
| if not infos: |
| logger.error('ERROR: Unable to find any info tags in the glossary') |
| return 1 |
| |
| def sortkey(key): |
| # Underscores sort undesirably, so replace them |
| return key.split('[')[0].replace('_', '-') |
| |
| changed = False |
| lines = [] |
| invars = False |
| lastletter = None |
| added = [] |
| with open(doc_conf, 'r') as dcf: |
| for line in dcf: |
| if not invars: |
| if line.startswith('#') and 'DESCRIPTIONS FOR VARIABLES' in line: |
| invars = True |
| elif not line.startswith('#'): |
| linesplit = line.split('=', 1) |
| if len(linesplit) > 1: |
| key = linesplit[0].rstrip() |
| lastletter = key[0] |
| # Find anything in the dict that should come before the current key |
| for dkey in sorted(infos.keys()): |
| if sortkey(dkey) < sortkey(key): |
| lines.append('%s = %s\n' % (dkey, infos[dkey])) |
| added.append(dkey) |
| del infos[dkey] |
| changed = True |
| newvalue = infos.get(key, None) |
| if newvalue: |
| del infos[key] |
| if newvalue != linesplit[1].strip(): |
| lines.append('%s = %s\n' % (key, newvalue)) |
| changed = True |
| continue |
| elif key in added: |
| # We already added a new value for this key, so skip it |
| continue |
| elif lastletter: |
| # Ensure we write out anything anything left over for this letter |
| for dkey in sorted(infos.keys()): |
| if dkey[0] == lastletter: |
| lines.append('%s = %s\n' % (dkey, infos[dkey])) |
| del infos[dkey] |
| changed = True |
| elif dkey[0] > lastletter: |
| # List is sorted, so we're done |
| break |
| lastletter = None |
| lines.append(line) |
| |
| if not invars: |
| logger.error('ERROR: Unable to find variables section in documentation.conf') |
| return 1 |
| |
| if infos: |
| changed = True |
| # Write out anything left over |
| lines.append('\n\n') |
| for key in sorted(infos.keys()): |
| lines.append('%s = %s\n' % (key, infos[key])) |
| |
| if changed: |
| logger.info('Updating %s' % doc_conf) |
| with open(doc_conf, 'w') as dcf: |
| for line in lines: |
| dcf.write(line) |
| else: |
| logger.info('No changes required') |
| |
| return 0 |
| |
| |
| if __name__ == "__main__": |
| try: |
| ret = main() |
| except Exception: |
| ret = 1 |
| import traceback |
| traceback.print_exc(5) |
| sys.exit(ret) |
| |
| |