/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to tools/generate_release_notes.py

  • Committer: Robert Collins
  • Date: 2010-05-05 00:05:29 UTC
  • mto: This revision was merged to the branch mainline in revision 5206.
  • Revision ID: robertc@robertcollins.net-20100505000529-ltmllyms5watqj5u
Make 'pydoc bzrlib.tests.build_tree_shape' useful.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python3
 
1
#!/usr/bin/python
2
2
 
3
 
# Copyright 2009-2010 Canonical Ltd.
 
3
# Copyright 2009 Canonical Ltd.
4
4
#
5
5
# This program is free software; you can redistribute it and/or modify
6
6
# it under the terms of the GNU General Public License as published by
16
16
# along with this program; if not, write to the Free Software
17
17
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
18
 
19
 
"""Generate doc/en/release-notes/index.txt from the per-series NEWS files.
20
 
 
21
 
NEWS files are kept in doc/en/release-notes/, one file per series, e.g.
22
 
doc/en/release-notes/brz-2.3.txt
23
 
"""
24
 
 
25
 
# XXX: add test_source test that latest doc/en/release-notes/brz-*.txt has the
26
 
# NEWS file-id (so that merges of new work will tend to always land new NEWS
27
 
# entries in the latest series).
28
 
 
29
 
 
30
 
import os.path
31
 
import re
 
19
import os
32
20
import sys
33
21
from optparse import OptionParser
34
22
 
35
 
 
36
 
preamble_plain = """\
37
 
####################
38
 
Breezy Release Notes
39
 
####################
40
 
 
41
 
 
42
 
.. contents:: List of Releases
43
 
   :depth: 2
44
 
 
45
 
"""
46
 
 
47
 
preamble_sphinx = """\
48
 
####################
49
 
Breezy Release Notes
50
 
####################
51
 
 
52
 
 
53
 
.. toctree::
54
 
   :maxdepth: 2
55
 
 
56
 
"""
57
 
 
58
 
 
59
 
def natural_sort_key(file_name):
60
 
    """Split 'aaa-N.MMbbb' into ('aaa-', N, '.' MM, 'bbb')
61
 
 
62
 
    e.g. 1.10b1 will sort as greater than 1.2::
63
 
 
64
 
        >>> natural_sort_key('brz-1.10b1.txt') > natural_sort_key('brz-1.2.txt')
65
 
        True
 
23
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
 
24
 
 
25
 
 
26
def split_into_topics(lines, out_file, out_dir):
 
27
    """Split a large NEWS file into topics, one per release.
 
28
 
 
29
    Releases are detected by matching headings that look like
 
30
    release names. Topics are created with matching names
 
31
    replacing spaces with dashes.
66
32
    """
67
 
    file_name = os.path.basename(file_name)
68
 
    parts = re.findall(r'(?:[0-9]+|[^0-9]+)', file_name)
69
 
    result = []
70
 
    for part in parts:
71
 
        if re.match('^[0-9]+$', part) is not None:
72
 
            part = int(part)
73
 
        result.append(part)
74
 
    return tuple(result)
75
 
 
76
 
 
77
 
def output_news_file_sphinx(out_file, news_file_name):
78
 
    news_file_name = os.path.basename(news_file_name)
79
 
    if not news_file_name.endswith('.txt'):
80
 
        raise AssertionError(
81
 
            'NEWS file %s does not have .txt extension.'
82
 
            % (news_file_name,))
83
 
    doc_name = news_file_name[:-4]
84
 
    link_text = doc_name.replace('-', ' ')
85
 
    out_file.write('   %s <%s>\n' % (link_text, doc_name))
86
 
 
87
 
 
88
 
def output_news_file_plain(out_file, news_file_name):
89
 
    with open(news_file_name, 'r') as f:
90
 
        lines = f.readlines()
91
 
    title = os.path.basename(news_file_name)[len('brz-'):-len('.txt')]
92
 
    for line in lines:
93
 
        if line == '####################\n':
94
 
            line = '#' * len(title) + '\n'
95
 
        elif line == 'Breezy Release Notes\n':
96
 
            line = title + '\n'
97
 
        elif line == '.. toctree::\n':
98
 
            continue
99
 
        elif line == '   :maxdepth: 1\n':
100
 
            continue
101
 
        out_file.write(line)
102
 
    out_file.write('\n\n')
 
33
    topic_file = None
 
34
    for index, line in enumerate(lines):
 
35
        maybe_new_topic = line[:4] in ['bzr ', 'bzr-0',]
 
36
        if maybe_new_topic and lines[index + 1].startswith('####'):
 
37
            release = line.strip()
 
38
            if topic_file is None:
 
39
                # First topic found
 
40
                out_file.write(".. toctree::\n   :maxdepth: 1\n\n")
 
41
            else:
 
42
                # close the current topic
 
43
                topic_file.close()
 
44
            topic_file = open_topic_file(out_file, out_dir, release)
 
45
        elif topic_file:
 
46
            topic_file.write(line)
 
47
        else:
 
48
            # Still in the header - dump content straight to output
 
49
            out_file.write(line)
 
50
 
 
51
 
 
52
def open_topic_file(out_file, out_dir, release):
 
53
    topic_name = release.replace(' ', '-')
 
54
    out_file.write("   %s\n" % (topic_name,))
 
55
    topic_path = os.path.join(out_dir, "%s.txt" % (topic_name,))
 
56
    result = open(topic_path, 'w')
 
57
    result.write("%s\n" % (release,))
 
58
    return result
103
59
 
104
60
 
105
61
def main(argv):
106
62
    # Check usage
107
 
    parser = OptionParser(usage="%prog OUTPUT_FILE NEWS_FILE [NEWS_FILE ...]")
 
63
    parser = OptionParser(usage="%prog SOURCE DESTINATION")
108
64
    (options, args) = parser.parse_args(argv)
109
 
    if len(args) < 2:
 
65
    if len(args) != 2:
110
66
        parser.print_help()
111
67
        sys.exit(1)
112
68
 
113
69
    # Open the files and do the work
114
 
    out_file_name = args[0]
115
 
    news_file_names = sorted(args[1:], key=natural_sort_key, reverse=True)
116
 
 
117
 
    if os.path.basename(out_file_name) == 'index.txt':
118
 
        preamble = preamble_sphinx
119
 
        output_news_file = output_news_file_sphinx
120
 
    else:
121
 
        preamble = preamble_plain
122
 
        output_news_file = output_news_file_plain
123
 
 
124
 
    with open(out_file_name, 'w') as out_file:
125
 
        out_file.write(preamble)
126
 
        for news_file_name in news_file_names:
127
 
            output_news_file(out_file, news_file_name)
 
70
    infile_name = args[0]
 
71
    outfile_name = args[1]
 
72
    outdir = os.path.dirname(outfile_name)
 
73
    infile = open(infile_name, 'r')
 
74
    try:
 
75
        lines = infile.readlines()
 
76
    finally:
 
77
        infile.close()
 
78
    outfile = open(outfile_name, 'w')
 
79
    try:
 
80
        split_into_topics(lines, outfile, outdir)
 
81
    finally:
 
82
        outfile.close()
128
83
 
129
84
 
130
85
if __name__ == '__main__':