Update upload.py @ fae51921ad9d

This version of upload.py is slightly less annoying, it won't cancel out if no
patchset title is provided and disable colors all the time.

R=cmp@chromium.org
BUG=
TEST=

Review URL: http://codereview.chromium.org/9233057

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@121826 0039d316-1c4b-4281-b951-d872f2087c98
experimental/szager/collated-output
maruel@chromium.org 13 years ago
parent 78c4b98fc3
commit 71e12a9e41

@ -285,7 +285,6 @@ class ChangeInfo(object):
self.issue = int(issue) self.issue = int(issue)
self.patchset = int(patchset) self.patchset = int(patchset)
self._description = None self._description = None
self._subject = None
self._reviewers = None self._reviewers = None
self._set_description(description) self._set_description(description)
if files is None: if files is None:
@ -310,19 +309,11 @@ class ChangeInfo(object):
parsed_lines = [] parsed_lines = []
reviewers_re = re.compile(REVIEWERS_REGEX) reviewers_re = re.compile(REVIEWERS_REGEX)
reviewers = '' reviewers = ''
subject = ''
for l in description.splitlines(): for l in description.splitlines():
if not subject:
subject = l
matched_reviewers = reviewers_re.match(l) matched_reviewers = reviewers_re.match(l)
if matched_reviewers: if matched_reviewers:
reviewers = matched_reviewers.group(1).split(',') reviewers = matched_reviewers.group(1).split(',')
parsed_lines.append(l) parsed_lines.append(l)
if len(subject) > 100:
subject = subject[:97] + '...'
self._subject = subject
self._reviewers = reviewers self._reviewers = reviewers
self._description = '\n'.join(parsed_lines) self._description = '\n'.join(parsed_lines)
@ -332,10 +323,6 @@ class ChangeInfo(object):
def reviewers(self): def reviewers(self):
return self._reviewers return self._reviewers
@property
def subject(self):
return self._subject
def NeedsUpload(self): def NeedsUpload(self):
return self.needs_upload return self.needs_upload
@ -859,18 +846,14 @@ def CMDupload(change_info, args):
desc_file = None desc_file = None
try: try:
if change_info.issue: # Uploading a new patchset. if change_info.issue:
found_message = False # Uploading a new patchset.
for arg in args:
if arg.startswith("--message") or arg.startswith("-m"):
found_message = True
break
if not found_message:
upload_arg.append("--message=''")
upload_arg.append("--issue=%d" % change_info.issue) upload_arg.append("--issue=%d" % change_info.issue)
else: # First time we upload.
if not any(i.startswith('--message') or i.startswith('-m') for i in args):
upload_arg.append('--title= ')
else:
# First time we upload.
handle, desc_file = tempfile.mkstemp(text=True) handle, desc_file = tempfile.mkstemp(text=True)
os.write(handle, change_info.description) os.write(handle, change_info.description)
os.close(handle) os.close(handle)
@ -888,9 +871,7 @@ def CMDupload(change_info, args):
cc_list = ','.join(filter(None, [cc_list] + watchers)) cc_list = ','.join(filter(None, [cc_list] + watchers))
if cc_list: if cc_list:
upload_arg.append("--cc=" + cc_list) upload_arg.append("--cc=" + cc_list)
upload_arg.append("--description_file=%s" % desc_file) upload_arg.append("--file=%s" % desc_file)
if change_info.subject:
upload_arg.append("--message=" + change_info.subject)
if GetCodeReviewSetting("PRIVATE") == "True": if GetCodeReviewSetting("PRIVATE") == "True":
upload_arg.append("--private") upload_arg.append("--private")

@ -626,47 +626,43 @@ def GetCodereviewSettingsInteractively():
class ChangeDescription(object): class ChangeDescription(object):
"""Contains a parsed form of the change description.""" """Contains a parsed form of the change description."""
def __init__(self, subject, log_desc, reviewers): def __init__(self, log_desc, reviewers):
self.subject = subject
self.log_desc = log_desc self.log_desc = log_desc
self.reviewers = reviewers self.reviewers = reviewers
self.description = self.log_desc self.description = self.log_desc
def Update(self): def Prompt(self):
initial_text = """# Enter a description of the change. content = """# Enter a description of the change.
# This will displayed on the codereview site. # This will displayed on the codereview site.
# The first line will also be used as the subject of the review. # The first line will also be used as the subject of the review.
""" """
initial_text += self.description content += self.description
if ('\nR=' not in self.description and if ('\nR=' not in self.description and
'\nTBR=' not in self.description and '\nTBR=' not in self.description and
self.reviewers): self.reviewers):
initial_text += '\nR=' + self.reviewers content += '\nR=' + self.reviewers
if '\nBUG=' not in self.description: if '\nBUG=' not in self.description:
initial_text += '\nBUG=' content += '\nBUG='
if '\nTEST=' not in self.description: if '\nTEST=' not in self.description:
initial_text += '\nTEST=' content += '\nTEST='
initial_text = initial_text.rstrip('\n') + '\n' content = content.rstrip('\n') + '\n'
content = gclient_utils.RunEditor(initial_text, True) content = gclient_utils.RunEditor(content, True)
if not content: if not content:
DieWithError('Running editor failed') DieWithError('Running editor failed')
content = re.compile(r'^#.*$', re.MULTILINE).sub('', content).strip() content = re.compile(r'^#.*$', re.MULTILINE).sub('', content).strip()
if not content: if not content.strip():
DieWithError('No CL description, aborting') DieWithError('No CL description, aborting')
self.ParseDescription(content) self.description = content
def ParseDescription(self, description): def ParseDescription(self):
"""Updates the list of reviewers and subject from the description.""" """Updates the list of reviewers and subject from the description."""
if not description: self.description = self.description.strip('\n') + '\n'
self.description = description
return
self.description = description.strip('\n') + '\n'
self.subject = description.split('\n', 1)[0]
# Retrieves all reviewer lines # Retrieves all reviewer lines
regexp = re.compile(r'^\s*(TBR|R)=(.+)$', re.MULTILINE) regexp = re.compile(r'^\s*(TBR|R)=(.+)$', re.MULTILINE)
self.reviewers = ','.join( reviewers = ','.join(
i.group(2).strip() for i in regexp.finditer(self.description)) i.group(2).strip() for i in regexp.finditer(self.description))
if reviewers:
self.reviewers = reviewers
def IsEmpty(self): def IsEmpty(self):
return not self.description return not self.description
@ -890,12 +886,11 @@ def GerritUpload(options, args, cl):
if options.target_branch: if options.target_branch:
branch = options.target_branch branch = options.target_branch
log_desc = CreateDescriptionFromLog(args) log_desc = options.message or CreateDescriptionFromLog(args)
if options.reviewers: if options.reviewers:
log_desc += '\nR=' + options.reviewers log_desc += '\nR=' + options.reviewers
change_desc = ChangeDescription(options.message, log_desc, change_desc = ChangeDescription(log_desc, options.reviewers)
options.reviewers) change_desc.ParseDescription()
change_desc.ParseDescription(log_desc)
if change_desc.IsEmpty(): if change_desc.IsEmpty():
print "Description is empty; aborting." print "Description is empty; aborting."
return 1 return 1
@ -928,9 +923,6 @@ def RietveldUpload(options, args, cl):
upload_args.extend(['--server', cl.GetRietveldServer()]) upload_args.extend(['--server', cl.GetRietveldServer()])
if options.emulate_svn_auto_props: if options.emulate_svn_auto_props:
upload_args.append('--emulate_svn_auto_props') upload_args.append('--emulate_svn_auto_props')
if options.from_logs and not options.message:
print 'Must set message for subject line if using desc_from_logs'
return 1
change_desc = None change_desc = None
@ -941,18 +933,17 @@ def RietveldUpload(options, args, cl):
print ("This branch is associated with issue %s. " print ("This branch is associated with issue %s. "
"Adding patch to that issue." % cl.GetIssue()) "Adding patch to that issue." % cl.GetIssue())
else: else:
log_desc = CreateDescriptionFromLog(args) message = options.message or CreateDescriptionFromLog(args)
change_desc = ChangeDescription(options.message, log_desc, change_desc = ChangeDescription(message, options.reviewers)
options.reviewers) if not options.force:
if not options.from_logs: change_desc.Prompt()
change_desc.Update() change_desc.ParseDescription()
if change_desc.IsEmpty(): if change_desc.IsEmpty():
print "Description is empty; aborting." print "Description is empty; aborting."
return 1 return 1
upload_args.extend(['--message', change_desc.subject]) upload_args.extend(['--message', change_desc.description])
upload_args.extend(['--description', change_desc.description])
if change_desc.reviewers: if change_desc.reviewers:
upload_args.extend(['--reviewers', change_desc.reviewers]) upload_args.extend(['--reviewers', change_desc.reviewers])
if options.send_mail: if options.send_mail:

@ -187,7 +187,6 @@ class ChangeInfoUnittest(GclTestsBase):
'UpdateRietveldDescription', 'UpdateRietveldDescription',
'description', 'issue', 'name', 'description', 'issue', 'name',
'needs_upload', 'patch', 'patchset', 'reviewers', 'rietveld', 'needs_upload', 'patch', 'patchset', 'reviewers', 'rietveld',
'subject',
] ]
# If this test fails, you should add the relevant test. # If this test fails, you should add the relevant test.
self.compareMembers( self.compareMembers(
@ -314,7 +313,7 @@ class CMDuploadUnittest(GclTestsBase):
gcl.GenerateDiff(files) gcl.GenerateDiff(files)
gcl.upload.RealMain(['upload.py', '-y', '--server=https://my_server', gcl.upload.RealMain(['upload.py', '-y', '--server=https://my_server',
'-r', 'georges@example.com', '-r', 'georges@example.com',
'--message=\'\'', '--issue=1'], '--issue=1', '--title= '],
change_info.patch).AndReturn(("1", change_info.patch).AndReturn(("1",
"2")) "2"))
change_info.GetLocalRoot().AndReturn('proout') change_info.GetLocalRoot().AndReturn('proout')
@ -358,7 +357,7 @@ class CMDuploadUnittest(GclTestsBase):
gcl.GenerateDiff(change_info.GetFileNames()) gcl.GenerateDiff(change_info.GetFileNames())
gcl.upload.RealMain( gcl.upload.RealMain(
[ 'upload.py', '-y', '--server=https://my_server', '--server=a', [ 'upload.py', '-y', '--server=https://my_server', '--server=a',
'--description_file=descfile', '--message=deescription'], '--file=descfile'],
change_info.patch).AndReturn(("1", "2")) change_info.patch).AndReturn(("1", "2"))
gcl.os.remove('descfile') gcl.os.remove('descfile')
change_info.SendToRietveld("/lint/issue%s_%s" % ('1', '2'), timeout=1) change_info.SendToRietveld("/lint/issue%s_%s" % ('1', '2'), timeout=1)
@ -398,9 +397,9 @@ class CMDuploadUnittest(GclTestsBase):
gcl.os.getcwd().AndReturn('somewhere') gcl.os.getcwd().AndReturn('somewhere')
gcl.os.chdir(change_info.GetLocalRoot()) gcl.os.chdir(change_info.GetLocalRoot())
gcl.GenerateDiff(change_info.GetFileNames()) gcl.GenerateDiff(change_info.GetFileNames())
gcl.upload.RealMain(['upload.py', '-y', '--server=https://my_server', gcl.upload.RealMain(
"--description_file=descfile", ['upload.py', '-y', '--server=https://my_server', "--file=descfile" ],
"--message=deescription"], change_info.patch).AndReturn(("1", "2")) change_info.patch).AndReturn(("1", "2"))
gcl.os.remove('descfile') gcl.os.remove('descfile')
change_info.SendToRietveld("/lint/issue%s_%s" % ('1', '2'), timeout=1) change_info.SendToRietveld("/lint/issue%s_%s" % ('1', '2'), timeout=1)
gcl.os.chdir('somewhere') gcl.os.chdir('somewhere')
@ -457,7 +456,7 @@ class CMDuploadUnittest(GclTestsBase):
gcl.GenerateDiff(files) gcl.GenerateDiff(files)
gcl.upload.RealMain(['upload.py', '-y', '--server=https://my_server', gcl.upload.RealMain(['upload.py', '-y', '--server=https://my_server',
'--reviewers=georges@example.com', '--reviewers=georges@example.com',
'--message=\'\'', '--issue=1'], '--issue=1', '--title= '],
change_info.patch).AndReturn(("1", "2")) change_info.patch).AndReturn(("1", "2"))
change_info.Save() change_info.Save()
change_info.PrimeLint() change_info.PrimeLint()
@ -486,7 +485,7 @@ class CMDuploadUnittest(GclTestsBase):
gcl.GenerateDiff(change_info.GetFileNames()) gcl.GenerateDiff(change_info.GetFileNames())
gcl.upload.RealMain(['upload.py', '-y', '--server=https://my_server', gcl.upload.RealMain(['upload.py', '-y', '--server=https://my_server',
'--reviewers=foo@example.com,bar@example.com', '--reviewers=foo@example.com,bar@example.com',
'--message=\'\'', '--issue=1'], '--issue=1', '--title= '],
change_info.patch).AndReturn(("1", "2")) change_info.patch).AndReturn(("1", "2"))
change_info.Save() change_info.Save()
change_info.PrimeLint() change_info.PrimeLint()

@ -210,12 +210,10 @@ class TestGitCl(TestCase):
@staticmethod @staticmethod
def _cmd_line(description, args): def _cmd_line(description, args):
"""Returns the upload command line passed to upload.RealMain().""" """Returns the upload command line passed to upload.RealMain()."""
msg = description.split('\n', 1)[0]
return [ return [
'upload', '--assume_yes', '--server', 'upload', '--assume_yes', '--server',
'https://codereview.example.com', 'https://codereview.example.com',
'--message', msg, '--message', description
'--description', description
] + args + [ ] + args + [
'--cc', 'joe@example.com', '--cc', 'joe@example.com',
'master...' 'master...'

@ -1,4 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding: utf-8
# #
# Copyright 2007 Google Inc. # Copyright 2007 Google Inc.
# #
@ -215,7 +216,7 @@ class AbstractRpcServer(object):
def _CreateRequest(self, url, data=None): def _CreateRequest(self, url, data=None):
"""Creates a new urllib request.""" """Creates a new urllib request."""
logging.debug("Creating request for: '%s' with payload:\n%s", url, data) logging.debug("Creating request for: '%s' with payload:\n%s", url, data)
req = urllib2.Request(url, data=data) req = urllib2.Request(url, data=data, headers={"Accept": "text/plain"})
if self.host_override: if self.host_override:
req.add_header("Host", self.host_override) req.add_header("Host", self.host_override)
for key, value in self.extra_headers.iteritems(): for key, value in self.extra_headers.iteritems():
@ -399,14 +400,13 @@ class AbstractRpcServer(object):
raise raise
elif e.code == 401 or e.code == 302: elif e.code == 401 or e.code == 302:
self._Authenticate() self._Authenticate()
## elif e.code >= 500 and e.code < 600:
## # Server Error - try again.
## continue
elif e.code == 301: elif e.code == 301:
# Handle permanent redirect manually. # Handle permanent redirect manually.
url = e.info()["location"] url = e.info()["location"]
url_loc = urlparse.urlparse(url) url_loc = urlparse.urlparse(url)
self.host = '%s://%s' % (url_loc[0], url_loc[1]) self.host = '%s://%s' % (url_loc[0], url_loc[1])
elif e.code >= 500:
ErrorExit(e.read())
else: else:
raise raise
finally: finally:
@ -532,14 +532,13 @@ group.add_option("--account_type", action="store", dest="account_type",
"valid choices are 'GOOGLE' and 'HOSTED').")) "valid choices are 'GOOGLE' and 'HOSTED')."))
# Issue # Issue
group = parser.add_option_group("Issue options") group = parser.add_option_group("Issue options")
group.add_option("-d", "--description", action="store", dest="description", group.add_option("-t", "--title", action="store", dest="title",
metavar="DESCRIPTION", default=None, help="New issue subject or new patch set title")
help="Optional description when creating an issue.") group.add_option("-m", "--message", action="store", dest="message",
group.add_option("-f", "--description_file", action="store",
dest="description_file", metavar="DESCRIPTION_FILE",
default=None, default=None,
help="Optional path of a file that contains " help="New issue description or new patch set message")
"the description when creating an issue.") group.add_option("-F", "--file", action="store", dest="file",
default=None, help="Read the message above from file.")
group.add_option("-r", "--reviewers", action="store", dest="reviewers", group.add_option("-r", "--reviewers", action="store", dest="reviewers",
metavar="REVIEWERS", default=None, metavar="REVIEWERS", default=None,
help="Add reviewers (comma separated email addresses).") help="Add reviewers (comma separated email addresses).")
@ -551,10 +550,6 @@ group.add_option("--private", action="store_true", dest="private",
help="Make the issue restricted to reviewers and those CCed") help="Make the issue restricted to reviewers and those CCed")
# Upload options # Upload options
group = parser.add_option_group("Patch options") group = parser.add_option_group("Patch options")
group.add_option("-m", "--message", action="store", dest="message",
metavar="MESSAGE", default=None,
help="A message to identify the patch. "
"Will prompt if omitted.")
group.add_option("-i", "--issue", type="int", action="store", group.add_option("-i", "--issue", type="int", action="store",
metavar="ISSUE", default=None, metavar="ISSUE", default=None,
help="Issue number to which to add. Defaults to new issue.") help="Issue number to which to add. Defaults to new issue.")
@ -1310,7 +1305,7 @@ class GitVCS(VersionControlSystem):
# then the diff of everything except deleted files with rename and copy # then the diff of everything except deleted files with rename and copy
# support enabled. # support enabled.
cmd = [ cmd = [
"git", "diff", "--no-ext-diff", "--full-index", "--ignore-submodules" "git", "diff", "--no-color", "--no-ext-diff", "--full-index", "--ignore-submodules"
] ]
diff = RunShell(cmd + ["--diff-filter=D"] + extra_args, env=env, diff = RunShell(cmd + ["--diff-filter=D"] + extra_args, env=env,
silent_ok=True) silent_ok=True)
@ -1464,11 +1459,13 @@ class MercurialVCS(VersionControlSystem):
def _GetRelPath(self, filename): def _GetRelPath(self, filename):
"""Get relative path of a file according to the current directory, """Get relative path of a file according to the current directory,
given its logical path in the repo.""" given its logical path in the repo."""
assert filename.startswith(self.subdir), (filename, self.subdir) absname = os.path.join(self.repo_dir, filename)
return filename[len(self.subdir):].lstrip(r"\/") return os.path.relpath(absname)
def GenerateDiff(self, extra_args): def GenerateDiff(self, extra_args):
cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args cmd = [
"hg", "diff", "--color", "never", "--git", "-r", self.base_rev
] + extra_args
data = RunShell(cmd, silent_ok=True) data = RunShell(cmd, silent_ok=True)
svndiff = [] svndiff = []
filecount = 0 filecount = 0
@ -1494,7 +1491,8 @@ class MercurialVCS(VersionControlSystem):
def GetUnknownFiles(self): def GetUnknownFiles(self):
"""Return a list of files unknown to the VCS.""" """Return a list of files unknown to the VCS."""
args = [] args = []
status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."], status = RunShell(
["hg", "status", "--color", "never", "--rev", self.base_rev, "-u", "."],
silent_ok=True) silent_ok=True)
unknown_files = [] unknown_files = []
for line in status.splitlines(): for line in status.splitlines():
@ -1504,15 +1502,16 @@ class MercurialVCS(VersionControlSystem):
return unknown_files return unknown_files
def GetBaseFile(self, filename): def GetBaseFile(self, filename):
# "hg status" and "hg cat" both take a path relative to the current subdir # "hg status" and "hg cat" both take a path relative to the current subdir,
# rather than to the repo root, but "hg diff" has given us the full path # but "hg diff" has given us the path relative to the repo root.
# to the repo root.
base_content = "" base_content = ""
new_content = None new_content = None
is_binary = False is_binary = False
oldrelpath = relpath = self._GetRelPath(filename) oldrelpath = relpath = self._GetRelPath(filename)
# "hg status -C" returns two lines for moved/copied files, one otherwise # "hg status -C" returns two lines for moved/copied files, one otherwise
out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath]) out = RunShell(
[ "hg", "status", "--color", "never", "-C", "--rev", self.base_rev,
relpath])
out = out.splitlines() out = out.splitlines()
# HACK: strip error message about missing file/directory if it isn't in # HACK: strip error message about missing file/directory if it isn't in
# the working copy # the working copy
@ -1575,15 +1574,15 @@ class PerforceVCS(VersionControlSystem):
ConfirmLogin() ConfirmLogin()
if not options.message: if not options.title:
description = self.RunPerforceCommand(["describe", self.p4_changelist], description = self.RunPerforceCommand(["describe", self.p4_changelist],
marshal_output=True) marshal_output=True)
if description and "desc" in description: if description and "desc" in description:
# Rietveld doesn't support multi-line descriptions # Rietveld doesn't support multi-line descriptions
raw_message = description["desc"].strip() raw_title = description["desc"].strip()
lines = raw_message.splitlines() lines = raw_title.splitlines()
if len(lines): if len(lines):
options.message = lines[0] options.title = lines[0]
def GetGUID(self): def GetGUID(self):
"""For now we don't know how to get repository ID for Perforce""" """For now we don't know how to get repository ID for Perforce"""
@ -1974,10 +1973,12 @@ def GuessVCSName(options):
if res != None: if res != None:
return res return res
# Subversion has a .svn in all working directories. # Subversion from 1.7 has a single centralized .svn folder
if os.path.isdir('.svn'): # ( see http://subversion.apache.org/docs/release-notes/1.7.html#wc-ng )
logging.info("Guessed VCS = Subversion") # That's why we use 'svn info' instead of checking for .svn dir
return (VCS_SUBVERSION, None) res = RunDetectCommand(VCS_SUBVERSION, ["svn", "info"])
if res != None:
return res
# Git has a command to test if you're in a git tree. # Git has a command to test if you're in a git tree.
# Try running it, but don't die if we don't have git installed. # Try running it, but don't die if we don't have git installed.
@ -2219,19 +2220,12 @@ def RealMain(argv, data=None):
files = vcs.GetBaseFiles(data) files = vcs.GetBaseFiles(data)
if verbosity >= 1: if verbosity >= 1:
print "Upload server:", options.server, "(change with -s/--server)" print "Upload server:", options.server, "(change with -s/--server)"
if options.issue:
prompt = "Message describing this patch set: "
else:
prompt = "New issue subject: "
message = options.message or raw_input(prompt).strip()
if not message:
ErrorExit("A non-empty message is required")
rpc_server = GetRpcServer(options.server, rpc_server = GetRpcServer(options.server,
options.email, options.email,
options.host, options.host,
options.save_cookies, options.save_cookies,
options.account_type) options.account_type)
form_fields = [("subject", message)] form_fields = []
repo_guid = vcs.GetGUID() repo_guid = vcs.GetGUID()
if repo_guid: if repo_guid:
@ -2256,15 +2250,40 @@ def RealMain(argv, data=None):
for cc in options.cc.split(','): for cc in options.cc.split(','):
CheckReviewer(cc) CheckReviewer(cc)
form_fields.append(("cc", options.cc)) form_fields.append(("cc", options.cc))
description = options.description
if options.description_file: # Process --message, --title and --file.
if options.description: message = options.message or ""
ErrorExit("Can't specify description and description_file") title = options.title or ""
file = open(options.description_file, 'r') if options.file:
description = file.read() if options.message:
ErrorExit("Can't specify both message and message file options")
file = open(options.file, 'r')
message = file.read()
file.close() file.close()
if description: if options.issue:
form_fields.append(("description", description)) prompt = "Title describing this patch set: "
else:
prompt = "New issue subject: "
title = (
title or message.split('\n', 1)[0].strip() or raw_input(prompt).strip())
if not title and not options.issue:
ErrorExit("A non-empty title is required for a new issue")
# For existing issues, it's fine to give a patchset an empty name. Rietveld
# doesn't accept that so use a whitespace.
title = title or " "
if len(title) > 100:
title = title[:99] + ''
if title and not options.issue:
message = message or title
form_fields.append(("subject", title))
if message:
if not options.issue:
form_fields.append(("description", message))
else:
# TODO: [ ] Use /<issue>/publish to add a comment.
pass
# Send a hash of all the base file so the server can determine if a copy # Send a hash of all the base file so the server can determine if a copy
# already exists in an earlier patchset. # already exists in an earlier patchset.
base_hashes = "" base_hashes = ""
@ -2282,10 +2301,6 @@ def RealMain(argv, data=None):
form_fields.append(("private", "1")) form_fields.append(("private", "1"))
if options.send_patch: if options.send_patch:
options.send_mail = True options.send_mail = True
# If we're uploading base files, don't send the email before the uploads, so
# that it contains the file status.
if options.send_mail and options.download_base:
form_fields.append(("send_mail", "1"))
if not options.download_base: if not options.download_base:
form_fields.append(("content_upload", "1")) form_fields.append(("content_upload", "1"))
if len(data) > MAX_UPLOAD_SIZE: if len(data) > MAX_UPLOAD_SIZE:
@ -2320,11 +2335,15 @@ def RealMain(argv, data=None):
if not options.download_base: if not options.download_base:
vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files)
payload = {} # payload for final request
if options.send_mail: if options.send_mail:
payload = "" payload["send_mail"] = "yes"
if options.send_patch: if options.send_patch:
payload=urllib.urlencode({"attach_patch": "yes"}) payload["attach_patch"] = "yes"
rpc_server.Send("/" + issue + "/mail", payload=payload) payload = urllib.urlencode(payload)
rpc_server.Send("/" + issue + "/upload_complete/" + (patchset or ""),
payload=payload)
return issue, patchset return issue, patchset

Loading…
Cancel
Save