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

Side by Side Diff: git_cl.py

Issue 6721031: Make git cl patch authenticate the request for the diff. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: update to HEAD Created 9 years, 8 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 | « no previous file | 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/python 1 #!/usr/bin/python
2 # git-cl -- a git-command for integrating reviews on Rietveld 2 # git-cl -- a git-command for integrating reviews on Rietveld
3 # Copyright (C) 2008 Evan Martin <martine@danga.com> 3 # Copyright (C) 2008 Evan Martin <martine@danga.com>
4 4
5 import errno 5 import errno
6 import logging 6 import logging
7 import optparse 7 import optparse
8 import os 8 import os
9 import re 9 import re
10 import subprocess 10 import subprocess
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 else: 330 else:
331 self.branch = None 331 self.branch = None
332 self.rietveld_server = None 332 self.rietveld_server = None
333 self.upstream_branch = None 333 self.upstream_branch = None
334 self.has_issue = False 334 self.has_issue = False
335 self.issue = None 335 self.issue = None
336 self.has_description = False 336 self.has_description = False
337 self.description = None 337 self.description = None
338 self.has_patchset = False 338 self.has_patchset = False
339 self.patchset = None 339 self.patchset = None
340 self._rpc_server = None
340 341
341 def GetBranch(self): 342 def GetBranch(self):
342 """Returns the short branch name, e.g. 'master'.""" 343 """Returns the short branch name, e.g. 'master'."""
343 if not self.branch: 344 if not self.branch:
344 self.branchref = RunGit(['symbolic-ref', 'HEAD']).strip() 345 self.branchref = RunGit(['symbolic-ref', 'HEAD']).strip()
345 self.branch = ShortBranchName(self.branchref) 346 self.branch = ShortBranchName(self.branchref)
346 return self.branch 347 return self.branch
347 348
348 def GetBranchRef(self): 349 def GetBranchRef(self):
349 """Returns the full branch name, e.g. 'refs/heads/master'.""" 350 """Returns the full branch name, e.g. 'refs/heads/master'."""
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 458
458 def SetPatchset(self, patchset): 459 def SetPatchset(self, patchset):
459 """Set this branch's patchset. If patchset=0, clears the patchset.""" 460 """Set this branch's patchset. If patchset=0, clears the patchset."""
460 if patchset: 461 if patchset:
461 RunGit(['config', self._PatchsetSetting(), str(patchset)]) 462 RunGit(['config', self._PatchsetSetting(), str(patchset)])
462 else: 463 else:
463 RunGit(['config', '--unset', self._PatchsetSetting()], 464 RunGit(['config', '--unset', self._PatchsetSetting()],
464 swallow_stderr=True, error_ok=True) 465 swallow_stderr=True, error_ok=True)
465 self.has_patchset = False 466 self.has_patchset = False
466 467
468 def GetPatchSetDiff(self, issue):
469 # Grab the last patchset of the issue first.
470 data = json.loads(self._RpcServer().Send('/api/%s' % issue))
471 patchset = data['patchsets'][-1]
472 return self._RpcServer().Send(
473 '/download/issue%s_%s.diff' % (issue, patchset))
474
467 def SetIssue(self, issue): 475 def SetIssue(self, issue):
468 """Set this branch's issue. If issue=0, clears the issue.""" 476 """Set this branch's issue. If issue=0, clears the issue."""
469 if issue: 477 if issue:
470 RunGit(['config', self._IssueSetting(), str(issue)]) 478 RunGit(['config', self._IssueSetting(), str(issue)])
471 if self.rietveld_server: 479 if self.rietveld_server:
472 RunGit(['config', self._RietveldServer(), self.rietveld_server]) 480 RunGit(['config', self._RietveldServer(), self.rietveld_server])
473 else: 481 else:
474 RunGit(['config', '--unset', self._IssueSetting()]) 482 RunGit(['config', '--unset', self._IssueSetting()])
475 self.SetPatchset(0) 483 self.SetPatchset(0)
476 self.has_issue = False 484 self.has_issue = False
477 485
478 def CloseIssue(self): 486 def CloseIssue(self):
479 rpc_server = self._RpcServer() 487 rpc_server = self._RpcServer()
480 # Newer versions of Rietveld require us to pass an XSRF token to POST, so 488 # Newer versions of Rietveld require us to pass an XSRF token to POST, so
481 # we fetch it from the server. (The version used by Chromium has been 489 # we fetch it from the server. (The version used by Chromium has been
482 # modified so the token isn't required when closing an issue.) 490 # modified so the token isn't required when closing an issue.)
483 xsrf_token = rpc_server.Send('/xsrf_token', 491 xsrf_token = rpc_server.Send('/xsrf_token',
484 extra_headers={'X-Requesting-XSRF-Token': '1'}) 492 extra_headers={'X-Requesting-XSRF-Token': '1'})
485 493
486 # You cannot close an issue with a GET. 494 # You cannot close an issue with a GET.
487 # We pass an empty string for the data so it is a POST rather than a GET. 495 # We pass an empty string for the data so it is a POST rather than a GET.
488 data = [("description", self.description), 496 data = [("description", self.description),
489 ("xsrf_token", xsrf_token)] 497 ("xsrf_token", xsrf_token)]
490 ctype, body = upload.EncodeMultipartFormData(data, []) 498 ctype, body = upload.EncodeMultipartFormData(data, [])
491 rpc_server.Send('/' + self.GetIssue() + '/close', body, ctype) 499 rpc_server.Send('/' + self.GetIssue() + '/close', body, ctype)
492 500
493 def _RpcServer(self): 501 def _RpcServer(self):
494 """Returns an upload.RpcServer() to access this review's rietveld instance. 502 """Returns an upload.RpcServer() to access this review's rietveld instance.
495 """ 503 """
496 server = self.GetRietveldServer() 504 if not self._rpc_server:
497 return upload.GetRpcServer(server, save_cookies=True) 505 server = self.GetRietveldServer()
506 self._rpc_server = upload.GetRpcServer(server, save_cookies=True)
507 return self._rpc_server
498 508
499 def _IssueSetting(self): 509 def _IssueSetting(self):
500 """Return the git setting that stores this change's issue.""" 510 """Return the git setting that stores this change's issue."""
501 return 'branch.%s.rietveldissue' % self.GetBranch() 511 return 'branch.%s.rietveldissue' % self.GetBranch()
502 512
503 def _PatchsetSetting(self): 513 def _PatchsetSetting(self):
504 """Return the git setting that stores this change's most recent patchset.""" 514 """Return the git setting that stores this change's most recent patchset."""
505 return 'branch.%s.rietveldpatchset' % self.GetBranch() 515 return 'branch.%s.rietveldpatchset' % self.GetBranch()
506 516
507 def _RietveldServer(self): 517 def _RietveldServer(self):
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 help="don't commit after patch applies") 1223 help="don't commit after patch applies")
1214 (options, args) = parser.parse_args(args) 1224 (options, args) = parser.parse_args(args)
1215 if len(args) != 1: 1225 if len(args) != 1:
1216 parser.print_help() 1226 parser.print_help()
1217 return 1 1227 return 1
1218 issue_arg = args[0] 1228 issue_arg = args[0]
1219 1229
1220 if re.match(r'\d+', issue_arg): 1230 if re.match(r'\d+', issue_arg):
1221 # Input is an issue id. Figure out the URL. 1231 # Input is an issue id. Figure out the URL.
1222 issue = issue_arg 1232 issue = issue_arg
1223 server = settings.GetDefaultServerUrl() 1233 patch_data = Changelist().GetPatchSetDiff(issue)
1224 fetch = urllib2.urlopen('%s/%s' % (server, issue)).read()
1225 m = re.search(r'/download/issue[0-9]+_[0-9]+.diff', fetch)
1226 if not m:
1227 DieWithError('Must pass an issue ID or full URL for '
1228 '\'Download raw patch set\'')
1229 url = '%s%s' % (server, m.group(0).strip())
1230 else: 1234 else:
1231 # Assume it's a URL to the patch. Default to http. 1235 # Assume it's a URL to the patch. Default to http.
1232 issue_url = FixUrl(issue_arg) 1236 issue_url = FixUrl(issue_arg)
1233 match = re.match(r'.*?/issue(\d+)_\d+.diff', issue_url) 1237 match = re.match(r'.*?/issue(\d+)_\d+.diff', issue_url)
1234 if match: 1238 if not match:
1235 issue = match.group(1)
1236 url = issue_arg
1237 else:
1238 DieWithError('Must pass an issue ID or full URL for ' 1239 DieWithError('Must pass an issue ID or full URL for '
1239 '\'Download raw patch set\'') 1240 '\'Download raw patch set\'')
1241 issue = match.group(1)
1242 patch_data = urllib2.urlopen(issue_arg).read()
1240 1243
1241 if options.newbranch: 1244 if options.newbranch:
1242 if options.force: 1245 if options.force:
1243 RunGit(['branch', '-D', options.newbranch], 1246 RunGit(['branch', '-D', options.newbranch],
1244 swallow_stderr=True, error_ok=True) 1247 swallow_stderr=True, error_ok=True)
1245 RunGit(['checkout', '-b', options.newbranch, 1248 RunGit(['checkout', '-b', options.newbranch,
1246 Changelist().GetUpstreamBranch()]) 1249 Changelist().GetUpstreamBranch()])
1247 1250
1248 # Switch up to the top-level directory, if necessary, in preparation for 1251 # Switch up to the top-level directory, if necessary, in preparation for
1249 # applying the patch. 1252 # applying the patch.
1250 top = RunGit(['rev-parse', '--show-cdup']).strip() 1253 top = RunGit(['rev-parse', '--show-cdup']).strip()
1251 if top: 1254 if top:
1252 os.chdir(top) 1255 os.chdir(top)
1253 1256
1254 patch_data = urllib2.urlopen(url).read()
1255 # Git patches have a/ at the beginning of source paths. We strip that out 1257 # Git patches have a/ at the beginning of source paths. We strip that out
1256 # with a sed script rather than the -p flag to patch so we can feed either 1258 # with a sed script rather than the -p flag to patch so we can feed either
1257 # Git or svn-style patches into the same apply command. 1259 # Git or svn-style patches into the same apply command.
1258 # re.sub() should be used but flags=re.MULTILINE is only in python 2.7. 1260 # re.sub() should be used but flags=re.MULTILINE is only in python 2.7.
1259 sed_proc = Popen(['sed', '-e', 's|^--- a/|--- |; s|^+++ b/|+++ |'], 1261 sed_proc = Popen(['sed', '-e', 's|^--- a/|--- |; s|^+++ b/|+++ |'],
1260 stdin=subprocess.PIPE, stdout=subprocess.PIPE) 1262 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
1261 patch_data = sed_proc.communicate(patch_data)[0] 1263 patch_data = sed_proc.communicate(patch_data)[0]
1262 if sed_proc.returncode: 1264 if sed_proc.returncode:
1263 DieWithError('Git patch mungling failed.') 1265 DieWithError('Git patch mungling failed.')
1264 logging.info(patch_data) 1266 logging.info(patch_data)
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' 1405 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith '
1404 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) 1406 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e)))
1405 1407
1406 # Not a known command. Default to help. 1408 # Not a known command. Default to help.
1407 GenUsage(parser, 'help') 1409 GenUsage(parser, 'help')
1408 return CMDhelp(parser, argv) 1410 return CMDhelp(parser, argv)
1409 1411
1410 1412
1411 if __name__ == '__main__': 1413 if __name__ == '__main__':
1412 sys.exit(main(sys.argv[1:])) 1414 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698