blob: adfca3ca5060b6fb0fc7568bb81c038484a176dd [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/usr/bin/env python
Andrew Geissler4ed12e12020-06-05 18:00:41 -05002#
3# SPDX-License-Identifier: GPL-2.0-only
4#
Patrick Williamsc124f4f2015-09-15 14:41:29 -05005# documentation.conf update script
6#
7# Author: Paul Eggleton <paul.eggleton@linux.intel.com>
8#
9# Copyright (C) 2015 Intel Corporation
10#
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011
12
13import sys
14import os
15import argparse
16import re
17from lxml import etree
18import logging
19
20def logger_create(name):
21 logger = logging.getLogger(name)
22 loggerhandler = logging.StreamHandler()
23 loggerhandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
24 logger.addHandler(loggerhandler)
25 logger.setLevel(logging.INFO)
26 return logger
27logger = logger_create('docconfupdater')
28
29def main():
30 parser = argparse.ArgumentParser(description="documentation.conf updater")
31 parser.add_argument('basepath', help='Path to OE-Core base directory')
32 parser.add_argument('-q', '--quiet', help='Print only warnings/errors', action='store_true')
33
34 args = parser.parse_args()
35
36 if args.quiet:
37 logger.setLevel(logging.WARN)
38
39 if not os.path.isdir(args.basepath):
40 logger.error('Specified base path %s not found')
41 return 1
42
43 doc_conf = os.path.join(args.basepath, 'meta', 'conf', 'documentation.conf')
44 if not os.path.exists(doc_conf):
45 logger.error('Unable to find %s' % doc_conf)
46 return 1
47
48 allowed_flags = ['doc']
49 flag_re = re.compile(r'\[(.+?)\]')
50
51 infos = {}
52 tree = etree.parse('ref-manual/ref-variables.xml')
53 root = tree.getroot()
54 for glossary in root.findall('glossary'):
55 for glossdiv in glossary.findall('glossdiv'):
56 for glossentry in glossdiv.findall('glossentry'):
57 info = glossentry.find('info')
58 if info is not None:
59 infoline = ' '.join(info.text.split())
60 infolinesplit = infoline.split('=', 1)
61 if len(infoline) < 2:
62 logger.warn('Invalid info line (no = character), ignoring: %s' % infoline)
63 continue
64 flags = flag_re.findall(infolinesplit[0])
65 if not flags:
66 logger.warn('Invalid info line (no varflag), ignoring: %s' % infoline)
67 continue
68 for flag in flags:
69 if flag not in allowed_flags:
70 logger.warn('Invalid info line (varflag %s not in allowed list), ignoring: %s' % (flag, infoline))
71 continue
72 infos[infolinesplit[0].rstrip()] = infolinesplit[1].lstrip()
73
74 if not infos:
75 logger.error('ERROR: Unable to find any info tags in the glossary')
76 return 1
77
78 def sortkey(key):
79 # Underscores sort undesirably, so replace them
80 return key.split('[')[0].replace('_', '-')
81
82 changed = False
83 lines = []
84 invars = False
85 lastletter = None
86 added = []
87 with open(doc_conf, 'r') as dcf:
88 for line in dcf:
89 if not invars:
90 if line.startswith('#') and 'DESCRIPTIONS FOR VARIABLES' in line:
91 invars = True
92 elif not line.startswith('#'):
93 linesplit = line.split('=', 1)
94 if len(linesplit) > 1:
95 key = linesplit[0].rstrip()
96 lastletter = key[0]
97 # Find anything in the dict that should come before the current key
98 for dkey in sorted(infos.keys()):
99 if sortkey(dkey) < sortkey(key):
100 lines.append('%s = %s\n' % (dkey, infos[dkey]))
101 added.append(dkey)
102 del infos[dkey]
103 changed = True
104 newvalue = infos.get(key, None)
105 if newvalue:
106 del infos[key]
107 if newvalue != linesplit[1].strip():
108 lines.append('%s = %s\n' % (key, newvalue))
109 changed = True
110 continue
111 elif key in added:
112 # We already added a new value for this key, so skip it
113 continue
114 elif lastletter:
115 # Ensure we write out anything anything left over for this letter
116 for dkey in sorted(infos.keys()):
117 if dkey[0] == lastletter:
118 lines.append('%s = %s\n' % (dkey, infos[dkey]))
119 del infos[dkey]
120 changed = True
121 elif dkey[0] > lastletter:
122 # List is sorted, so we're done
123 break
124 lastletter = None
125 lines.append(line)
126
127 if not invars:
128 logger.error('ERROR: Unable to find variables section in documentation.conf')
129 return 1
130
131 if infos:
132 changed = True
133 # Write out anything left over
134 lines.append('\n\n')
135 for key in sorted(infos.keys()):
136 lines.append('%s = %s\n' % (key, infos[key]))
137
138 if changed:
139 logger.info('Updating %s' % doc_conf)
140 with open(doc_conf, 'w') as dcf:
141 for line in lines:
142 dcf.write(line)
143 else:
144 logger.info('No changes required')
145
146 return 0
147
148
149if __name__ == "__main__":
150 try:
151 ret = main()
152 except Exception:
153 ret = 1
154 import traceback
155 traceback.print_exc(5)
156 sys.exit(ret)
157
158