1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
#!/cygdrive/C/Python25/python
"""A script to help automate the build process."""
# When preparing a new release, make sure to set all of these to the latest
# values.
VERSIONS = {
'bzr': '1.12',
'qbzr': '0.9.8',
'bzrtools': '1.12.0',
'bzr-svn': '0.5.2',
'bzr-rebase': '0.4.4',
'subvertpy': '0.6.4',
}
# This will be passed to 'make' to ensure we build with the right python
PYTHON='/cygdrive/c/Python25/python'
# Create the final build in this directory
TARGET_ROOT='release'
DEBUG_SUBPROCESS = True
import os
import shutil
import subprocess
import sys
BZR_EXE = None
def bzr():
global BZR_EXE
if BZR_EXE is not None:
return BZR_EXE
try:
subprocess.call(['bzr', '--version'], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
BZR_EXE = 'bzr'
except OSError:
try:
subprocess.call(['bzr.bat', '--version'], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
BZR_EXE = 'bzr.bat'
except OSError:
raise RuntimeError('Could not find bzr or bzr.bat on your path.')
return BZR_EXE
def call_or_fail(*args, **kwargs):
"""Call a subprocess, and fail if the return code is not 0."""
if DEBUG_SUBPROCESS:
print ' calling: "%s"' % (' '.join(args[0]),)
p = subprocess.Popen(*args, **kwargs)
(out, err) = p.communicate()
if p.returncode != 0:
raise RuntimeError('Failed to run: %s, %s' % (args, kwargs))
return out
TARGET = None
def get_target():
global TARGET
if TARGET is not None:
return TARGET
out = call_or_fail([sys.executable, get_bzr_dir() + '/bzr',
'version', '--short'], stdout=subprocess.PIPE)
version = out.strip()
TARGET = os.path.abspath(TARGET_ROOT + '-' + version)
return TARGET
def clean_target():
"""Nuke the target directory so we know we are starting from scratch."""
target = get_target()
if os.path.isdir(target):
print "Deleting: %s" % (target,)
shutil.rmtree(target)
def get_bzr_dir():
return 'bzr.' + VERSIONS['bzr']
def update_bzr():
"""Make sure we have the latest bzr in play."""
bzr_dir = get_bzr_dir()
if not os.path.isdir(bzr_dir):
bzr_version = VERSIONS['bzr']
bzr_url = 'http://bazaar-vcs.org/bzr/bzr.' + bzr_version
print "Getting bzr release %s from %s" % (bzr_version, bzr_url)
call_or_fail([bzr(), 'co', bzr_url])
else:
print "Ensuring %s is up-to-date" % (bzr_dir,)
call_or_fail([bzr(), 'update', bzr_dir])
def create_target():
target = get_target()
print "Creating target dir: %s" % (target,)
call_or_fail([bzr(), 'co', get_bzr_dir(), target])
def get_plugin_trunk_dir(plugin_name):
return '%s/trunk' % (plugin_name,)
def get_plugin_release_dir(plugin_name):
return '%s/%s' % (plugin_name, VERSIONS[plugin_name])
def get_plugin_trunk_branch(plugin_name):
return 'lp:%s' % (plugin_name,)
def update_plugin_trunk(plugin_name):
trunk_dir = get_plugin_trunk_dir(plugin_name)
if not os.path.isdir(trunk_dir):
plugin_trunk = get_plugin_trunk_branch(plugin_name)
print "Getting latest %s trunk" % (plugin_name,)
call_or_fail([bzr(), 'co', plugin_trunk,
trunk_dir])
else:
print "Ensuring %s is up-to-date" % (trunk_dir,)
call_or_fail([bzr(), 'update', trunk_dir])
return trunk_dir
def _plugin_tag_name(plugin_name):
if plugin_name in ('bzr-svn', 'bzr-rebase', 'subvertpy'):
return '%s-%s' % (plugin_name, VERSIONS[plugin_name])
# bzrtools and qbzr use 'release-X.Y.Z'
return 'release-' + VERSIONS[plugin_name]
def update_plugin(plugin_name):
release_dir = get_plugin_release_dir(plugin_name)
if not os.path.isdir(plugin_name):
if plugin_name in ('bzr-svn', 'bzr-rebase'):
# bzr-svn uses a different repo format
call_or_fail([bzr(), 'init-repo', '--rich-root-pack', plugin_name])
else:
os.mkdir(plugin_name)
if os.path.isdir(release_dir):
print "Removing existing dir: %s" % (release_dir,)
shutil.rmtree(release_dir)
# First update trunk
trunk_dir = update_plugin_trunk(plugin_name)
# Now create the tagged directory
tag_name = _plugin_tag_name(plugin_name)
print "Creating the branch %s" % (release_dir,)
call_or_fail([bzr(), 'co', '-rtag:%s' % (tag_name,),
trunk_dir, release_dir])
return release_dir
def install_plugin(plugin_name):
release_dir = update_plugin(plugin_name)
# at least bzrtools doesn't like you to call 'setup.py' unless you are in
# that directory specifically, so we cd, rather than calling it from
# outside
print "Installing %s" % (release_dir,)
call_or_fail([sys.executable, 'setup.py', 'install', '-O1',
'--install-lib=%s' % (get_target(),)],
cwd=release_dir)
def update_tbzr():
tbzr_loc = os.environ.get('TBZR', None)
if tbzr_loc is None:
raise ValueError('You must set TBZR to the location of tortoisebzr.')
print 'Updating %s' % (tbzr_loc,)
call_or_fail([bzr(), 'update', tbzr_loc])
def build_installer():
target = get_target()
print
print
print '*' * 60
print 'Building standalone installer'
call_or_fail(['make', 'PYTHON=%s' % (PYTHON,), 'installer'],
cwd=target)
def main(args):
import optparse
p = optparse.OptionParser(usage='%prog [OPTIONS]')
opts, args = p.parse_args(args)
update_bzr()
update_tbzr()
clean_target()
create_target()
install_plugin('subvertpy')
install_plugin('bzrtools')
install_plugin('qbzr')
install_plugin('bzr-svn')
install_plugin('bzr-rebase')
build_installer()
if __name__ == '__main__':
main(sys.argv[1:])
# vim: ts=4 sw=4 sts=4 et ai
|