~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
24
import sys
25
6326.8.22 by Gavin Panella
Add a header to the docs.
26
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.
27
from itertools import chain
28
from optparse import OptionParser
6326.8.22 by Gavin Panella
Add a header to the docs.
29
6326.8.19 by Gavin Panella
Add generation script.
30
from canonical.launchpad.components.externalbugtracker import (
31
    BUG_TRACKER_CLASSES)
32
33
6326.8.55 by Gavin Panella
New version of the utilities script, using generators and conforming to command line usage standards.
34
def generate_blank_lines(num):
35
    """Generate `num` blank lines."""
36
    for i in range(num):
37
        yield ''
38
39
40
def generate_page_header():
41
    """Generate the header for the page."""
7231.2.2 by Gavin Panella
Use new MoinMoin anchor syntax.
42
    yield '<<Anchor(StatusTables)>>'
6326.8.55 by Gavin Panella
New version of the utilities script, using generators and conforming to command line usage standards.
43
    yield '== Status mapping tables =='
44
    yield ''
45
    yield 'Last generated: %s.' % (
46
        datetime.utcnow().strftime('%Y-%m-%d %H:%M UTC'),)
47
48
49
def generate_table_header(typ):
50
    """Generate a header for an individual table.
51
52
    :param typ: A member of `BugTrackerType`.
53
    """
7231.2.2 by Gavin Panella
Use new MoinMoin anchor syntax.
54
    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.
55
    yield '=== %s ===' % (typ.title,)
56
57
58
def generate_table_grid(lookup, titles):
59
    """Simply return the table grid generated by the lookup tree."""
60
    return lookup.moinmoin_table(titles)
61
62
63
def generate_table(typ, cls):
64
    """Generate a table documenting the specified external bug tracker.
65
66
    :param typ: A member of `BugTrackerType`.
67
    :param cls: The `ExternalBugTracker` subclass corresponding to `typ`.
68
    """
69
70
    # Get the lookup tree.
71
    lookup = cls._status_lookup
72
73
    # Find or fabricate titles.
74
    titles = getattr(cls, '_status_lookup_titles', None)
75
    if titles is None:
76
        titles = ['Key %d' % (i + 1) for i in range(lookup.max_depth)]
77
    else:
78
        titles = list(titles)
79
    titles.append('Launchpad status')
80
81
    # Format the table.
82
    return chain(
83
        generate_table_header(typ),
84
        generate_blank_lines(1),
85
        generate_table_grid(lookup, titles))
86
87
88
def generate_documentable_classes():
89
    """Yield each class that has a mapping table defined."""
90
    for typ, cls in BUG_TRACKER_CLASSES.iteritems():
91
        if getattr(cls, '_status_lookup', None) is not None:
92
            yield typ, cls
93
94
95
def generate_tables():
96
    """Generate all the tables."""
97
    documentable_classes = sorted(
98
        generate_documentable_classes(),
99
        key=(lambda (typ, cls): typ.title))
100
    return chain(
101
        *(chain(generate_table(typ, cls),
102
                generate_blank_lines(2))
103
          for (typ, cls) in documentable_classes))
104
105
106
def generate_page():
107
    """Generate the MoinMoin-style page."""
108
    return chain(
109
        generate_page_header(),
110
        generate_blank_lines(2),
111
        generate_tables())
112
113
114
def write_page(outfile):
115
    """Write the page lines to `outfile`.
116
117
    :param outfile: A `file`-like object.
118
    """
119
    # By default, encode using UTF-8.
120
    write = codecs.getwriter('UTF-8')(outfile).write
121
    for line in generate_page():
122
        write(line)
123
        write('\n')
124
125
126
def get_option_parser():
127
    """Return the option parser for this program."""
128
    usage = "Usage: %prog [options]"
129
    parser = OptionParser(
130
        usage=usage, description=(
131
            "Generates MoinMoin-style tables to document the mapping of "
132
            "remote bug statuses to Launchpad statuses."))
133
    parser.add_option(
134
        "-o", "--file-out", dest="outfile", default='-', help=(
135
            "write data to OUTFILE"))
136
    return parser
137
138
139
def main(args):
140
    parser = get_option_parser()
141
    (options, args) = parser.parse_args(args)
142
    if len(args) > 0:
143
        parser.error("Incorrect number of arguments.")
144
    if options.outfile == '-':
145
        outfile = sys.stdout
146
    else:
147
        outfile = open(options.outfile, 'wb')
148
    write_page(outfile)
149
150
6326.8.19 by Gavin Panella
Add generation script.
151
if __name__ == '__main__':
6326.8.55 by Gavin Panella
New version of the utilities script, using generators and conforming to command line usage standards.
152
    sys.exit(main(sys.argv[1:]))