Extend cherry-pick script with the ability to promote -dev versions to stable
Change-Id: I4969652078339cdee32881d6392e466c1f56fe85
diff --git a/tools/cherry-pick.py b/tools/cherry-pick.py
index b28441a..7bc7c8c 100755
--- a/tools/cherry-pick.py
+++ b/tools/cherry-pick.py
@@ -15,6 +15,23 @@
VERSION_PREFIX = 'String LABEL = "'
+def sed(old, new, file):
+ subprocess.run(['sed', '-i', 's/%s/%s/' % (old, new), file])
+
+
+def git_new_branch(name, upstream=None):
+ cmd = ['git', 'new-branch', name]
+ if upstream:
+ cmd += ['--upstream', upstream]
+ else:
+ cmd += ['--upstream-current']
+ subprocess.run(cmd)
+
+
+def git_commit(message):
+ subprocess.run(['git', 'commit', '-a', '-m', message])
+
+
def parse_options():
parser = argparse.ArgumentParser(description='Release r8')
parser.add_argument('--branch',
@@ -32,10 +49,6 @@
default=False,
action='store_true',
help='Do not upload to Gerrit')
- parser.add_argument('hashes',
- metavar='<hash>',
- nargs='+',
- help='Hashed to merge')
parser.add_argument('--remote',
default='origin',
help='The remote name (defaults to "origin")')
@@ -54,15 +67,36 @@
default=False,
action='store_true',
help='Send Gerrit review request right away')
+ exclusive = parser.add_mutually_exclusive_group(required=True)
+ exclusive.add_argument('hashes',
+ default=[],
+ metavar='<hash>',
+ nargs='*',
+ help='Hashes to merge')
+ exclusive.add_argument('--promote-dev',
+ '--promote_dev',
+ default=False,
+ action='store_true',
+ help='Promote a -dev branch to stable')
return parser.parse_args()
+def version_from_version_file():
+ for line in open(VERSION_FILE, 'r'):
+ index = line.find(VERSION_PREFIX)
+ if index > 0:
+ index += len(VERSION_PREFIX)
+ subline = line[index:]
+ return subline[:subline.index('"')]
+ return "unknown"
+
+
def run(args, branch):
if args.current_checkout:
for i in range(len(args.hashes) + 1):
local_branch_name = 'cherry-%s-%d' % (branch, i + 1)
print('Deleting branch %s' % local_branch_name)
- subprocess.run(['git', 'branch', local_branch_name, '-D'])
+ subprocess.run(['git', '--delete', '--force', 'branch', local_branch_name])
bugs = set()
@@ -71,38 +105,24 @@
local_branch_name = 'cherry-%s-%d' % (branch, count)
print('Cherry-picking %s in %s' % (hash, local_branch_name))
if count == 1:
- subprocess.run([
- 'git', 'new-branch', local_branch_name, '--upstream',
- '%s/%s' % (args.remote, branch)
- ])
+ git_new_branch(local_branch_name, '%s/%s' % (args.remote, branch))
else:
- subprocess.run(['git', 'new-branch', local_branch_name, '--upstream-current'])
+ git_new_branch(local_branch_name)
subprocess.run(['git', 'cherry-pick', hash])
confirm_and_upload(local_branch_name, args, bugs)
count = count + 1
local_branch_name = 'cherry-%s-%d' % (branch, count)
- subprocess.run(['git', 'new-branch', local_branch_name, '--upstream-current'])
+ git_new_branch(local_branch_name)
- old_version = 'unknown'
- for line in open(VERSION_FILE, 'r'):
- index = line.find(VERSION_PREFIX)
- if index > 0:
- index += len(VERSION_PREFIX)
- subline = line[index:]
- old_version = subline[:subline.index('"')]
- break
-
+ old_version = version_from_version_file()
new_version = 'unknown'
if old_version.find('.') > 0 and old_version.find('-') == -1:
split_version = old_version.split('.')
new_version = '.'.join(split_version[:-1] +
[str(int(split_version[-1]) + 1)])
- subprocess.run([
- 'sed', '-i',
- 's/%s/%s/' % (old_version, new_version), VERSION_FILE
- ])
+ sed(old_version, new_version, VERSION_FILE)
else:
editor = os.environ.get('VISUAL')
if not editor:
@@ -119,7 +139,7 @@
for bug in sorted(bugs):
message += 'Bug: b/%s\n' % bug
- subprocess.run(['git', 'commit', '-a', '-m', message])
+ git_commit(message)
confirm_and_upload(branch, args, None)
if not args.current_checkout and not args.yes:
while True:
@@ -180,12 +200,55 @@
print('Not uploading, upload command was "%s"' % cmd)
+def promote_dev(args):
+ if len(args.branch) > 1:
+ print("Only one branch can be specified for --promote-dev.")
+ sys.exit(1)
+ branch = args.branch[0]
+
+ if args.current_checkout:
+ print("--current-checkout not supported for --promote-dev.")
+ sys.exit(1)
+
+ with utils.TempDir() as temp:
+ print("Performing promote dev in %s" % temp)
+ subprocess.check_call(['git', 'clone', utils.REPO_SOURCE, temp])
+ with utils.ChangedWorkingDirectory(temp):
+ local_branch_name = 'promote-dev-%s' % branch
+ subprocess.run(['git', 'branch', local_branch_name, '-D'])
+ git_new_branch(local_branch_name, '%s/%s' % (args.remote, branch))
+
+ dev_version = version_from_version_file()
+ print(dev_version)
+ if not dev_version.endswith('-dev'):
+ print("Not a -dev version branch")
+ sys.exit(1)
+ version = dev_version[0:len(dev_version) - 4]
+
+ print("Promoting %s to %s" % (dev_version, version))
+ sed(dev_version, version, VERSION_FILE)
+
+ message = ('Version %s\n\n'
+ 'Promoting version %s to version %s' % (version, dev_version, version))
+
+ git_commit(message)
+ confirm_and_upload(branch, args, None)
+
+
def main():
args = parse_options()
+
if len(args.branch) == 0:
print("No branches specified.")
sys.exit(1)
+ if args.promote_dev:
+ promote_dev(args)
+ sys.exit(0)
+
+ # At least one hash even though it is optional, as it is in an exclusive group
+ # with --promote-dev which is checked above.
+ assert len(args.hashes) > 0
branches = args.branch
args.branch = None
for branch in branches: