Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(464)

Side by Side Diff: third_party/upload.py

Issue 9193023: Update upload.py @827fa087f74d, which includes support for svn 1.7 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Don't try to fix push-from-logs.sh in this CL, defer for later Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tests/git_cl_test.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # coding: utf-8
2 # 3 #
3 # Copyright 2007 Google Inc. 4 # Copyright 2007 Google Inc.
4 # 5 #
5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License. 7 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at 8 # You may obtain a copy of the License at
8 # 9 #
9 # http://www.apache.org/licenses/LICENSE-2.0 10 # http://www.apache.org/licenses/LICENSE-2.0
10 # 11 #
11 # Unless required by applicable law or agreed to in writing, software 12 # Unless required by applicable law or agreed to in writing, software
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 """Returns an OpenerDirector for making HTTP requests. 209 """Returns an OpenerDirector for making HTTP requests.
209 210
210 Returns: 211 Returns:
211 A urllib2.OpenerDirector object. 212 A urllib2.OpenerDirector object.
212 """ 213 """
213 raise NotImplementedError() 214 raise NotImplementedError()
214 215
215 def _CreateRequest(self, url, data=None): 216 def _CreateRequest(self, url, data=None):
216 """Creates a new urllib request.""" 217 """Creates a new urllib request."""
217 logging.debug("Creating request for: '%s' with payload:\n%s", url, data) 218 logging.debug("Creating request for: '%s' with payload:\n%s", url, data)
218 req = urllib2.Request(url, data=data) 219 req = urllib2.Request(url, data=data, headers={"Accept": "text/plain"})
219 if self.host_override: 220 if self.host_override:
220 req.add_header("Host", self.host_override) 221 req.add_header("Host", self.host_override)
221 for key, value in self.extra_headers.iteritems(): 222 for key, value in self.extra_headers.iteritems():
222 req.add_header(key, value) 223 req.add_header(key, value)
223 return req 224 return req
224 225
225 def _GetAuthToken(self, email, password): 226 def _GetAuthToken(self, email, password):
226 """Uses ClientLogin to authenticate the user, returning an auth token. 227 """Uses ClientLogin to authenticate the user, returning an auth token.
227 228
228 Args: 229 Args:
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 try: 393 try:
393 f = self.opener.open(req) 394 f = self.opener.open(req)
394 response = f.read() 395 response = f.read()
395 f.close() 396 f.close()
396 return response 397 return response
397 except urllib2.HTTPError, e: 398 except urllib2.HTTPError, e:
398 if tries > 3: 399 if tries > 3:
399 raise 400 raise
400 elif e.code == 401 or e.code == 302: 401 elif e.code == 401 or e.code == 302:
401 self._Authenticate() 402 self._Authenticate()
402 ## elif e.code >= 500 and e.code < 600:
403 ## # Server Error - try again.
404 ## continue
405 elif e.code == 301: 403 elif e.code == 301:
406 # Handle permanent redirect manually. 404 # Handle permanent redirect manually.
407 url = e.info()["location"] 405 url = e.info()["location"]
408 url_loc = urlparse.urlparse(url) 406 url_loc = urlparse.urlparse(url)
409 self.host = '%s://%s' % (url_loc[0], url_loc[1]) 407 self.host = '%s://%s' % (url_loc[0], url_loc[1])
408 elif e.code >= 500:
409 ErrorExit(e.read())
410 else: 410 else:
411 raise 411 raise
412 finally: 412 finally:
413 socket.setdefaulttimeout(old_timeout) 413 socket.setdefaulttimeout(old_timeout)
414 414
415 415
416 class HttpRpcServer(AbstractRpcServer): 416 class HttpRpcServer(AbstractRpcServer):
417 """Provides a simplified RPC-style interface for HTTP requests.""" 417 """Provides a simplified RPC-style interface for HTTP requests."""
418 418
419 def _Authenticate(self): 419 def _Authenticate(self):
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 dest="save_cookies", default=True, 525 dest="save_cookies", default=True,
526 help="Do not save authentication cookies to local disk.") 526 help="Do not save authentication cookies to local disk.")
527 group.add_option("--account_type", action="store", dest="account_type", 527 group.add_option("--account_type", action="store", dest="account_type",
528 metavar="TYPE", default=AUTH_ACCOUNT_TYPE, 528 metavar="TYPE", default=AUTH_ACCOUNT_TYPE,
529 choices=["GOOGLE", "HOSTED"], 529 choices=["GOOGLE", "HOSTED"],
530 help=("Override the default account type " 530 help=("Override the default account type "
531 "(defaults to '%default', " 531 "(defaults to '%default', "
532 "valid choices are 'GOOGLE' and 'HOSTED').")) 532 "valid choices are 'GOOGLE' and 'HOSTED')."))
533 # Issue 533 # Issue
534 group = parser.add_option_group("Issue options") 534 group = parser.add_option_group("Issue options")
535 group.add_option("-d", "--description", action="store", dest="description", 535 group.add_option("-t", "--title", action="store", dest="title",
536 metavar="DESCRIPTION", default=None, 536 help="New issue subject or new patch set title")
537 help="Optional description when creating an issue.") 537 group.add_option("-m", "--message", action="store", dest="message",
538 group.add_option("-f", "--description_file", action="store",
539 dest="description_file", metavar="DESCRIPTION_FILE",
540 default=None, 538 default=None,
541 help="Optional path of a file that contains " 539 help="New issue description or new patch set message")
542 "the description when creating an issue.") 540 group.add_option("-F", "--file", action="store", dest="file",
541 default=None, help="Read the message above from file.")
543 group.add_option("-r", "--reviewers", action="store", dest="reviewers", 542 group.add_option("-r", "--reviewers", action="store", dest="reviewers",
544 metavar="REVIEWERS", default=None, 543 metavar="REVIEWERS", default=None,
545 help="Add reviewers (comma separated email addresses).") 544 help="Add reviewers (comma separated email addresses).")
546 group.add_option("--cc", action="store", dest="cc", 545 group.add_option("--cc", action="store", dest="cc",
547 metavar="CC", default=None, 546 metavar="CC", default=None,
548 help="Add CC (comma separated email addresses).") 547 help="Add CC (comma separated email addresses).")
549 group.add_option("--private", action="store_true", dest="private", 548 group.add_option("--private", action="store_true", dest="private",
550 default=False, 549 default=False,
551 help="Make the issue restricted to reviewers and those CCed") 550 help="Make the issue restricted to reviewers and those CCed")
552 # Upload options 551 # Upload options
553 group = parser.add_option_group("Patch options") 552 group = parser.add_option_group("Patch options")
554 group.add_option("-m", "--message", action="store", dest="message",
555 metavar="MESSAGE", default=None,
556 help="A message to identify the patch. "
557 "Will prompt if omitted.")
558 group.add_option("-i", "--issue", type="int", action="store", 553 group.add_option("-i", "--issue", type="int", action="store",
559 metavar="ISSUE", default=None, 554 metavar="ISSUE", default=None,
560 help="Issue number to which to add. Defaults to new issue.") 555 help="Issue number to which to add. Defaults to new issue.")
561 group.add_option("--base_url", action="store", dest="base_url", default=None, 556 group.add_option("--base_url", action="store", dest="base_url", default=None,
562 help="Base URL path for files (listed as \"Base URL\" when " 557 help="Base URL path for files (listed as \"Base URL\" when "
563 "viewing issue). If omitted, will be guessed automatically " 558 "viewing issue). If omitted, will be guessed automatically "
564 "for SVN repos and left blank for others.") 559 "for SVN repos and left blank for others.")
565 group.add_option("--download_base", action="store_true", 560 group.add_option("--download_base", action="store_true",
566 dest="download_base", default=False, 561 dest="download_base", default=False,
567 help="Base files will be downloaded by the server " 562 help="Base files will be downloaded by the server "
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 1452
1458 def GetGUID(self): 1453 def GetGUID(self):
1459 # See chapter "Uniquely identifying a repository" 1454 # See chapter "Uniquely identifying a repository"
1460 # http://hgbook.red-bean.com/read/customizing-the-output-of-mercurial.html 1455 # http://hgbook.red-bean.com/read/customizing-the-output-of-mercurial.html
1461 info = RunShell("hg log -r0 --template {node}".split()) 1456 info = RunShell("hg log -r0 --template {node}".split())
1462 return info.strip() 1457 return info.strip()
1463 1458
1464 def _GetRelPath(self, filename): 1459 def _GetRelPath(self, filename):
1465 """Get relative path of a file according to the current directory, 1460 """Get relative path of a file according to the current directory,
1466 given its logical path in the repo.""" 1461 given its logical path in the repo."""
1467 assert filename.startswith(self.subdir), (filename, self.subdir) 1462 absname = os.path.join(self.repo_dir, filename)
1468 return filename[len(self.subdir):].lstrip(r"\/") 1463 return os.path.relpath(absname)
1469 1464
1470 def GenerateDiff(self, extra_args): 1465 def GenerateDiff(self, extra_args):
1471 cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args 1466 cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args
1472 data = RunShell(cmd, silent_ok=True) 1467 data = RunShell(cmd, silent_ok=True)
1473 svndiff = [] 1468 svndiff = []
1474 filecount = 0 1469 filecount = 0
1475 for line in data.splitlines(): 1470 for line in data.splitlines():
1476 m = re.match("diff --git a/(\S+) b/(\S+)", line) 1471 m = re.match("diff --git a/(\S+) b/(\S+)", line)
1477 if m: 1472 if m:
1478 # Modify line to make it look like as it comes from svn diff. 1473 # Modify line to make it look like as it comes from svn diff.
(...skipping 18 matching lines...) Expand all
1497 status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."], 1492 status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."],
1498 silent_ok=True) 1493 silent_ok=True)
1499 unknown_files = [] 1494 unknown_files = []
1500 for line in status.splitlines(): 1495 for line in status.splitlines():
1501 st, fn = line.split(" ", 1) 1496 st, fn = line.split(" ", 1)
1502 if st == "?": 1497 if st == "?":
1503 unknown_files.append(fn) 1498 unknown_files.append(fn)
1504 return unknown_files 1499 return unknown_files
1505 1500
1506 def GetBaseFile(self, filename): 1501 def GetBaseFile(self, filename):
1507 # "hg status" and "hg cat" both take a path relative to the current subdir 1502 # "hg status" and "hg cat" both take a path relative to the current subdir,
1508 # rather than to the repo root, but "hg diff" has given us the full path 1503 # but "hg diff" has given us the path relative to the repo root.
1509 # to the repo root.
1510 base_content = "" 1504 base_content = ""
1511 new_content = None 1505 new_content = None
1512 is_binary = False 1506 is_binary = False
1513 oldrelpath = relpath = self._GetRelPath(filename) 1507 oldrelpath = relpath = self._GetRelPath(filename)
1514 # "hg status -C" returns two lines for moved/copied files, one otherwise 1508 # "hg status -C" returns two lines for moved/copied files, one otherwise
1515 out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath]) 1509 out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath])
1516 out = out.splitlines() 1510 out = out.splitlines()
1517 # HACK: strip error message about missing file/directory if it isn't in 1511 # HACK: strip error message about missing file/directory if it isn't in
1518 # the working copy 1512 # the working copy
1519 if out[0].startswith('%s: ' % relpath): 1513 if out[0].startswith('%s: ' % relpath):
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 ErrorExit("A changelist id is required") 1562 ErrorExit("A changelist id is required")
1569 if (options.revision): 1563 if (options.revision):
1570 ErrorExit("--rev is not supported for perforce") 1564 ErrorExit("--rev is not supported for perforce")
1571 1565
1572 self.p4_port = options.p4_port 1566 self.p4_port = options.p4_port
1573 self.p4_client = options.p4_client 1567 self.p4_client = options.p4_client
1574 self.p4_user = options.p4_user 1568 self.p4_user = options.p4_user
1575 1569
1576 ConfirmLogin() 1570 ConfirmLogin()
1577 1571
1578 if not options.message: 1572 if not options.title:
1579 description = self.RunPerforceCommand(["describe", self.p4_changelist], 1573 description = self.RunPerforceCommand(["describe", self.p4_changelist],
1580 marshal_output=True) 1574 marshal_output=True)
1581 if description and "desc" in description: 1575 if description and "desc" in description:
1582 # Rietveld doesn't support multi-line descriptions 1576 # Rietveld doesn't support multi-line descriptions
1583 raw_message = description["desc"].strip() 1577 raw_title = description["desc"].strip()
1584 lines = raw_message.splitlines() 1578 lines = raw_title.splitlines()
1585 if len(lines): 1579 if len(lines):
1586 options.message = lines[0] 1580 options.title = lines[0]
1587 1581
1588 def GetGUID(self): 1582 def GetGUID(self):
1589 """For now we don't know how to get repository ID for Perforce""" 1583 """For now we don't know how to get repository ID for Perforce"""
1590 return 1584 return
1591 1585
1592 def RunPerforceCommandWithReturnCode(self, extra_args, marshal_output=False, 1586 def RunPerforceCommandWithReturnCode(self, extra_args, marshal_output=False,
1593 universal_newlines=True): 1587 universal_newlines=True):
1594 args = ["p4"] 1588 args = ["p4"]
1595 if marshal_output: 1589 if marshal_output:
1596 # -G makes perforce format its output as marshalled python objects 1590 # -G makes perforce format its output as marshalled python objects
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
1967 if errcode != errno.ENOENT: # command not found code 1961 if errcode != errno.ENOENT: # command not found code
1968 raise 1962 raise
1969 1963
1970 # Mercurial has a command to get the base directory of a repository 1964 # Mercurial has a command to get the base directory of a repository
1971 # Try running it, but don't die if we don't have hg installed. 1965 # Try running it, but don't die if we don't have hg installed.
1972 # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. 1966 # NOTE: we try Mercurial first as it can sit on top of an SVN working copy.
1973 res = RunDetectCommand(VCS_MERCURIAL, ["hg", "root"]) 1967 res = RunDetectCommand(VCS_MERCURIAL, ["hg", "root"])
1974 if res != None: 1968 if res != None:
1975 return res 1969 return res
1976 1970
1977 # Subversion has a .svn in all working directories. 1971 # Subversion from 1.7 has a single centralized .svn folder
1978 if os.path.isdir('.svn'): 1972 # ( see http://subversion.apache.org/docs/release-notes/1.7.html#wc-ng )
1979 logging.info("Guessed VCS = Subversion") 1973 # That's why we use 'svn info' instead of checking for .svn dir
1980 return (VCS_SUBVERSION, None) 1974 res = RunDetectCommand(VCS_SUBVERSION, ["svn", "info"])
1975 if res != None:
1976 return res
1981 1977
1982 # Git has a command to test if you're in a git tree. 1978 # Git has a command to test if you're in a git tree.
1983 # Try running it, but don't die if we don't have git installed. 1979 # Try running it, but don't die if we don't have git installed.
1984 res = RunDetectCommand(VCS_GIT, ["git", "rev-parse", 1980 res = RunDetectCommand(VCS_GIT, ["git", "rev-parse",
1985 "--is-inside-work-tree"]) 1981 "--is-inside-work-tree"])
1986 if res != None: 1982 if res != None:
1987 return res 1983 return res
1988 1984
1989 # detect CVS repos use `cvs status && $? == 0` rules 1985 # detect CVS repos use `cvs status && $? == 0` rules
1990 res = RunDetectCommand(VCS_CVS, ["cvs", "status"]) 1986 res = RunDetectCommand(VCS_CVS, ["cvs", "status"])
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2212 if data is None: 2208 if data is None:
2213 data = vcs.GenerateDiff(args) 2209 data = vcs.GenerateDiff(args)
2214 data = vcs.PostProcessDiff(data) 2210 data = vcs.PostProcessDiff(data)
2215 if options.print_diffs: 2211 if options.print_diffs:
2216 print "Rietveld diff start:*****" 2212 print "Rietveld diff start:*****"
2217 print data 2213 print data
2218 print "Rietveld diff end:*****" 2214 print "Rietveld diff end:*****"
2219 files = vcs.GetBaseFiles(data) 2215 files = vcs.GetBaseFiles(data)
2220 if verbosity >= 1: 2216 if verbosity >= 1:
2221 print "Upload server:", options.server, "(change with -s/--server)" 2217 print "Upload server:", options.server, "(change with -s/--server)"
2222 if options.issue:
2223 prompt = "Message describing this patch set: "
2224 else:
2225 prompt = "New issue subject: "
2226 message = options.message or raw_input(prompt).strip()
2227 if not message:
2228 ErrorExit("A non-empty message is required")
2229 rpc_server = GetRpcServer(options.server, 2218 rpc_server = GetRpcServer(options.server,
2230 options.email, 2219 options.email,
2231 options.host, 2220 options.host,
2232 options.save_cookies, 2221 options.save_cookies,
2233 options.account_type) 2222 options.account_type)
2234 form_fields = [("subject", message)] 2223 form_fields = []
2235 2224
2236 repo_guid = vcs.GetGUID() 2225 repo_guid = vcs.GetGUID()
2237 if repo_guid: 2226 if repo_guid:
2238 form_fields.append(("repo_guid", repo_guid)) 2227 form_fields.append(("repo_guid", repo_guid))
2239 if base: 2228 if base:
2240 b = urlparse.urlparse(base) 2229 b = urlparse.urlparse(base)
2241 username, netloc = urllib.splituser(b.netloc) 2230 username, netloc = urllib.splituser(b.netloc)
2242 if username: 2231 if username:
2243 logging.info("Removed username from base URL") 2232 logging.info("Removed username from base URL")
2244 base = urlparse.urlunparse((b.scheme, netloc, b.path, b.params, 2233 base = urlparse.urlunparse((b.scheme, netloc, b.path, b.params,
2245 b.query, b.fragment)) 2234 b.query, b.fragment))
2246 form_fields.append(("base", base)) 2235 form_fields.append(("base", base))
2247 if options.issue: 2236 if options.issue:
2248 form_fields.append(("issue", str(options.issue))) 2237 form_fields.append(("issue", str(options.issue)))
2249 if options.email: 2238 if options.email:
2250 form_fields.append(("user", options.email)) 2239 form_fields.append(("user", options.email))
2251 if options.reviewers: 2240 if options.reviewers:
2252 for reviewer in options.reviewers.split(','): 2241 for reviewer in options.reviewers.split(','):
2253 CheckReviewer(reviewer) 2242 CheckReviewer(reviewer)
2254 form_fields.append(("reviewers", options.reviewers)) 2243 form_fields.append(("reviewers", options.reviewers))
2255 if options.cc: 2244 if options.cc:
2256 for cc in options.cc.split(','): 2245 for cc in options.cc.split(','):
2257 CheckReviewer(cc) 2246 CheckReviewer(cc)
2258 form_fields.append(("cc", options.cc)) 2247 form_fields.append(("cc", options.cc))
2259 description = options.description 2248
2260 if options.description_file: 2249 # Process --message, --title and --file.
2261 if options.description: 2250 message = options.message or ""
2262 ErrorExit("Can't specify description and description_file") 2251 title = options.title or ""
2263 file = open(options.description_file, 'r') 2252 if options.file:
2264 description = file.read() 2253 if options.message:
2254 ErrorExit("Can't specify both message and message file options")
2255 file = open(options.file, 'r')
2256 message = file.read()
2265 file.close() 2257 file.close()
2266 if description: 2258 if options.issue:
2267 form_fields.append(("description", description)) 2259 prompt = "Title describing this patch set: "
2260 else:
2261 prompt = "New issue subject: "
2262 title = (
2263 title or message.split('\n', 1)[0].strip() or raw_input(prompt)).strip()
2264 if not title:
2265 ErrorExit("A non-empty title is required")
2266 if len(title) > 100:
2267 title = title[:99] + '…'
2268 if title and not options.issue:
2269 message = message or title
2270
2271 form_fields.append(("subject", title))
2272 if message:
2273 if not options.issue:
2274 form_fields.append(("description", message))
2275 else:
2276 # TODO: [ ] Use /<issue>/publish to add a comment.
2277 pass
2278
2268 # Send a hash of all the base file so the server can determine if a copy 2279 # Send a hash of all the base file so the server can determine if a copy
2269 # already exists in an earlier patchset. 2280 # already exists in an earlier patchset.
2270 base_hashes = "" 2281 base_hashes = ""
2271 for file, info in files.iteritems(): 2282 for file, info in files.iteritems():
2272 if not info[0] is None: 2283 if not info[0] is None:
2273 checksum = md5(info[0]).hexdigest() 2284 checksum = md5(info[0]).hexdigest()
2274 if base_hashes: 2285 if base_hashes:
2275 base_hashes += "|" 2286 base_hashes += "|"
2276 base_hashes += checksum + ":" + file 2287 base_hashes += checksum + ":" + file
2277 form_fields.append(("base_hashes", base_hashes)) 2288 form_fields.append(("base_hashes", base_hashes))
2278 if options.private: 2289 if options.private:
2279 if options.issue: 2290 if options.issue:
2280 print "Warning: Private flag ignored when updating an existing issue." 2291 print "Warning: Private flag ignored when updating an existing issue."
2281 else: 2292 else:
2282 form_fields.append(("private", "1")) 2293 form_fields.append(("private", "1"))
2283 if options.send_patch: 2294 if options.send_patch:
2284 options.send_mail = True 2295 options.send_mail = True
2285 # If we're uploading base files, don't send the email before the uploads, so
2286 # that it contains the file status.
2287 if options.send_mail and options.download_base:
2288 form_fields.append(("send_mail", "1"))
2289 if not options.download_base: 2296 if not options.download_base:
2290 form_fields.append(("content_upload", "1")) 2297 form_fields.append(("content_upload", "1"))
2291 if len(data) > MAX_UPLOAD_SIZE: 2298 if len(data) > MAX_UPLOAD_SIZE:
2292 print "Patch is large, so uploading file patches separately." 2299 print "Patch is large, so uploading file patches separately."
2293 uploaded_diff_file = [] 2300 uploaded_diff_file = []
2294 form_fields.append(("separate_patches", "1")) 2301 form_fields.append(("separate_patches", "1"))
2295 else: 2302 else:
2296 uploaded_diff_file = [("data", "data.diff", data)] 2303 uploaded_diff_file = [("data", "data.diff", data)]
2297 ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff_file) 2304 ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff_file)
2298 response_body = rpc_server.Send("/upload", body, content_type=ctype) 2305 response_body = rpc_server.Send("/upload", body, content_type=ctype)
(...skipping 14 matching lines...) Expand all
2313 sys.exit(0) 2320 sys.exit(0)
2314 issue = msg[msg.rfind("/")+1:] 2321 issue = msg[msg.rfind("/")+1:]
2315 2322
2316 if not uploaded_diff_file: 2323 if not uploaded_diff_file:
2317 result = UploadSeparatePatches(issue, rpc_server, patchset, data, options) 2324 result = UploadSeparatePatches(issue, rpc_server, patchset, data, options)
2318 if not options.download_base: 2325 if not options.download_base:
2319 patches = result 2326 patches = result
2320 2327
2321 if not options.download_base: 2328 if not options.download_base:
2322 vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) 2329 vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files)
2323 if options.send_mail: 2330
2324 payload = "" 2331 payload = {} # payload for final request
2325 if options.send_patch: 2332 if options.send_mail:
2326 payload=urllib.urlencode({"attach_patch": "yes"}) 2333 payload["send_mail"] = "yes"
2327 rpc_server.Send("/" + issue + "/mail", payload=payload) 2334 if options.send_patch:
2335 payload["attach_patch"] = "yes"
2336 payload = urllib.urlencode(payload)
2337 rpc_server.Send("/" + issue + "/upload_complete/" + (patchset or ""),
2338 payload=payload)
2328 return issue, patchset 2339 return issue, patchset
2329 2340
2330 2341
2331 def main(): 2342 def main():
2332 try: 2343 try:
2333 logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" 2344 logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:"
2334 "%(lineno)s %(message)s ")) 2345 "%(lineno)s %(message)s "))
2335 os.environ['LC_ALL'] = 'C' 2346 os.environ['LC_ALL'] = 'C'
2336 RealMain(sys.argv) 2347 RealMain(sys.argv)
2337 except KeyboardInterrupt: 2348 except KeyboardInterrupt:
2338 print 2349 print
2339 StatusUpdate("Interrupted.") 2350 StatusUpdate("Interrupted.")
2340 sys.exit(1) 2351 sys.exit(1)
2341 2352
2342 2353
2343 if __name__ == "__main__": 2354 if __name__ == "__main__":
2344 main() 2355 main()
OLDNEW
« no previous file with comments | « tests/git_cl_test.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698