OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 # Copyright (C) 2008 Evan Martin <martine@danga.com> | 6 # Copyright (C) 2008 Evan Martin <martine@danga.com> |
7 | 7 |
8 """A git-command for integrating reviews on Rietveld.""" | 8 """A git-command for integrating reviews on Rietveld.""" |
9 | 9 |
10 import errno | 10 import errno |
(...skipping 21 matching lines...) Expand all Loading... |
32 except ImportError: | 32 except ImportError: |
33 # Fall back to the packaged version. | 33 # Fall back to the packaged version. |
34 sys.path.append(os.path.join(os.path.dirname(__file__), 'third_party')) | 34 sys.path.append(os.path.join(os.path.dirname(__file__), 'third_party')) |
35 import simplejson as json # pylint: disable=F0401 | 35 import simplejson as json # pylint: disable=F0401 |
36 | 36 |
37 | 37 |
38 from third_party import upload | 38 from third_party import upload |
39 import breakpad # pylint: disable=W0611 | 39 import breakpad # pylint: disable=W0611 |
40 import fix_encoding | 40 import fix_encoding |
41 import presubmit_support | 41 import presubmit_support |
| 42 import rietveld |
42 import scm | 43 import scm |
43 import watchlists | 44 import watchlists |
44 | 45 |
45 | 46 |
46 | 47 |
47 DEFAULT_SERVER = 'http://codereview.appspot.com' | 48 DEFAULT_SERVER = 'http://codereview.appspot.com' |
48 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s' | 49 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s' |
49 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' | 50 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' |
50 | 51 |
51 | 52 |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 return self.rietveld_server | 457 return self.rietveld_server |
457 | 458 |
458 def GetIssueURL(self): | 459 def GetIssueURL(self): |
459 """Get the URL for a particular issue.""" | 460 """Get the URL for a particular issue.""" |
460 return '%s/%s' % (self.GetRietveldServer(), self.GetIssue()) | 461 return '%s/%s' % (self.GetRietveldServer(), self.GetIssue()) |
461 | 462 |
462 def GetDescription(self, pretty=False): | 463 def GetDescription(self, pretty=False): |
463 if not self.has_description: | 464 if not self.has_description: |
464 if self.GetIssue(): | 465 if self.GetIssue(): |
465 path = '/' + self.GetIssue() + '/description' | 466 path = '/' + self.GetIssue() + '/description' |
466 rpc_server = self._RpcServer() | 467 rpc_server = self.RpcServer() |
467 self.description = rpc_server.Send(path).strip() | 468 self.description = rpc_server.Send(path).strip() |
468 self.has_description = True | 469 self.has_description = True |
469 if pretty: | 470 if pretty: |
470 wrapper = textwrap.TextWrapper() | 471 wrapper = textwrap.TextWrapper() |
471 wrapper.initial_indent = wrapper.subsequent_indent = ' ' | 472 wrapper.initial_indent = wrapper.subsequent_indent = ' ' |
472 return wrapper.fill(self.description) | 473 return wrapper.fill(self.description) |
473 return self.description | 474 return self.description |
474 | 475 |
475 def GetPatchset(self): | 476 def GetPatchset(self): |
476 if not self.has_patchset: | 477 if not self.has_patchset: |
(...skipping 10 matching lines...) Expand all Loading... |
487 """Set this branch's patchset. If patchset=0, clears the patchset.""" | 488 """Set this branch's patchset. If patchset=0, clears the patchset.""" |
488 if patchset: | 489 if patchset: |
489 RunGit(['config', self._PatchsetSetting(), str(patchset)]) | 490 RunGit(['config', self._PatchsetSetting(), str(patchset)]) |
490 else: | 491 else: |
491 RunGit(['config', '--unset', self._PatchsetSetting()], | 492 RunGit(['config', '--unset', self._PatchsetSetting()], |
492 swallow_stderr=True, error_ok=True) | 493 swallow_stderr=True, error_ok=True) |
493 self.has_patchset = False | 494 self.has_patchset = False |
494 | 495 |
495 def GetPatchSetDiff(self, issue): | 496 def GetPatchSetDiff(self, issue): |
496 # Grab the last patchset of the issue first. | 497 # Grab the last patchset of the issue first. |
497 data = json.loads(self._RpcServer().Send('/api/%s' % issue)) | 498 data = json.loads(self.RpcServer().Send('/api/%s' % issue)) |
498 patchset = data['patchsets'][-1] | 499 patchset = data['patchsets'][-1] |
499 return self._RpcServer().Send( | 500 return self.RpcServer().Send( |
500 '/download/issue%s_%s.diff' % (issue, patchset)) | 501 '/download/issue%s_%s.diff' % (issue, patchset)) |
501 | 502 |
502 def SetIssue(self, issue): | 503 def SetIssue(self, issue): |
503 """Set this branch's issue. If issue=0, clears the issue.""" | 504 """Set this branch's issue. If issue=0, clears the issue.""" |
504 if issue: | 505 if issue: |
505 RunGit(['config', self._IssueSetting(), str(issue)]) | 506 RunGit(['config', self._IssueSetting(), str(issue)]) |
506 if self.rietveld_server: | 507 if self.rietveld_server: |
507 RunGit(['config', self._RietveldServer(), self.rietveld_server]) | 508 RunGit(['config', self._RietveldServer(), self.rietveld_server]) |
508 else: | 509 else: |
509 RunGit(['config', '--unset', self._IssueSetting()]) | 510 RunGit(['config', '--unset', self._IssueSetting()]) |
510 self.SetPatchset(0) | 511 self.SetPatchset(0) |
511 self.has_issue = False | 512 self.has_issue = False |
512 | 513 |
513 def CloseIssue(self): | 514 def CloseIssue(self): |
514 rpc_server = self._RpcServer() | 515 rpc_server = self.RpcServer() |
515 # Newer versions of Rietveld require us to pass an XSRF token to POST, so | 516 # Newer versions of Rietveld require us to pass an XSRF token to POST, so |
516 # we fetch it from the server. (The version used by Chromium has been | 517 # we fetch it from the server. (The version used by Chromium has been |
517 # modified so the token isn't required when closing an issue.) | 518 # modified so the token isn't required when closing an issue.) |
518 xsrf_token = rpc_server.Send('/xsrf_token', | 519 xsrf_token = rpc_server.Send('/xsrf_token', |
519 extra_headers={'X-Requesting-XSRF-Token': '1'}) | 520 extra_headers={'X-Requesting-XSRF-Token': '1'}) |
520 | 521 |
521 # You cannot close an issue with a GET. | 522 # You cannot close an issue with a GET. |
522 # We pass an empty string for the data so it is a POST rather than a GET. | 523 # We pass an empty string for the data so it is a POST rather than a GET. |
523 data = [("description", self.description), | 524 data = [("description", self.description), |
524 ("xsrf_token", xsrf_token)] | 525 ("xsrf_token", xsrf_token)] |
525 ctype, body = upload.EncodeMultipartFormData(data, []) | 526 ctype, body = upload.EncodeMultipartFormData(data, []) |
526 rpc_server.Send('/' + self.GetIssue() + '/close', body, ctype) | 527 rpc_server.Send( |
| 528 '/' + self.GetIssue() + '/close', payload=body, content_type=ctype) |
527 | 529 |
528 def _RpcServer(self): | 530 def RpcServer(self): |
529 """Returns an upload.RpcServer() to access this review's rietveld instance. | 531 """Returns an upload.RpcServer() to access this review's rietveld instance. |
530 """ | 532 """ |
531 if not self._rpc_server: | 533 if not self._rpc_server: |
532 server = self.GetRietveldServer() | 534 self.GetIssue() |
533 self._rpc_server = upload.GetRpcServer(server, save_cookies=True) | 535 self._rpc_server = rietveld.Rietveld(self.rietveld_server, None, None) |
534 return self._rpc_server | 536 return self._rpc_server |
535 | 537 |
536 def _IssueSetting(self): | 538 def _IssueSetting(self): |
537 """Return the git setting that stores this change's issue.""" | 539 """Return the git setting that stores this change's issue.""" |
538 return 'branch.%s.rietveldissue' % self.GetBranch() | 540 return 'branch.%s.rietveldissue' % self.GetBranch() |
539 | 541 |
540 def _PatchsetSetting(self): | 542 def _PatchsetSetting(self): |
541 """Return the git setting that stores this change's most recent patchset.""" | 543 """Return the git setting that stores this change's most recent patchset.""" |
542 return 'branch.%s.rietveldpatchset' % self.GetBranch() | 544 return 'branch.%s.rietveldpatchset' % self.GetBranch() |
543 | 545 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 # Apply watchlists on upload. | 843 # Apply watchlists on upload. |
842 if not committing: | 844 if not committing: |
843 watchlist = watchlists.Watchlists(change.RepositoryRoot()) | 845 watchlist = watchlists.Watchlists(change.RepositoryRoot()) |
844 files = [f.LocalPath() for f in change.AffectedFiles()] | 846 files = [f.LocalPath() for f in change.AffectedFiles()] |
845 cl.SetWatchers(watchlist.GetWatchersForPaths(files)) | 847 cl.SetWatchers(watchlist.GetWatchersForPaths(files)) |
846 | 848 |
847 try: | 849 try: |
848 output = presubmit_support.DoPresubmitChecks(change, committing, | 850 output = presubmit_support.DoPresubmitChecks(change, committing, |
849 verbose=verbose, output_stream=sys.stdout, input_stream=sys.stdin, | 851 verbose=verbose, output_stream=sys.stdout, input_stream=sys.stdin, |
850 default_presubmit=None, may_prompt=may_prompt, tbr=tbr, | 852 default_presubmit=None, may_prompt=may_prompt, tbr=tbr, |
851 host_url=cl.GetRietveldServer()) | 853 rietveld=cl.RpcServer()) |
852 except presubmit_support.PresubmitFailure, e: | 854 except presubmit_support.PresubmitFailure, e: |
853 DieWithError( | 855 DieWithError( |
854 ('%s\nMaybe your depot_tools is out of date?\n' | 856 ('%s\nMaybe your depot_tools is out of date?\n' |
855 'If all fails, contact maruel@') % e) | 857 'If all fails, contact maruel@') % e) |
856 | 858 |
857 # TODO(dpranke): We should propagate the error out instead of calling exit(). | 859 # TODO(dpranke): We should propagate the error out instead of calling exit(). |
858 if not output.should_continue(): | 860 if not output.should_continue(): |
859 sys.exit(1) | 861 sys.exit(1) |
860 | 862 |
861 return output | 863 return output |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1443 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 1445 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
1444 | 1446 |
1445 # Not a known command. Default to help. | 1447 # Not a known command. Default to help. |
1446 GenUsage(parser, 'help') | 1448 GenUsage(parser, 'help') |
1447 return CMDhelp(parser, argv) | 1449 return CMDhelp(parser, argv) |
1448 | 1450 |
1449 | 1451 |
1450 if __name__ == '__main__': | 1452 if __name__ == '__main__': |
1451 fix_encoding.fix_encoding() | 1453 fix_encoding.fix_encoding() |
1452 sys.exit(main(sys.argv[1:])) | 1454 sys.exit(main(sys.argv[1:])) |
OLD | NEW |