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

Side by Side Diff: git_cl.py

Issue 7084037: Add commit_queue.py tool to toggle the bit of the commit queue from command line (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: prefer --use-commit-queue Created 9 years, 6 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 | « commit_queue.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 # 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 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 self.GetIssue() 456 self.GetIssue()
457 return self.rietveld_server 457 return self.rietveld_server
458 458
459 def GetIssueURL(self): 459 def GetIssueURL(self):
460 """Get the URL for a particular issue.""" 460 """Get the URL for a particular issue."""
461 return '%s/%s' % (self.GetRietveldServer(), self.GetIssue()) 461 return '%s/%s' % (self.GetRietveldServer(), self.GetIssue())
462 462
463 def GetDescription(self, pretty=False): 463 def GetDescription(self, pretty=False):
464 if not self.has_description: 464 if not self.has_description:
465 if self.GetIssue(): 465 if self.GetIssue():
466 path = '/' + self.GetIssue() + '/description' 466 self.description = self.RpcServer().get_description(
467 rpc_server = self.RpcServer() 467 int(self.GetIssue())).strip()
468 self.description = rpc_server.Send(path).strip()
469 self.has_description = True 468 self.has_description = True
470 if pretty: 469 if pretty:
471 wrapper = textwrap.TextWrapper() 470 wrapper = textwrap.TextWrapper()
472 wrapper.initial_indent = wrapper.subsequent_indent = ' ' 471 wrapper.initial_indent = wrapper.subsequent_indent = ' '
473 return wrapper.fill(self.description) 472 return wrapper.fill(self.description)
474 return self.description 473 return self.description
475 474
476 def GetPatchset(self): 475 def GetPatchset(self):
477 if not self.has_patchset: 476 if not self.has_patchset:
478 patchset = RunGit(['config', self._PatchsetSetting()], 477 patchset = RunGit(['config', self._PatchsetSetting()],
479 error_ok=True).strip() 478 error_ok=True).strip()
480 if patchset: 479 if patchset:
481 self.patchset = patchset 480 self.patchset = patchset
482 else: 481 else:
483 self.patchset = None 482 self.patchset = None
484 self.has_patchset = True 483 self.has_patchset = True
485 return self.patchset 484 return self.patchset
486 485
487 def SetPatchset(self, patchset): 486 def SetPatchset(self, patchset):
488 """Set this branch's patchset. If patchset=0, clears the patchset.""" 487 """Set this branch's patchset. If patchset=0, clears the patchset."""
489 if patchset: 488 if patchset:
490 RunGit(['config', self._PatchsetSetting(), str(patchset)]) 489 RunGit(['config', self._PatchsetSetting(), str(patchset)])
491 else: 490 else:
492 RunGit(['config', '--unset', self._PatchsetSetting()], 491 RunGit(['config', '--unset', self._PatchsetSetting()],
493 swallow_stderr=True, error_ok=True) 492 swallow_stderr=True, error_ok=True)
494 self.has_patchset = False 493 self.has_patchset = False
495 494
496 def GetPatchSetDiff(self, issue): 495 def GetPatchSetDiff(self, issue):
497 # Grab the last patchset of the issue first. 496 patchset = self.RpcServer().get_issue_properties(
498 data = json.loads(self.RpcServer().Send('/api/%s' % issue)) 497 int(issue), False)['patchsets'][-1]
499 patchset = data['patchsets'][-1] 498 return self.RpcServer().get(
500 return self.RpcServer().Send(
501 '/download/issue%s_%s.diff' % (issue, patchset)) 499 '/download/issue%s_%s.diff' % (issue, patchset))
502 500
503 def SetIssue(self, issue): 501 def SetIssue(self, issue):
504 """Set this branch's issue. If issue=0, clears the issue.""" 502 """Set this branch's issue. If issue=0, clears the issue."""
505 if issue: 503 if issue:
506 RunGit(['config', self._IssueSetting(), str(issue)]) 504 RunGit(['config', self._IssueSetting(), str(issue)])
507 if self.rietveld_server: 505 if self.rietveld_server:
508 RunGit(['config', self._RietveldServer(), self.rietveld_server]) 506 RunGit(['config', self._RietveldServer(), self.rietveld_server])
509 else: 507 else:
510 RunGit(['config', '--unset', self._IssueSetting()]) 508 RunGit(['config', '--unset', self._IssueSetting()])
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 'If all fails, contact maruel@') % e) 555 'If all fails, contact maruel@') % e)
558 556
559 # TODO(dpranke): We should propagate the error out instead of calling 557 # TODO(dpranke): We should propagate the error out instead of calling
560 # exit(). 558 # exit().
561 if not output.should_continue(): 559 if not output.should_continue():
562 sys.exit(1) 560 sys.exit(1)
563 561
564 return output 562 return output
565 563
566 def CloseIssue(self): 564 def CloseIssue(self):
567 rpc_server = self.RpcServer() 565 return self.RpcServer().close_issue(int(self.GetIssue()))
568 # Newer versions of Rietveld require us to pass an XSRF token to POST, so
569 # we fetch it from the server. (The version used by Chromium has been
570 # modified so the token isn't required when closing an issue.)
571 xsrf_token = rpc_server.Send('/xsrf_token',
572 extra_headers={'X-Requesting-XSRF-Token': '1'})
573 566
574 # You cannot close an issue with a GET. 567 def SetFlag(self, flag, value):
575 # We pass an empty string for the data so it is a POST rather than a GET. 568 """Patchset must match."""
576 data = [("description", self.description), 569 if not self.GetPatchset():
577 ("xsrf_token", xsrf_token)] 570 DieWithError('The patchset needs to match. Send another patchset.')
578 ctype, body = upload.EncodeMultipartFormData(data, []) 571 try:
579 rpc_server.Send( 572 return self.RpcServer().set_flag(
580 '/' + self.GetIssue() + '/close', payload=body, content_type=ctype) 573 int(self.GetIssue()), int(self.GetPatchset()), flag, value)
574 except urllib2.HTTPError, e:
575 if e.code == 404:
576 DieWithError('The issue %s doesn\'t exist.' % self.GetIssue())
577 if e.code == 403:
578 DieWithError(
579 ('Access denied to issue %s. Maybe the patchset %s doesn\'t '
580 'match?') % (self.GetIssue(), self.GetPatchset()))
581 raise
581 582
582 def RpcServer(self): 583 def RpcServer(self):
583 """Returns an upload.RpcServer() to access this review's rietveld instance. 584 """Returns an upload.RpcServer() to access this review's rietveld instance.
584 """ 585 """
585 if not self._rpc_server: 586 if not self._rpc_server:
586 self.GetIssue() 587 self.GetIssue()
587 self._rpc_server = rietveld.Rietveld(self.rietveld_server, None, None) 588 self._rpc_server = rietveld.Rietveld(self.rietveld_server, None, None)
588 return self._rpc_server 589 return self._rpc_server
589 590
590 def _IssueSetting(self): 591 def _IssueSetting(self):
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 help='cc email addresses') 907 help='cc email addresses')
907 parser.add_option('--send-mail', action='store_true', 908 parser.add_option('--send-mail', action='store_true',
908 help='send email to reviewer immediately') 909 help='send email to reviewer immediately')
909 parser.add_option("--emulate_svn_auto_props", action="store_true", 910 parser.add_option("--emulate_svn_auto_props", action="store_true",
910 dest="emulate_svn_auto_props", 911 dest="emulate_svn_auto_props",
911 help="Emulate Subversion's auto properties feature.") 912 help="Emulate Subversion's auto properties feature.")
912 parser.add_option("--desc_from_logs", action="store_true", 913 parser.add_option("--desc_from_logs", action="store_true",
913 dest="from_logs", 914 dest="from_logs",
914 help="""Squashes git commit logs into change description and 915 help="""Squashes git commit logs into change description and
915 uses message as subject""") 916 uses message as subject""")
917 parser.add_option('-c', '--use-commit-queue', action='store_true',
918 help='tell the commit queue to commit this patchset')
916 (options, args) = parser.parse_args(args) 919 (options, args) = parser.parse_args(args)
917 920
918 # Make sure index is up-to-date before running diff-index. 921 # Make sure index is up-to-date before running diff-index.
919 RunGit(['update-index', '--refresh', '-q'], error_ok=True) 922 RunGit(['update-index', '--refresh', '-q'], error_ok=True)
920 if RunGit(['diff-index', 'HEAD']): 923 if RunGit(['diff-index', 'HEAD']):
921 print 'Cannot upload with a dirty tree. You must commit locally first.' 924 print 'Cannot upload with a dirty tree. You must commit locally first.'
922 return 1 925 return 1
923 926
924 cl = Changelist() 927 cl = Changelist()
925 if args: 928 if args:
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 print '\nGot exception while uploading -- saving description to %s\n' \ 1017 print '\nGot exception while uploading -- saving description to %s\n' \
1015 % backup_path 1018 % backup_path
1016 backup_file = open(backup_path, 'w') 1019 backup_file = open(backup_path, 'w')
1017 backup_file.write(change_desc.description) 1020 backup_file.write(change_desc.description)
1018 backup_file.close() 1021 backup_file.close()
1019 raise 1022 raise
1020 1023
1021 if not cl.GetIssue(): 1024 if not cl.GetIssue():
1022 cl.SetIssue(issue) 1025 cl.SetIssue(issue)
1023 cl.SetPatchset(patchset) 1026 cl.SetPatchset(patchset)
1027
1028 if options.use_commit_queue:
1029 cl.SetFlag('commit', '1')
1024 return 0 1030 return 0
1025 1031
1026 1032
1027 def SendUpstream(parser, args, cmd): 1033 def SendUpstream(parser, args, cmd):
1028 """Common code for CmdPush and CmdDCommit 1034 """Common code for CmdPush and CmdDCommit
1029 1035
1030 Squashed commit into a single. 1036 Squashed commit into a single.
1031 Updates changelog with metadata (e.g. pointer to review). 1037 Updates changelog with metadata (e.g. pointer to review).
1032 Pushes/dcommits the code upstream. 1038 Pushes/dcommits the code upstream.
1033 Updates review and closes. 1039 Updates review and closes.
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 parser.add_option('--reject', action='store_true', dest='reject', 1264 parser.add_option('--reject', action='store_true', dest='reject',
1259 help='allow failed patches and spew .rej files') 1265 help='allow failed patches and spew .rej files')
1260 parser.add_option('-n', '--no-commit', action='store_true', dest='nocommit', 1266 parser.add_option('-n', '--no-commit', action='store_true', dest='nocommit',
1261 help="don't commit after patch applies") 1267 help="don't commit after patch applies")
1262 (options, args) = parser.parse_args(args) 1268 (options, args) = parser.parse_args(args)
1263 if len(args) != 1: 1269 if len(args) != 1:
1264 parser.print_help() 1270 parser.print_help()
1265 return 1 1271 return 1
1266 issue_arg = args[0] 1272 issue_arg = args[0]
1267 1273
1274 # TODO(maruel): Use apply_issue.py
1275
1268 if re.match(r'\d+', issue_arg): 1276 if re.match(r'\d+', issue_arg):
1269 # Input is an issue id. Figure out the URL. 1277 # Input is an issue id. Figure out the URL.
1270 issue = issue_arg 1278 issue = issue_arg
1271 patch_data = Changelist().GetPatchSetDiff(issue) 1279 patch_data = Changelist().GetPatchSetDiff(issue)
1272 else: 1280 else:
1273 # Assume it's a URL to the patch. Default to http. 1281 # Assume it's a URL to the patch. Default to http.
1274 issue_url = FixUrl(issue_arg) 1282 issue_url = FixUrl(issue_arg)
1275 match = re.match(r'.*?/issue(\d+)_\d+.diff', issue_url) 1283 match = re.match(r'.*?/issue(\d+)_\d+.diff', issue_url)
1276 if not match: 1284 if not match:
1277 DieWithError('Must pass an issue ID or full URL for ' 1285 DieWithError('Must pass an issue ID or full URL for '
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 print 1379 print
1372 print GetTreeStatusReason() 1380 print GetTreeStatusReason()
1373 if status != 'open': 1381 if status != 'open':
1374 return 1 1382 return 1
1375 return 0 1383 return 0
1376 1384
1377 1385
1378 def CMDupstream(parser, args): 1386 def CMDupstream(parser, args):
1379 """print the name of the upstream branch, if any""" 1387 """print the name of the upstream branch, if any"""
1380 _, args = parser.parse_args(args) 1388 _, args = parser.parse_args(args)
1389 if args:
1390 parser.error('Unrecognized args: %s' % ' '.join(args))
1381 cl = Changelist() 1391 cl = Changelist()
1382 print cl.GetUpstreamBranch() 1392 print cl.GetUpstreamBranch()
1383 return 0 1393 return 0
1384 1394
1385 1395
1396 def CMDset_commit(parser, args):
1397 """set the commit bit"""
1398 _, args = parser.parse_args(args)
1399 if args:
1400 parser.error('Unrecognized args: %s' % ' '.join(args))
1401 cl = Changelist()
1402 cl.SetFlag('commit', '1')
1403 return 0
1404
1405
1386 def Command(name): 1406 def Command(name):
1387 return getattr(sys.modules[__name__], 'CMD' + name, None) 1407 return getattr(sys.modules[__name__], 'CMD' + name, None)
1388 1408
1389 1409
1390 def CMDhelp(parser, args): 1410 def CMDhelp(parser, args):
1391 """print list of commands or help for a specific command""" 1411 """print list of commands or help for a specific command"""
1392 _, args = parser.parse_args(args) 1412 _, args = parser.parse_args(args)
1393 if len(args) == 1: 1413 if len(args) == 1:
1394 return main(args + ['--help']) 1414 return main(args + ['--help'])
1395 parser.print_help() 1415 parser.print_help()
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) 1468 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e)))
1449 1469
1450 # Not a known command. Default to help. 1470 # Not a known command. Default to help.
1451 GenUsage(parser, 'help') 1471 GenUsage(parser, 'help')
1452 return CMDhelp(parser, argv) 1472 return CMDhelp(parser, argv)
1453 1473
1454 1474
1455 if __name__ == '__main__': 1475 if __name__ == '__main__':
1456 fix_encoding.fix_encoding() 1476 fix_encoding.fix_encoding()
1457 sys.exit(main(sys.argv[1:])) 1477 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « commit_queue.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698