blob: 0bcb9fd926737e745fbca5b8d1408ad8f05b1f2d [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Upload a cherry pick CL to rietveld."""
import argparse
import md5
import subprocess2
import sys
from git_cl import Changelist
from git_common import config, run
from third_party.upload import EncodeMultipartFormData, GitVCS
from rietveld import Rietveld
def cherry_pick(target_branch, commit):
"""Attempt to upload a cherry pick CL to rietveld.
Args:
target_branch: The branch to cherry pick onto.
commit: The git hash of the commit to cherry pick.
"""
author = config('user.email')
description = '%s\n\n(cherry picked from commit %s)\n' % (
run('show', '--pretty=%B', '--quiet', commit), commit)
parent = run('show', '--pretty=%P', '--quiet', commit)
print 'Found parent revision:', parent
class Options(object):
def __init__(self):
self.emulate_svn_auto_props = False
content_type, payload = EncodeMultipartFormData([
('base', '%s@%s' % (Changelist().GetRemoteUrl(), target_branch)),
('cc', config('rietveld.cc')),
('content_upload', '1'),
('description', description),
('project', '%s@%s' % (config('rietveld.project'), target_branch)),
('subject', description.splitlines()[0]),
('user', author),
], [
('data', 'data.diff', GitVCS(Options()).PostProcessDiff(
run('diff', parent, commit))),
])
rietveld = Rietveld(config('rietveld.server'), author, None)
# pylint: disable=W0212
output = rietveld._send(
'/upload',
payload=payload,
content_type=content_type,
).splitlines()
# If successful, output will look like:
# Issue created. URL: https://codereview.chromium.org/1234567890
# 1
# 10001 some/path/first.file
# 10002 some/path/second.file
# 10003 some/path/third.file
if output[0].startswith('Issue created. URL: '):
print output[0]
issue = output[0].rsplit('/', 1)[-1]
patchset = output[1]
files = output[2:]
for f in files:
file_id, filename = f.split()
mode = 'M'
try:
content = run('show', '%s:%s' % (parent, filename))
except subprocess2.CalledProcessError:
# File didn't exist in the parent revision.
content = ''
mode = 'A'
content_type, payload = EncodeMultipartFormData([
('checksum', md5.md5(content).hexdigest()),
('filename', filename),
('is_current', 'False'),
('status', mode),
], [
('data', filename, content),
])
# pylint: disable=W0212
print ' Uploading base file for %s:' % filename, rietveld._send(
'/%s/upload_content/%s/%s' % (issue, patchset, file_id),
payload=payload,
content_type=content_type,
)
try:
content = run('show', '%s:%s' % (commit, filename))
except subprocess2.CalledProcessError:
# File no longer exists in the new commit.
content = ''
mode = 'D'
content_type, payload = EncodeMultipartFormData([
('checksum', md5.md5(content).hexdigest()),
('filename', filename),
('is_current', 'True'),
('status', mode),
], [
('data', filename, content),
])
# pylint: disable=W0212
print ' Uploading %s:' % filename, rietveld._send(
'/%s/upload_content/%s/%s' % (issue, patchset, file_id),
payload=payload,
content_type=content_type,
)
# pylint: disable=W0212
print 'Finalizing upload:', rietveld._send('/%s/upload_complete/1' % issue)
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'--branch',
'-b',
help='The upstream branch to cherry pick to.',
metavar='<branch>',
required=True,
)
parser.add_argument(
'commit',
help='SHA to cherry pick.',
metavar='<commit>',
)
args = parser.parse_args()
cherry_pick(args.branch, args.commit)
return 0
if __name__ == '__main__':
try:
sys.exit(main())
except KeyboardInterrupt:
sys.stderr.write('interrupted\n')
sys.exit(1)