2
# -*- coding: utf-8 -*-
7
Helper script that performs a release. Does pretty much everything
10
:copyright: (c) 2013 by Armin Ronacher.
11
:license: BSD, see LICENSE for more details.
16
from datetime import datetime, date
17
from subprocess import Popen, PIPE
19
_date_clean_re = re.compile(r'(\d+)(st|nd|rd|th)')
22
def parse_changelog():
23
with open('CHANGES') as f:
26
match = re.search('^Version\s+(.*)', line.strip())
29
length = len(match.group(1))
30
version = match.group(1).strip()
31
if lineiter.next().count('-') != len(match.group(0)):
34
change_info = lineiter.next().strip()
38
match = re.search(r'released on (\w+\s+\d+\w+\s+\d+)'
39
r'(?:, codename (.*))?(?i)', change_info)
43
datestr, codename = match.groups()
44
return version, parse_date(datestr), codename
47
def bump_version(version):
49
parts = map(int, version.split('.'))
51
fail('Current version is not numeric')
56
return '.'.join(map(str, parts))
59
def parse_date(string):
60
string = _date_clean_re.sub(r'\1', string)
61
return datetime.strptime(string, '%B %d %Y')
64
def set_filename_version(filename, version_number, pattern):
66
def inject_version(match):
67
before, old, after = match.groups()
69
return before + version_number + after
70
with open(filename) as f:
71
contents = re.sub(r"^(\s*%s\s*=\s*')(.+?)(')(?sm)" % pattern,
72
inject_version, f.read())
75
fail('Could not find %s in %s', pattern, filename)
77
with open(filename, 'w') as f:
81
def set_init_version(version):
82
info('Setting __init__.py version to %s', version)
83
set_filename_version('babel/__init__.py', version, '__version__')
86
def set_setup_version(version):
87
info('Setting setup.py version to %s', version)
88
set_filename_version('setup.py', version, 'version')
91
def build_and_upload():
92
Popen([sys.executable, 'setup.py', 'release', 'sdist', 'upload']).wait()
95
def fail(message, *args):
96
print >> sys.stderr, 'Error:', message % args
100
def info(message, *args):
101
print >> sys.stderr, message % args
105
return set(Popen(['git', 'tag'], stdout=PIPE).communicate()[0].splitlines())
109
return Popen(['git', 'diff', '--quiet']).wait() == 0
112
def make_git_commit(message, *args):
113
message = message % args
114
Popen(['git', 'commit', '-am', message]).wait()
117
def make_git_tag(tag):
118
info('Tagging "%s"', tag)
119
Popen(['git', 'tag', tag]).wait()
123
os.chdir(os.path.join(os.path.dirname(__file__), '..'))
125
rv = parse_changelog()
127
fail('Could not parse changelog')
129
version, release_date, codename = rv
130
dev_version = bump_version(version) + '-dev'
132
info('Releasing %s (codename %s, release date %s)',
133
version, codename, release_date.strftime('%d/%m/%Y'))
134
tags = get_git_tags()
137
fail('Version "%s" is already tagged', version)
138
if release_date.date() != date.today():
139
fail('Release date is not today (%s != %s)')
141
if not git_is_clean():
142
fail('You have uncommitted changes in git')
144
set_init_version(version)
145
set_setup_version(version)
146
make_git_commit('Bump version number to %s', version)
147
make_git_tag(version)
149
set_init_version(dev_version)
150
set_setup_version(dev_version)
153
if __name__ == '__main__':