aboutsummaryrefslogtreecommitdiffstats
path: root/documentation/tools/update-documentation-conf
blob: 3f8d28009390e66b6a46b137b87c46b020586da3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/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)