1 |
1 |
import os
|
|
2 |
import re
|
2 |
3 |
|
3 |
4 |
import logging
|
4 |
5 |
logging.basicConfig()
|
5 |
|
from optparse import OptionParser
|
|
6 |
#from optparse import OptionParser
|
|
7 |
from argparse import ArgumentParser
|
6 |
8 |
|
7 |
9 |
os.environ["GIT_PYTHON_TRACE"] = "full"
|
8 |
10 |
from devflow import utils, versioning
|
9 |
11 |
from devflow.version import __version__
|
10 |
12 |
from devflow.autopkg import call
|
11 |
|
from devflow.ui import query_action
|
|
13 |
from devflow.ui import query_action, query_user, query_yes_no
|
12 |
14 |
from functools import wraps, partial
|
13 |
15 |
from contextlib import contextmanager
|
14 |
16 |
from git.exc import GitCommandError
|
|
17 |
from sh import mktemp
|
|
18 |
|
|
19 |
|
|
20 |
def create_temp_file(suffix):
|
|
21 |
create_dir_cmd = mktemp("/tmp/" + suffix + "-XXXXX")
|
|
22 |
return create_dir_cmd.stdout.strip()
|
15 |
23 |
|
16 |
24 |
|
17 |
25 |
def cleanup(func):
|
... | ... | |
38 |
46 |
yield
|
39 |
47 |
except GitCommandError as e:
|
40 |
48 |
if e.status != 128:
|
41 |
|
print "An error occured. Resolve it and type 'exit'"
|
42 |
|
call("bash")
|
|
49 |
print "An error occured. Resolve it and type 'exit 0'"
|
|
50 |
tmpbashrc=create_temp_file("bashrc")
|
|
51 |
f = open(tmpbashrc, 'w')
|
|
52 |
f.write("source $HOME/.bashrc ; export PS1=(Conflict)\"$PS1\"")
|
|
53 |
f.close()
|
|
54 |
call('bash --rcfile %s' % tmpbashrc)
|
|
55 |
os.unlink(tmpbashrc)
|
43 |
56 |
else:
|
44 |
57 |
raise
|
45 |
58 |
|
|
59 |
def get_release_version(develop_version):
|
|
60 |
version = develop_version.rstrip('next')
|
|
61 |
parts = version.split('.')
|
|
62 |
major_version = int(parts[0])
|
|
63 |
minor_version = int(parts[1])
|
|
64 |
#return str(major_version) + '.' + str(minor_version+1) + 'rc1'
|
|
65 |
return str(major_version) + '.' + str(minor_version+1)
|
|
66 |
|
|
67 |
def get_develop_version_from_release(release_version):
|
|
68 |
#version = re.sub('rc[0-9]+$', '', release_version)
|
|
69 |
version = release_version
|
|
70 |
parts = version.split('.')
|
|
71 |
major_version = int(parts[0])
|
|
72 |
minor_version = int(parts[1])
|
|
73 |
return str(major_version) + '.' + str(minor_version+1) + 'next'
|
|
74 |
|
|
75 |
def get_hotfix_version(version):
|
|
76 |
parts = version.split('.')
|
|
77 |
major_version = int(parts[0])
|
|
78 |
minor_version = int(parts[1])
|
|
79 |
if (len(parts) > 2):
|
|
80 |
hotfix_version = int(parts[2])
|
|
81 |
else:
|
|
82 |
hotfix_version = 0
|
|
83 |
|
|
84 |
return str(major_version) + '.' + str(minor_version) + '.'\
|
|
85 |
+ str(hotfix_version+1)
|
46 |
86 |
|
47 |
87 |
class GitManager(object):
|
48 |
88 |
def __init__(self):
|
... | ... | |
54 |
94 |
self.log.info("Repository: %s. HEAD: %s", self.repo, self.start_hex)
|
55 |
95 |
self.new_branches = []
|
56 |
96 |
self.new_tags = []
|
57 |
|
self.repo.git.pull("origin")
|
|
97 |
#self.repo.git.pull("origin")
|
58 |
98 |
|
59 |
99 |
def get_branch(self, mode, version):
|
60 |
100 |
if mode not in ["release", "hotfix"]:
|
... | ... | |
66 |
106 |
raise ValueError("Unknown mode: %s" % mode)
|
67 |
107 |
return "debian-%s-%s" % (mode, version)
|
68 |
108 |
|
69 |
|
@cleanup
|
70 |
|
def start_release(self, version):
|
71 |
|
self.start_common("release", version)
|
|
109 |
def doit(self, action_yes=None, action_no=None, question="Do it", args=None,
|
|
110 |
default=False):
|
|
111 |
if not args.defaults:
|
|
112 |
ret = query_yes_no(question, default = "yes" if default else "no")
|
|
113 |
else:
|
|
114 |
ret = default
|
72 |
115 |
|
73 |
|
@cleanup
|
74 |
|
def start_hotfix(self, version):
|
75 |
|
self.start_common("hotfix", version)
|
|
116 |
if ret and action_yes:
|
|
117 |
action_yes()
|
|
118 |
elif not ret and action_no:
|
|
119 |
action_no()
|
|
120 |
|
|
121 |
def __print_cleanup(self, branches):
|
|
122 |
print "To remove obsolete branches run:"
|
|
123 |
for b in branches:
|
|
124 |
print "git branch -D %s" % b
|
|
125 |
|
|
126 |
|
|
127 |
def __cleanup_branches(self, branches):
|
|
128 |
repo = self.repo
|
|
129 |
for b in branches:
|
|
130 |
repo.git.branch("-D", b)
|
|
131 |
|
|
132 |
def cleanup_branches(self, branches, args, default=False):
|
|
133 |
if args.cleanup is not None:
|
|
134 |
if args.cleanup:
|
|
135 |
self.__cleanup_branches(branches)
|
|
136 |
else:
|
|
137 |
self.__print_cleanup(branches)
|
|
138 |
return
|
|
139 |
|
|
140 |
question="Remove branches %s" % branches
|
|
141 |
action_yes = partial(self.__cleanup_branches, branches)
|
|
142 |
action_no = partial(self.__print_cleanup, branches)
|
|
143 |
self.doit(action_yes=action_yes, action_no=action_no,
|
|
144 |
question=question, args=args, default=default)
|
|
145 |
|
|
146 |
|
|
147 |
def check_edit_changelog(self, edit_action, args, default=True):
|
|
148 |
if args.edit_changelog is not None:
|
|
149 |
if args.edit_changelog:
|
|
150 |
edit_action()
|
|
151 |
return
|
|
152 |
question = "Edit changelog ?"
|
|
153 |
self.doit(action_yes=edit_action, question=question, args=args,
|
|
154 |
default=default)
|
|
155 |
|
|
156 |
def _merge_branches(self, branch_to, branch_from):
|
|
157 |
repo = self.repo
|
|
158 |
cur_branch = repo.active_branch.name
|
|
159 |
repo.git.checkout(branch_to)
|
|
160 |
with conflicts():
|
|
161 |
repo.git.merge("--no-ff", branch_from)
|
|
162 |
repo.git.checkout(cur_branch)
|
|
163 |
|
|
164 |
def merge_branches(self, branch_to, branch_from, args, default=True):
|
|
165 |
action = partial(self._merge_branches, branch_to, branch_from)
|
|
166 |
question = "Merge branch %s to %s ?" % (branch_from, branch_to)
|
|
167 |
self.doit(action_yes=action, question=question, args=args,
|
|
168 |
default=default)
|
|
169 |
|
|
170 |
def edit_changelog(self, branch, base_branch=None):
|
|
171 |
repo = self.repo
|
|
172 |
if not branch in repo.branches:
|
|
173 |
raise ValueError("Branch %s does not exist." % branch)
|
|
174 |
if base_branch and not base_branch in repo.branches:
|
|
175 |
raise ValueError("Branch %s does not exist." % base_branch)
|
|
176 |
|
|
177 |
repo.git.checkout(branch)
|
|
178 |
topdir = repo.working_dir
|
|
179 |
changelog = os.path.join(topdir, "Changelog")
|
|
180 |
|
|
181 |
lines = []
|
|
182 |
lines.append("#Changelog for %s\n" % branch)
|
|
183 |
if base_branch:
|
|
184 |
commits = repo.git.rev_list("%s..%s" % (base_branch, branch)).split("\n")
|
|
185 |
for c in commits:
|
|
186 |
commit = repo.commit(c)
|
|
187 |
lines.append(commit.message)
|
|
188 |
lines.append("\n")
|
|
189 |
|
|
190 |
f = open(changelog, 'rw+')
|
|
191 |
lines.extend(f.readlines())
|
|
192 |
f.seek(0)
|
|
193 |
f.truncate(0)
|
|
194 |
f.writelines(lines)
|
|
195 |
f.close()
|
|
196 |
|
|
197 |
editor = os.getenv('EDITOR')
|
|
198 |
if not editor:
|
|
199 |
editor = 'vim'
|
|
200 |
call("%s %s" % (editor, changelog))
|
|
201 |
repo.git.add(changelog)
|
|
202 |
repo.git.commit(m="Update changelog")
|
|
203 |
print "Updated changelog on branch %s" % branch
|
76 |
204 |
|
77 |
205 |
@cleanup
|
78 |
|
def end_release(self, version):
|
|
206 |
def start_release(self, args):
|
79 |
207 |
repo = self.repo
|
80 |
|
master = "master"
|
81 |
|
debian_master = "debian"
|
82 |
208 |
upstream = "develop"
|
83 |
209 |
debian = "debian-develop"
|
|
210 |
repo.git.checkout(upstream)
|
|
211 |
|
|
212 |
vcs = utils.get_vcs_info()
|
|
213 |
develop_version = versioning.get_base_version(vcs)
|
|
214 |
if not args.version:
|
|
215 |
version = get_release_version(develop_version)
|
|
216 |
if not args.defaults:
|
|
217 |
version = query_user("Release version", default=version)
|
|
218 |
else:
|
|
219 |
#validate version?
|
|
220 |
pass
|
|
221 |
rc_version = "%src1" % version
|
|
222 |
new_develop_version = "%snext" % version
|
|
223 |
|
84 |
224 |
upstream_branch = self.get_branch("release", version)
|
85 |
225 |
debian_branch = self.get_debian_branch("release", version)
|
86 |
|
repo.git.checkout(upstream)
|
87 |
|
with conflicts():
|
88 |
|
repo.git.merge("--no-ff", upstream_branch)
|
|
226 |
|
|
227 |
#create release branch
|
|
228 |
repo.git.branch(upstream_branch, upstream)
|
|
229 |
self.new_branches.append(upstream_branch)
|
|
230 |
repo.git.checkout(upstream_branch)
|
|
231 |
versioning.bump_version(rc_version)
|
|
232 |
|
|
233 |
#create debian release branch
|
89 |
234 |
repo.git.checkout(debian)
|
90 |
|
with conflicts():
|
91 |
|
repo.git.merge("--no-ff", debian_branch)
|
|
235 |
repo.git.branch(debian_branch, debian)
|
|
236 |
self.new_branches.append(debian_branch)
|
92 |
237 |
|
93 |
|
repo.git.checkout(master)
|
94 |
|
with conflicts():
|
95 |
|
repo.git.merge("--no-ff", upstream_branch)
|
96 |
|
repo.git.checkout(debian_master)
|
97 |
|
with conflicts():
|
98 |
|
repo.git.merge("--no-ff", debian_branch)
|
|
238 |
repo.git.checkout(upstream_branch)
|
|
239 |
repo.git.checkout(debian)
|
99 |
240 |
|
|
241 |
#bump develop version
|
100 |
242 |
repo.git.checkout(upstream)
|
101 |
|
print "To remove obsolete branches run:"
|
102 |
|
print "git branch -d %s" % upstream_branch
|
103 |
|
print "git branch -d %s" % debian_branch
|
|
243 |
versioning.bump_version(new_develop_version)
|
|
244 |
|
|
245 |
repo.git.checkout(upstream_branch)
|
|
246 |
|
104 |
247 |
|
105 |
248 |
@cleanup
|
106 |
|
def end_hotfix(self, version):
|
|
249 |
def start_hotfix(self, args):
|
107 |
250 |
repo = self.repo
|
108 |
251 |
upstream = "master"
|
109 |
252 |
debian = "debian"
|
110 |
|
upstream_branch = self.get_branch("hotfix", version)
|
111 |
|
debian_branch = self.get_debian_branch("hotfix", version)
|
112 |
|
|
113 |
253 |
repo.git.checkout(upstream)
|
114 |
|
with conflicts():
|
115 |
|
repo.git.merge("--no-ff", upstream_branch)
|
116 |
|
repo.git.checkout(debian)
|
117 |
|
with conflicts():
|
118 |
|
repo.git.merge("--no-ff", debian_branch)
|
|
254 |
#maybe provide major.minor version, find the latest release/hotfix and
|
|
255 |
#branch from there ?
|
|
256 |
|
|
257 |
vcs = utils.get_vcs_info()
|
|
258 |
version = versioning.get_base_version(vcs)
|
|
259 |
if not args.version:
|
|
260 |
version = get_hotfix_version(version)
|
|
261 |
if not args.defaults:
|
|
262 |
version = query_user("Hotfix version", default=version)
|
|
263 |
else:
|
|
264 |
#validate version?
|
|
265 |
pass
|
119 |
266 |
|
120 |
|
repo.git.checkout(upstream)
|
121 |
|
print "To remove obsolete branches run:"
|
122 |
|
print "git branch -d %s" % upstream_branch
|
123 |
|
print "git branch -d %s" % debian_branch
|
|
267 |
rc_version = "%src1" % version
|
|
268 |
new_develop_version = "%snext" % version
|
124 |
269 |
|
125 |
|
def start_common(self, mode, version):
|
126 |
|
if mode not in ["release", "hotfix"]:
|
127 |
|
raise ValueError("Unknown mode: %s" % mode)
|
128 |
|
repo = self.repo
|
129 |
|
upstream = "develop" if mode == "release" else "master"
|
130 |
|
debian = "debian-develop" if mode == "release" else "debian"
|
131 |
|
upstream_branch = "%s-%s" % (mode, version)
|
132 |
|
debian_branch = "debian-%s-%s" % (mode, version)
|
133 |
|
repo.git.checkout(upstream)
|
|
270 |
upstream_branch = self.get_branch("hotfix", version)
|
|
271 |
debian_branch = self.get_debian_branch("hotfix", version)
|
|
272 |
|
|
273 |
#create hotfix branch
|
134 |
274 |
repo.git.branch(upstream_branch, upstream)
|
135 |
275 |
self.new_branches.append(upstream_branch)
|
136 |
|
versioning.bump_version("%snext" % version)
|
137 |
276 |
repo.git.checkout(upstream_branch)
|
138 |
|
versioning.bump_version("%src1" % version)
|
|
277 |
versioning.bump_version(rc_version)
|
|
278 |
|
|
279 |
#create debian hotfix branch
|
139 |
280 |
repo.git.checkout(debian)
|
140 |
281 |
repo.git.branch(debian_branch, debian)
|
141 |
282 |
self.new_branches.append(debian_branch)
|
|
283 |
|
142 |
284 |
repo.git.checkout(upstream_branch)
|
143 |
285 |
repo.git.checkout(debian)
|
144 |
286 |
|
|
287 |
#bump develop version. Ask first or verify we have the same
|
|
288 |
#major.minornext?
|
|
289 |
#repo.git.checkout(upstream)
|
|
290 |
#versioning.bump_version(new_develop_version)
|
|
291 |
|
|
292 |
repo.git.checkout(upstream_branch)
|
|
293 |
|
|
294 |
@cleanup
|
|
295 |
def end_release(self, args):
|
|
296 |
version = args.version
|
|
297 |
repo = self.repo
|
|
298 |
master = "master"
|
|
299 |
debian_master = "debian"
|
|
300 |
upstream = "develop"
|
|
301 |
debian = "debian-develop"
|
|
302 |
upstream_branch = self.get_branch("release", version)
|
|
303 |
debian_branch = self.get_debian_branch("release", version)
|
|
304 |
tag = upstream_branch
|
|
305 |
debial_tag = "debian/" + tag
|
|
306 |
|
|
307 |
edit_action = partial(self.edit_changelog, upstream_branch, "develop")
|
|
308 |
self.check_edit_changelog(edit_action, args, default=True)
|
|
309 |
|
|
310 |
#merge to master
|
|
311 |
self._merge_branches(master, upstream_branch)
|
|
312 |
self._merge_branches(debian_master, debian_branch)
|
|
313 |
|
|
314 |
#create tags
|
|
315 |
repo.git.checkout(master)
|
|
316 |
repo.git.tag("%s" % tag)
|
|
317 |
repo.git.checkout(debian)
|
|
318 |
repo.git.tag("%s" % debian)
|
|
319 |
|
|
320 |
#merge release changes to upstream
|
|
321 |
self.merge_branches(upstream, upstream_branch, args, default=True)
|
|
322 |
self.merge_branches(debian, debian_branch, args, default=True)
|
|
323 |
|
|
324 |
repo.git.checkout(upstream)
|
|
325 |
|
|
326 |
branches = [upstream_branch, debian_branch]
|
|
327 |
self.cleanup_branches(branches, args, default=True)
|
|
328 |
|
|
329 |
@cleanup
|
|
330 |
def end_hotfix(self, args):
|
|
331 |
version = args.version
|
|
332 |
|
|
333 |
repo = self.repo
|
|
334 |
upstream = "master"
|
|
335 |
debian = "debian"
|
|
336 |
upstream_branch = self.get_branch("hotfix", version)
|
|
337 |
debian_branch = self.get_debian_branch("hotfix", version)
|
|
338 |
|
|
339 |
#create tags?
|
|
340 |
|
|
341 |
self._merge_branches(upstream, upstream_branch)
|
|
342 |
self._merge_branches(debian, debian_branch)
|
|
343 |
|
|
344 |
repo.git.checkout(upstream)
|
|
345 |
|
|
346 |
branches = [upstream_branch, debian_branch]
|
|
347 |
self.cleanup_branches(branches, args, default=True)
|
|
348 |
|
145 |
349 |
@cleanup
|
146 |
|
def start_feature(self, feature_name):
|
|
350 |
def start_feature(self, args):
|
|
351 |
feature_name = args.feature_name
|
147 |
352 |
repo = self.repo
|
148 |
353 |
feature_upstream = "feature-%s" % feature_name
|
149 |
354 |
feature_debian = "debian-%s" % feature_upstream
|
... | ... | |
153 |
358 |
self.new_branches.append(feature_debian)
|
154 |
359 |
|
155 |
360 |
@cleanup
|
156 |
|
def end_feature(self, feature_name):
|
|
361 |
def end_feature(self, args):
|
|
362 |
feature_name = args.feature_name
|
157 |
363 |
repo = self.repo
|
158 |
364 |
feature_upstream = "feature-%s" % feature_name
|
159 |
365 |
if not feature_upstream in repo.branches:
|
160 |
366 |
raise ValueError("Branch %s does not exist." % feature_upstream)
|
161 |
367 |
feature_debian = "debian-%s" % feature_upstream
|
162 |
|
action = partial(self.edit_changelog, feature_upstream, "develop")
|
163 |
|
query_action("Edit changelog", action = action)
|
164 |
|
# self.edit_changelog(feature_upstream)
|
165 |
|
repo.git.checkout("develop")
|
166 |
|
with conflicts():
|
167 |
|
repo.git.merge(feature_upstream)
|
168 |
|
repo.git.checkout("debian-develop")
|
|
368 |
|
|
369 |
edit_action = partial(self.edit_changelog, feature_upstream, "develop")
|
|
370 |
self.check_edit_changelog(edit_action, args, default=True)
|
|
371 |
|
|
372 |
#merge to develop
|
|
373 |
self._merge_branches("develop", feature_upstream)
|
169 |
374 |
if feature_debian in repo.branches:
|
170 |
|
with conflicts():
|
171 |
|
repo.git.merge(feature_debian)
|
|
375 |
self._merge_branches("debian-develop", feature_debian)
|
172 |
376 |
repo.git.checkout("develop")
|
173 |
|
print "To remove obsolete branches run:"
|
174 |
|
print "git branch -D %s" % feature_upstream
|
|
377 |
|
|
378 |
branches = [feature_upstream]
|
175 |
379 |
if feature_debian in repo.branches:
|
176 |
|
print "git branch -D %s" % feature_debian
|
|
380 |
branches.append(feature_debian)
|
|
381 |
self.cleanup_branches(branches, args, default=True)
|
177 |
382 |
|
178 |
|
def edit_changelog(self, branch, base_branch=None):
|
179 |
|
repo = self.repo
|
180 |
|
if not branch in repo.branches:
|
181 |
|
raise ValueError("Branch %s does not exist." % branch)
|
182 |
|
if base_branch and not base_branch in repo.branches:
|
183 |
|
raise ValueError("Branch %s does not exist." % base_branch)
|
184 |
383 |
|
185 |
|
repo.git.checkout(branch)
|
186 |
|
topdir = repo.working_dir
|
187 |
|
changelog = os.path.join(topdir, "Changelog")
|
|
384 |
def refhead(repo):
|
|
385 |
return repo.head.log[-1].newhexsha
|
188 |
386 |
|
189 |
|
lines = []
|
190 |
|
lines.append("#Changelog for %s\n" % branch)
|
191 |
|
if base_branch:
|
192 |
|
commits = repo.git.rev_list("%s..%s" % (base_branch, branch)).split("\n")
|
193 |
|
for c in commits:
|
194 |
|
commit = repo.commit(c)
|
195 |
|
lines.append(commit.message)
|
196 |
|
lines.append("\n")
|
197 |
387 |
|
198 |
|
f = open(changelog, 'rw+')
|
199 |
|
lines.extend(f.readlines())
|
200 |
|
f.seek(0)
|
201 |
|
f.truncate(0)
|
202 |
|
f.writelines(lines)
|
203 |
|
f.close()
|
204 |
|
|
|
388 |
def main():
|
|
389 |
parser = ArgumentParser(description="Devflow tool")
|
|
390 |
parser.add_argument('-V', '--version', action='version',
|
|
391 |
version='devflow-flow %s' % __version__)
|
|
392 |
parser.add_argument('-d', '--defaults', action='store_true', default=False,
|
|
393 |
help="Assume default on every choice, unless a value is provided")
|
205 |
394 |
|
206 |
|
editor = os.getenv('EDITOR')
|
207 |
|
if not editor:
|
208 |
|
editor = 'vim'
|
209 |
|
call("%s %s" % (editor, changelog))
|
210 |
|
repo.git.add(changelog)
|
211 |
|
repo.git.commit(m="Update changelog")
|
212 |
|
print "Updated changelog on branch %s" % branch
|
|
395 |
subparsers = parser.add_subparsers()
|
213 |
396 |
|
214 |
|
def end_common(self, mode, version):
|
215 |
|
pass
|
216 |
397 |
|
|
398 |
init_parser = subparsers.add_parser('init',
|
|
399 |
help="Initialize a new devflow repo")
|
|
400 |
init_parser.add_argument('-m', '--master', type=str, nargs='?',
|
|
401 |
help="Master branch")
|
|
402 |
init_parser.add_argument('-d', '--develop', type=str, nargs='?',
|
|
403 |
help="Develop branch")
|
|
404 |
init_parser.set_defaults(func='init_repo')
|
217 |
405 |
|
218 |
|
def refhead(repo):
|
219 |
|
return repo.head.log[-1].newhexsha
|
220 |
406 |
|
|
407 |
feature_parser = subparsers.add_parser('feature', help="Feature options")
|
|
408 |
feature_subparsers = feature_parser.add_subparsers()
|
|
409 |
|
|
410 |
feature_start_parser = feature_subparsers.add_parser('start',
|
|
411 |
help="Start a new feature")
|
|
412 |
feature_start_parser.set_defaults(func='start_feature')
|
|
413 |
feature_start_parser.add_argument('feature_name', type=str,
|
|
414 |
help="Name of the feature")
|
|
415 |
|
|
416 |
feature_finish_parser = feature_subparsers.add_parser('finish',
|
|
417 |
help="Finish a feature")
|
|
418 |
feature_finish_parser.set_defaults(func='end_feature')
|
|
419 |
feature_finish_parser.add_argument('feature_name', type=str,
|
|
420 |
help="Name of the feature")
|
|
421 |
feature_finish_parser.add_argument('--no-edit-changelog',
|
|
422 |
action='store_const', const=False, dest='edit_changelog',
|
|
423 |
help="Do not edit the changelog")
|
|
424 |
feature_finish_parser.add_argument('--no-cleanup', action='store_const',
|
|
425 |
const=True, dest='cleanup', help="Do not cleanup branches")
|
|
426 |
|
|
427 |
release_parser = subparsers.add_parser('release', help="release options")
|
|
428 |
release_subparsers = release_parser.add_subparsers()
|
|
429 |
|
|
430 |
|
|
431 |
release_start_parser = release_subparsers.add_parser('start',
|
|
432 |
help="Start a new release")
|
|
433 |
release_start_parser.add_argument('--version', type=str,
|
|
434 |
help="Version of the release")
|
|
435 |
release_start_parser.add_argument('--develop-version', type=str,
|
|
436 |
help="New develop version")
|
|
437 |
release_start_parser.set_defaults(func='start_release')
|
|
438 |
|
|
439 |
|
|
440 |
release_finish_parser = release_subparsers.add_parser('finish',
|
|
441 |
help="Finish a release")
|
|
442 |
release_finish_parser.add_argument('version', type=str,
|
|
443 |
help="Version of the release")
|
|
444 |
release_finish_parser.add_argument('--no-edit-changelog',
|
|
445 |
action='store_const', const=False, dest='edit_changelog',
|
|
446 |
help="Do not edit the changelog")
|
|
447 |
release_finish_parser.add_argument('--no-cleanup', action='store_const',
|
|
448 |
const=True, dest='cleanup', help="Do not cleanup branches")
|
|
449 |
|
|
450 |
release_finish_parser.set_defaults(func='end_release')
|
|
451 |
|
|
452 |
hotfix_parser = subparsers.add_parser('hotfix', help="hotfix options")
|
|
453 |
hotfix_subparsers = hotfix_parser.add_subparsers()
|
|
454 |
|
|
455 |
|
|
456 |
hotfix_start_parser = hotfix_subparsers.add_parser('start',
|
|
457 |
help="Start a new hotfix")
|
|
458 |
hotfix_start_parser.add_argument('--version', type=str,
|
|
459 |
help="Version of the hotfix")
|
|
460 |
hotfix_start_parser.add_argument('--develop-version', type=str,
|
|
461 |
help="New develop version")
|
|
462 |
hotfix_start_parser.set_defaults(func='start_hotfix')
|
|
463 |
|
|
464 |
|
|
465 |
hotfix_finish_parser = hotfix_subparsers.add_parser('finish',
|
|
466 |
help="Finish a hotfix")
|
|
467 |
hotfix_finish_parser.add_argument('version', type=str,
|
|
468 |
help="Version of the hotfix")
|
|
469 |
hotfix_finish_parser.add_argument('--no-edit-changelog',
|
|
470 |
action='store_const', const=False, dest='edit_changelog',
|
|
471 |
help="Do not edit the changelog")
|
|
472 |
hotfix_finish_parser.add_argument('--no-cleanup', action='store_const',
|
|
473 |
const=True, dest='cleanup', help="Do not cleanup branches")
|
|
474 |
hotfix_finish_parser.set_defaults(func='end_hotfix')
|
|
475 |
|
|
476 |
|
|
477 |
|
|
478 |
args = parser.parse_args()
|
221 |
479 |
|
222 |
|
def main():
|
223 |
|
HELP_MSG = "usage: %prog mode=[release|hotfix|feature]"\
|
224 |
|
" [version|name]"
|
225 |
|
parser = OptionParser(usage=HELP_MSG,
|
226 |
|
version="devflow-flow %s" % __version__,
|
227 |
|
add_help_option=True)
|
228 |
|
options, args = parser.parse_args()
|
229 |
|
if len(args) != 3:
|
230 |
|
parser.error("Invalid number of arguments.")
|
231 |
|
mode, action, version = args
|
232 |
480 |
gm = GitManager()
|
233 |
|
func = "%s_%s" % (action, mode)
|
234 |
|
try:
|
235 |
|
getattr(gm, func)(version)
|
236 |
|
except AttributeError:
|
237 |
|
parser.error("Invalid arguments.")
|
|
481 |
getattr(gm, args.func)(args)
|
|
482 |
|
238 |
483 |
|
239 |
484 |
if __name__ == "__main__":
|
240 |
485 |
main()
|