diff --git a/documentation/tools/update-documentation-conf b/documentation/tools/update-documentation-conf new file mode 100644 index 0000000000..3f8d280093 --- /dev/null +++ b/documentation/tools/update-documentation-conf @@ -0,0 +1,168 @@ +#!/usr/bin/env python + +# documentation.conf update script +# +# Author: Paul Eggleton +# +# Copyright (C) 2015 Intel Corporation +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +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) + +