~launchpad-pqm/launchpad/devel

6326.8.19 by Gavin Panella
Add generation script.
1
#!/usr/bin/python2.4
6326.8.21 by Gavin Panella
Comment in the script.
2
#
3
# Generates documentation of mapping from remote bug tracker statuses
4
# to local, Launchpad statuses. Typically, this should be used to
5
# update the online documentation each time the status mappings are
6
# updated.
7
#
8
# See https://help.launchpad.net/BugStatuses
9
#
6326.8.19 by Gavin Panella
Add generation script.
10
7231.2.11 by Gavin Panella
Add XXX to explain why utilities/generate-external-bug-status-docs is not tested.
11
# XXX: GavinPanella 2008-12-03 bug=235434: This script is a temporary
12
# measure before moving the documentation of external bug status
13
# mapping tables into Launchpad proper. It is not tested and will
14
# remain so because it would be a mostly wasted effort. The impact of
15
# this is very low because it is infrequently run, and typically only
16
# by me, so I get to pick up the pieces.
17
6326.8.19 by Gavin Panella
Add generation script.
18
import _pythonpath
19
6326.8.55 by Gavin Panella
New version of the utilities script, using generators and conforming to command line usage standards.
20
import codecs
21
import sys
22
6326.8.22 by Gavin Panella
Add a header to the docs.
23
from datetime import datetime
6326.8.55 by Gavin Panella
New version of the utilities script, using generators and conforming to command line usage standards.
24
from itertools import chain
25
from optparse import OptionParser
6326.8.22 by Gavin Panella
Add a header to the docs.
26
6326.8.19 by Gavin Panella
Add generation script.
27
from canonical.launchpad.components.externalbugtracker import (
28
    BUG_TRACKER_CLASSES)
29
30
6326.8.55 by Gavin Panella
New version of the utilities script, using generators and conforming to command line usage standards.
31
def generate_blank_lines(num):
32
    """Generate `num` blank lines."""
33
    for i in range(num):
34
        yield ''
35
36
37
def generate_page_header():
38
    """Generate the header for the page."""
7231.2.2 by Gavin Panella
Use new MoinMoin anchor syntax.
39
    yield '<<Anchor(StatusTables)>>'
6326.8.55 by Gavin Panella
New version of the utilities script, using generators and conforming to command line usage standards.
40
    yield '== Status mapping tables =='
41
    yield ''
42
    yield 'Last generated: %s.' % (
43
        datetime.utcnow().strftime('%Y-%m-%d %H:%M UTC'),)
44
45
46
def generate_table_header(typ):
47
    """Generate a header for an individual table.
48
49
    :param typ: A member of `BugTrackerType`.
50
    """
7231.2.2 by Gavin Panella
Use new MoinMoin anchor syntax.
51
    yield '<<Anchor(%s)>>' % (typ.name,)
6326.8.55 by Gavin Panella
New version of the utilities script, using generators and conforming to command line usage standards.
52
    yield '=== %s ===' % (typ.title,)
53
54
55
def generate_table_grid(lookup, titles):
56
    """Simply return the table grid generated by the lookup tree."""
57
    return lookup.moinmoin_table(titles)
58
59
60
def generate_table(typ, cls):
61
    """Generate a table documenting the specified external bug tracker.
62
63
    :param typ: A member of `BugTrackerType`.
64
    :param cls: The `ExternalBugTracker` subclass corresponding to `typ`.
65
    """
66
67
    # Get the lookup tree.
68
    lookup = cls._status_lookup
69
70
    # Find or fabricate titles.
71
    titles = getattr(cls, '_status_lookup_titles', None)
72
    if titles is None:
73
        titles = ['Key %d' % (i + 1) for i in range(lookup.max_depth)]
74
    else:
75
        titles = list(titles)
76
    titles.append('Launchpad status')
77
78
    # Format the table.
79
    return chain(
80
        generate_table_header(typ),
81
        generate_blank_lines(1),
82
        generate_table_grid(lookup, titles))
83
84
85
def generate_documentable_classes():
86
    """Yield each class that has a mapping table defined."""
87
    for typ, cls in BUG_TRACKER_CLASSES.iteritems():
88
        if getattr(cls, '_status_lookup', None) is not None:
89
            yield typ, cls
90
91
92
def generate_tables():
93
    """Generate all the tables."""
94
    documentable_classes = sorted(
95
        generate_documentable_classes(),
96
        key=(lambda (typ, cls): typ.title))
97
    return chain(
98
        *(chain(generate_table(typ, cls),
99
                generate_blank_lines(2))
100
          for (typ, cls) in documentable_classes))
101
102
103
def generate_page():
104
    """Generate the MoinMoin-style page."""
105
    return chain(
106
        generate_page_header(),
107
        generate_blank_lines(2),
108
        generate_tables())
109
110
111
def write_page(outfile):
112
    """Write the page lines to `outfile`.
113
114
    :param outfile: A `file`-like object.
115
    """
116
    # By default, encode using UTF-8.
117
    write = codecs.getwriter('UTF-8')(outfile).write
118
    for line in generate_page():
119
        write(line)
120
        write('\n')
121
122
123
def get_option_parser():
124
    """Return the option parser for this program."""
125
    usage = "Usage: %prog [options]"
126
    parser = OptionParser(
127
        usage=usage, description=(
128
            "Generates MoinMoin-style tables to document the mapping of "
129
            "remote bug statuses to Launchpad statuses."))
130
    parser.add_option(
131
        "-o", "--file-out", dest="outfile", default='-', help=(
132
            "write data to OUTFILE"))
133
    return parser
134
135
136
def main(args):
137
    parser = get_option_parser()
138
    (options, args) = parser.parse_args(args)
139
    if len(args) > 0:
140
        parser.error("Incorrect number of arguments.")
141
    if options.outfile == '-':
142
        outfile = sys.stdout
143
    else:
144
        outfile = open(options.outfile, 'wb')
145
    write_page(outfile)
146
147
6326.8.19 by Gavin Panella
Add generation script.
148
if __name__ == '__main__':
6326.8.55 by Gavin Panella
New version of the utilities script, using generators and conforming to command line usage standards.
149
    sys.exit(main(sys.argv[1:]))