~launchpad-pqm/launchpad/devel

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