#!/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)