3
# Copyright (C) 1998-2006 by the Free Software Foundation, Inc.
5
# This program is free software; you can redistribute it and/or
6
# modify it under the terms of the GNU General Public License
7
# as published by the Free Software Foundation; either version 2
8
# of the License, or (at your option) any later version.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20
# XXX This file does not need to be compatible with Python 2.1. It is only
21
# used by the release manager.
31
from subprocess import Popen, PIPE
32
from urlparse import urlparse
35
__revision__ = '$Revision: 8022 $'
37
parts = __revision__.split()
39
__version__ = parts[1]
41
__version__ = parts[0]
49
def calculate_urls(relname):
51
stdout, stderr = do('svn info')
52
for line in stdout.splitlines():
53
key, val = line.split(':', 1)
54
if key.lower() == 'url':
58
print >> sys.stderr, 'No source url found'
60
scheme, netloc, path, params, query, frag = urlparse(srcurl)
61
if params or query or frag:
62
print >> sys.stderr, 'src url has params, query and/or frag'
64
parts = path.split(SLASH)
65
# XXX Fix this to work on the trunk too
66
for i, part in enumerate(parts):
67
if part == 'branches':
70
print >> sys.stderr, 'No branches directory found in src url'
73
parts.extend(['tags', relname])
74
dsturl = SLASH.join(parts)
79
proc = Popen(cmd.split(), stdout=PIPE, stderr=PIPE)
80
stdout, stderr = proc.communicate()
85
return time.strftime('%d-%b-%Y', time.localtime(time.time()))
88
def releasedir(tagname=None):
89
tmpdir = tempfile.gettempdir()
90
return os.path.join(tmpdir, 'mailman-' + tagname)
94
return 'Release_' + tagname.replace('.', '_')
98
def tag_release(tagname):
99
# Convert dots in tagname to underscores
100
relname = tag2rel(tagname)
101
# Calculate the 'tags' directory, which should be a sibling of the
102
# 'branches' directory.
103
srcurl, dsturl = calculate_urls(relname)
104
print 'Tag url:', dsturl
105
fd, msgfile = tempfile.mkstemp(text=True)
108
fp = open(msgfile, 'w')
110
print >> fp, 'Tagging release', tagname
113
do('svn cp %s %s -F %s' % (srcurl, dsturl, msgfile))
119
def make_pkg(tagname, sign):
120
reldir = releasedir(tagname)
121
if os.path.exists(reldir):
122
print >> sys.stderr, 'Release directory already exists:', reldir
124
relname = tag2rel(tagname)
125
srcurl, dsturl = calculate_urls(relname)
126
print 'Exporting to release dir', reldir, '...'
127
do('svn export %s %s' % (dsturl, reldir))
128
if not os.path.exists(reldir):
129
print >> sys.stderr, 'svn export failed:', dsturl
133
os.chdir(os.path.dirname(reldir))
134
print 'Making tarball...'
135
relname = 'mailman-' + tagname
136
tarfile = relname + '.tgz'
137
do('tar cvzf %s --exclude .svn %s' % (tarfile, relname))
138
do('tar cvzf mailman-doc.tgz --exclude .svn mailman-doc')
140
do('gpg -bas %s' % tarfile)
146
VERSIONMARK = '<!-VERSION--->'
147
DATEMARK = '<!-DATE--->'
150
def do_bump(newvers):
151
print 'Doing bump...',
152
for file in ('index.ht',):
153
print '\t%s...' % file,
154
fp = open(os.path.join('admin', 'www', file), 'r+')
156
parts = text.split(VERSIONMARK)
158
text = VERSIONMARK.join(parts)
159
parts = text.split(DATEMARK)
161
text = DATEMARK.join(parts)
165
# hack the configure.in file
166
print 'Version.py...',
167
infp = open('Mailman/Version.py')
168
outfp = open('Mailman/Version.py.new', 'w')
170
cre = re.compile(r'^VERSION(?P<ws>[ \t]*)=')
172
mo = cre.search(line)
173
if matched or not mo:
176
outfp.write('VERSION%s= "%s"\n' % (mo.group('ws'), newvers))
179
print >> sys.stderr, 'Error! VERSION line not found'
182
os.rename('Mailman/Version.py.new', 'Mailman/Version.py')
187
parser = optparse.OptionParser(version=__version__,
189
%prog [options] tagname
191
Manage releases of Mailman. tagname is used in the various commands above.
192
It should essentially be the version number for the release, and is
194
parser.add_option('-t', '--tag',
195
default=False, action='store_true', help="""\
196
Tag all release files with tagname.""")
197
parser.add_option('-p', '--package',
198
default=False, action='store_true',
199
help='Create the distribution package.')
200
parser.add_option('-b', '--bump',
201
default=False, action='store_true', help="""\
202
Bump the revision number in key files to tagname. This is done by textual
204
parser.add_option('-s', '--sign',
205
default=False, action='store_true', help="""\
206
Sign the release. gpg will prompt you for your passphrase.""")
207
opts, args = parser.parse_args()
209
print >> sys.stderr, 'Unexpected arguments:', SPACE(args[1:])
212
print >> sys.stderr, 'Required tagname argument is missing'
214
return parser, opts, args[0]
219
parser, opts, tagname = parseargs()
229
make_pkg(tagname, opts.sign)
235
if __name__ == '__main__':