poky/documentation/tools/update-documentation-conf
Scott Rifenbark eafdfbfb37 tools: Added new file update-documentation-conf
This is a Python script that a developer can run to create a .patch
file that when submitted to oe-core will update the documentation.conf
file.  The update will bring the [doc] file variable descriptions
in line with what is in the ref-manual variables file.

Reported-by: Paul Eggleton <paul.eggleton@intel.com>
(From yocto-docs rev: f9dca76a8d9be3dcdbde9229beb03f0ba3701485)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-02-17 15:16:52 +00:00

6.0 KiB

#!/usr/bin/env python

documentation.conf update script

Author: Paul Eggleton paul.eggleton@linux.intel.com

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)