You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
depot_tools/git-try.py

185 lines
5.2 KiB
Python

#!/usr/bin/python
# Repo lives in ~evanm/projects/git-try -- feel free to send patches.
import getpass
import optparse
import os
import subprocess
import tempfile
import traceback
import urllib
import sys
def Backquote(cmd):
"""Like running `cmd` in a shell script."""
return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0].strip()
def GetTryServerConfig():
"""Returns the dictionary of try server options or None if they
cannot be found."""
script_path = 'tools/tryserver/tryserver.py'
root_dir = Backquote(['git', 'rev-parse', '--show-cdup'])
try:
script_file = open(os.path.join(root_dir, script_path))
except IOError:
return None
locals = {}
try:
exec(script_file, locals)
except Exception, e:
return None
return locals
def GetBranchName():
"""Return name of current git branch."""
branch = Backquote(['git', 'symbolic-ref', 'HEAD'])
if not branch.startswith('refs/heads/'):
raise "Couldn't figure out branch name"
branch = branch[len('refs/heads/'):]
return branch
def GetPatchName():
"""Construct a name for this patch."""
# TODO: perhaps include the hash of the current commit, to distinguish
# patches?
return GetBranchName()
def GetRevision():
"""Get the latest Subversion revision number."""
for line in Backquote(['git', 'svn', 'info']).split('\n'):
if line.startswith('Revision:'):
return line[len('Revision:'):].strip()
raise "Couldn't figure out latest revision"
def GetRietveldIssueNumber():
return Backquote(['git', 'config',
'branch.%s.rietveldissue' % GetBranchName()])
def GetRietveldPatchsetNumber():
return Backquote(['git', 'config',
'branch.%s.rietveldpatchset' % GetBranchName()])
def GetMungedDiff(branch):
"""Get the diff we'll send to the try server. We munge paths to match svn."""
# Make the following changes:
# - Prepend "src/" to paths as svn is expecting
# - In the case of added files, replace /dev/null with the path to the file
# being added.
output = []
if not branch:
# Try to guess the upstream branch.
branch = Backquote(['git', 'cl', 'upstream'])
diff = subprocess.Popen(['git', 'diff-tree', '-p', '--no-prefix',
branch, 'HEAD'],
stdout=subprocess.PIPE).stdout.readlines()
for i in range(len(diff)):
line = diff[i]
if line.startswith('--- /dev/null'):
line = '--- %s' % diff[i+1][4:]
elif line.startswith('--- ') or line.startswith('+++ '):
line = line[0:4] + 'src/' + line[4:]
output.append(line)
return ''.join(output)
def GetEmail():
# TODO: check for errors here?
return Backquote(['git', 'config', 'user.email'])
def TryChange(args):
"""Put a patch on the try server using SVN."""
# TODO: figure out a better way to load trychange
script_path = '../depot_tools/release'
root_dir = Backquote(['git', 'rev-parse', '--show-cdup'])
sys.path.append(os.path.join(root_dir, script_path))
import trychange
trychange.checkout_root = os.path.abspath(root_dir)
trychange.TryChange(args, None, False)
def WriteTryDiffHTTP(config, patch_name, diff, options):
"""Put a patch on the try server."""
params = {
'user': getpass.getuser(),
'name': patch_name,
'patch': diff
}
if options.bot:
params['bot'] = options.bot
if options.clobber:
params['clobber'] = 'true'
url = 'http://%s:%s/send_try_patch' % (config['try_server_http_host'],
config['try_server_http_port'])
connection = urllib.urlopen(url, urllib.urlencode(params))
response = connection.read()
if (response != 'OK'):
print "Error posting to", url
print response
assert False
if __name__ == '__main__':
parser = optparse.OptionParser(
usage='git try [branch]',
description='Upload the current diff of branch...HEAD to the try server.')
parser.add_option("-b", "--bot",
help="Force the use of a specific build slave (eg mac, "
"win, or linux)")
parser.add_option("-c", "--clobber", action="store_true",
help="Make the try run use be a clobber build")
(options, args) = parser.parse_args(sys.argv)
branch = None
if len(args) > 1:
branch = args[1]
patch_name = GetPatchName()
diff = GetMungedDiff(branch)
# Send directly to try server if we can parse the config, otherwise
# upload via SVN.
config = GetTryServerConfig()
if config is not None:
print "Sending %s using HTTP..." % patch_name
WriteTryDiffHTTP(config=config, patch_name=patch_name, diff=diff,
options=options)
else:
print "Sending %s using SVN..." % patch_name
# Write the diff out to a temporary file
diff_file = tempfile.NamedTemporaryFile()
diff_file.write(diff)
diff_file.flush()
email = GetEmail()
user = email.partition('@')[0]
args = [
'--use_svn',
'--svn_repo', 'svn://svn.chromium.org/chrome-try/try',
'-u', user,
'-e', email,
'-n', patch_name,
'-r', GetRevision(),
'--diff', diff_file.name,
]
if GetRietveldPatchsetNumber():
args.extend([
'--issue', GetRietveldIssueNumber(),
'--patchset', GetRietveldPatchsetNumber(),
])
TryChange(args=args)