169 lines
6.0 KiB
Plaintext
169 lines
6.0 KiB
Plaintext
|
#!/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)
|
||
|
|
||
|
|