OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 from distutils.version import LooseVersion | 10 from distutils.version import LooseVersion |
(...skipping 16 matching lines...) Expand all Loading... |
27 import zlib | 27 import zlib |
28 | 28 |
29 try: | 29 try: |
30 import readline # pylint: disable=F0401,W0611 | 30 import readline # pylint: disable=F0401,W0611 |
31 except ImportError: | 31 except ImportError: |
32 pass | 32 pass |
33 | 33 |
34 | 34 |
35 from third_party import colorama | 35 from third_party import colorama |
36 from third_party import upload | 36 from third_party import upload |
| 37 import auth |
37 import breakpad # pylint: disable=W0611 | 38 import breakpad # pylint: disable=W0611 |
38 import clang_format | 39 import clang_format |
39 import dart_format | 40 import dart_format |
40 import fix_encoding | 41 import fix_encoding |
41 import gclient_utils | 42 import gclient_utils |
42 import git_common | 43 import git_common |
43 import owners | 44 import owners |
44 import owners_finder | 45 import owners_finder |
45 import presubmit_support | 46 import presubmit_support |
46 import rietveld | 47 import rietveld |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 self.LazyUpdateIfNeeded() | 492 self.LazyUpdateIfNeeded() |
492 return RunGit(['config', param], **kwargs).strip() | 493 return RunGit(['config', param], **kwargs).strip() |
493 | 494 |
494 | 495 |
495 def ShortBranchName(branch): | 496 def ShortBranchName(branch): |
496 """Convert a name like 'refs/heads/foo' to just 'foo'.""" | 497 """Convert a name like 'refs/heads/foo' to just 'foo'.""" |
497 return branch.replace('refs/heads/', '') | 498 return branch.replace('refs/heads/', '') |
498 | 499 |
499 | 500 |
500 class Changelist(object): | 501 class Changelist(object): |
501 def __init__(self, branchref=None, issue=None): | 502 def __init__(self, branchref=None, issue=None, auth_config=None): |
502 # Poke settings so we get the "configure your server" message if necessary. | 503 # Poke settings so we get the "configure your server" message if necessary. |
503 global settings | 504 global settings |
504 if not settings: | 505 if not settings: |
505 # Happens when git_cl.py is used as a utility library. | 506 # Happens when git_cl.py is used as a utility library. |
506 settings = Settings() | 507 settings = Settings() |
507 settings.GetDefaultServerUrl() | 508 settings.GetDefaultServerUrl() |
508 self.branchref = branchref | 509 self.branchref = branchref |
509 if self.branchref: | 510 if self.branchref: |
510 self.branch = ShortBranchName(self.branchref) | 511 self.branch = ShortBranchName(self.branchref) |
511 else: | 512 else: |
512 self.branch = None | 513 self.branch = None |
513 self.rietveld_server = None | 514 self.rietveld_server = None |
514 self.upstream_branch = None | 515 self.upstream_branch = None |
515 self.lookedup_issue = False | 516 self.lookedup_issue = False |
516 self.issue = issue or None | 517 self.issue = issue or None |
517 self.has_description = False | 518 self.has_description = False |
518 self.description = None | 519 self.description = None |
519 self.lookedup_patchset = False | 520 self.lookedup_patchset = False |
520 self.patchset = None | 521 self.patchset = None |
521 self._rpc_server = None | |
522 self.cc = None | 522 self.cc = None |
523 self.watchers = () | 523 self.watchers = () |
| 524 self._auth_config = auth_config |
| 525 self._props = None |
524 self._remote = None | 526 self._remote = None |
525 self._props = None | 527 self._rpc_server = None |
| 528 |
| 529 @property |
| 530 def auth_config(self): |
| 531 return self._auth_config |
526 | 532 |
527 def GetCCList(self): | 533 def GetCCList(self): |
528 """Return the users cc'd on this CL. | 534 """Return the users cc'd on this CL. |
529 | 535 |
530 Return is a string suitable for passing to gcl with the --cc flag. | 536 Return is a string suitable for passing to gcl with the --cc flag. |
531 """ | 537 """ |
532 if self.cc is None: | 538 if self.cc is None: |
533 base_cc = settings.GetDefaultCCList() | 539 base_cc = settings.GetDefaultCCList() |
534 more_cc = ','.join(self.watchers) | 540 more_cc = ','.join(self.watchers) |
535 self.cc = ','.join(filter(None, (base_cc, more_cc))) or '' | 541 self.cc = ','.join(filter(None, (base_cc, more_cc))) or '' |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 DieWithError( | 984 DieWithError( |
979 ('Access denied to issue %s. Maybe the patchset %s doesn\'t ' | 985 ('Access denied to issue %s. Maybe the patchset %s doesn\'t ' |
980 'match?') % (self.GetIssue(), self.GetPatchset())) | 986 'match?') % (self.GetIssue(), self.GetPatchset())) |
981 raise | 987 raise |
982 | 988 |
983 def RpcServer(self): | 989 def RpcServer(self): |
984 """Returns an upload.RpcServer() to access this review's rietveld instance. | 990 """Returns an upload.RpcServer() to access this review's rietveld instance. |
985 """ | 991 """ |
986 if not self._rpc_server: | 992 if not self._rpc_server: |
987 self._rpc_server = rietveld.CachingRietveld( | 993 self._rpc_server = rietveld.CachingRietveld( |
988 self.GetRietveldServer(), None, None) | 994 self.GetRietveldServer(), |
| 995 self._auth_config or auth.make_auth_config()) |
989 return self._rpc_server | 996 return self._rpc_server |
990 | 997 |
991 def _IssueSetting(self): | 998 def _IssueSetting(self): |
992 """Return the git setting that stores this change's issue.""" | 999 """Return the git setting that stores this change's issue.""" |
993 return 'branch.%s.rietveldissue' % self.GetBranch() | 1000 return 'branch.%s.rietveldissue' % self.GetBranch() |
994 | 1001 |
995 def _PatchsetSetting(self): | 1002 def _PatchsetSetting(self): |
996 """Return the git setting that stores this change's most recent patchset.""" | 1003 """Return the git setting that stores this change's most recent patchset.""" |
997 return 'branch.%s.rietveldpatchset' % self.GetBranch() | 1004 return 'branch.%s.rietveldpatchset' % self.GetBranch() |
998 | 1005 |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1335 return { | 1342 return { |
1336 'unsent': Fore.RED, | 1343 'unsent': Fore.RED, |
1337 'waiting': Fore.BLUE, | 1344 'waiting': Fore.BLUE, |
1338 'reply': Fore.YELLOW, | 1345 'reply': Fore.YELLOW, |
1339 'lgtm': Fore.GREEN, | 1346 'lgtm': Fore.GREEN, |
1340 'commit': Fore.MAGENTA, | 1347 'commit': Fore.MAGENTA, |
1341 'closed': Fore.CYAN, | 1348 'closed': Fore.CYAN, |
1342 'error': Fore.WHITE, | 1349 'error': Fore.WHITE, |
1343 }.get(status, Fore.WHITE) | 1350 }.get(status, Fore.WHITE) |
1344 | 1351 |
1345 def fetch_cl_status(b): | 1352 def fetch_cl_status(b, auth_config=None): |
1346 """Fetches information for an issue and returns (branch, issue, color).""" | 1353 """Fetches information for an issue and returns (branch, issue, color).""" |
1347 c = Changelist(branchref=b) | 1354 c = Changelist(branchref=b, auth_config=auth_config) |
1348 i = c.GetIssueURL() | 1355 i = c.GetIssueURL() |
1349 status = c.GetStatus() | 1356 status = c.GetStatus() |
1350 color = color_for_status(status) | 1357 color = color_for_status(status) |
1351 | 1358 |
1352 if i and (not status or status == 'error'): | 1359 if i and (not status or status == 'error'): |
1353 # The issue probably doesn't exist anymore. | 1360 # The issue probably doesn't exist anymore. |
1354 i += ' (broken)' | 1361 i += ' (broken)' |
1355 | 1362 |
1356 return (b, i, color) | 1363 return (b, i, color) |
1357 | 1364 |
1358 def get_cl_statuses(branches, fine_grained, max_processes=None): | 1365 def get_cl_statuses( |
| 1366 branches, fine_grained, max_processes=None, auth_config=None): |
1359 """Returns a blocking iterable of (branch, issue, color) for given branches. | 1367 """Returns a blocking iterable of (branch, issue, color) for given branches. |
1360 | 1368 |
1361 If fine_grained is true, this will fetch CL statuses from the server. | 1369 If fine_grained is true, this will fetch CL statuses from the server. |
1362 Otherwise, simply indicate if there's a matching url for the given branches. | 1370 Otherwise, simply indicate if there's a matching url for the given branches. |
1363 | 1371 |
1364 If max_processes is specified, it is used as the maximum number of processes | 1372 If max_processes is specified, it is used as the maximum number of processes |
1365 to spawn to fetch CL status from the server. Otherwise 1 process per branch is | 1373 to spawn to fetch CL status from the server. Otherwise 1 process per branch is |
1366 spawned. | 1374 spawned. |
1367 """ | 1375 """ |
1368 # Silence upload.py otherwise it becomes unwieldly. | 1376 # Silence upload.py otherwise it becomes unwieldly. |
1369 upload.verbosity = 0 | 1377 upload.verbosity = 0 |
1370 | 1378 |
1371 if fine_grained: | 1379 if fine_grained: |
1372 # Process one branch synchronously to work through authentication, then | 1380 # Process one branch synchronously to work through authentication, then |
1373 # spawn processes to process all the other branches in parallel. | 1381 # spawn processes to process all the other branches in parallel. |
1374 if branches: | 1382 if branches: |
1375 yield fetch_cl_status(branches[0]) | 1383 fetch = lambda branch: fetch_cl_status(branch, auth_config=auth_config) |
| 1384 yield fetch(branches[0]) |
1376 | 1385 |
1377 branches_to_fetch = branches[1:] | 1386 branches_to_fetch = branches[1:] |
1378 pool = ThreadPool( | 1387 pool = ThreadPool( |
1379 min(max_processes, len(branches_to_fetch)) | 1388 min(max_processes, len(branches_to_fetch)) |
1380 if max_processes is not None | 1389 if max_processes is not None |
1381 else len(branches_to_fetch)) | 1390 else len(branches_to_fetch)) |
1382 for x in pool.imap_unordered(fetch_cl_status, branches_to_fetch): | 1391 for x in pool.imap_unordered(fetch, branches_to_fetch): |
1383 yield x | 1392 yield x |
1384 else: | 1393 else: |
1385 # Do not use GetApprovingReviewers(), since it requires an HTTP request. | 1394 # Do not use GetApprovingReviewers(), since it requires an HTTP request. |
1386 for b in branches: | 1395 for b in branches: |
1387 c = Changelist(branchref=b) | 1396 c = Changelist(branchref=b, auth_config=auth_config) |
1388 url = c.GetIssueURL() | 1397 url = c.GetIssueURL() |
1389 yield (b, url, Fore.BLUE if url else Fore.WHITE) | 1398 yield (b, url, Fore.BLUE if url else Fore.WHITE) |
1390 | 1399 |
1391 def CMDstatus(parser, args): | 1400 def CMDstatus(parser, args): |
1392 """Show status of changelists. | 1401 """Show status of changelists. |
1393 | 1402 |
1394 Colors are used to tell the state of the CL unless --fast is used: | 1403 Colors are used to tell the state of the CL unless --fast is used: |
1395 - Red not sent for review or broken | 1404 - Red not sent for review or broken |
1396 - Blue waiting for review | 1405 - Blue waiting for review |
1397 - Yellow waiting for you to reply to review | 1406 - Yellow waiting for you to reply to review |
1398 - Green LGTM'ed | 1407 - Green LGTM'ed |
1399 - Magenta in the commit queue | 1408 - Magenta in the commit queue |
1400 - Cyan was committed, branch can be deleted | 1409 - Cyan was committed, branch can be deleted |
1401 | 1410 |
1402 Also see 'git cl comments'. | 1411 Also see 'git cl comments'. |
1403 """ | 1412 """ |
1404 parser.add_option('--field', | 1413 parser.add_option('--field', |
1405 help='print only specific field (desc|id|patch|url)') | 1414 help='print only specific field (desc|id|patch|url)') |
1406 parser.add_option('-f', '--fast', action='store_true', | 1415 parser.add_option('-f', '--fast', action='store_true', |
1407 help='Do not retrieve review status') | 1416 help='Do not retrieve review status') |
1408 parser.add_option( | 1417 parser.add_option( |
1409 '-j', '--maxjobs', action='store', type=int, | 1418 '-j', '--maxjobs', action='store', type=int, |
1410 help='The maximum number of jobs to use when retrieving review status') | 1419 help='The maximum number of jobs to use when retrieving review status') |
1411 (options, args) = parser.parse_args(args) | 1420 |
| 1421 auth.add_auth_options(parser) |
| 1422 options, args = parser.parse_args(args) |
1412 if args: | 1423 if args: |
1413 parser.error('Unsupported args: %s' % args) | 1424 parser.error('Unsupported args: %s' % args) |
| 1425 auth_config = auth.extract_auth_config_from_options(options) |
1414 | 1426 |
1415 if options.field: | 1427 if options.field: |
1416 cl = Changelist() | 1428 cl = Changelist(auth_config=auth_config) |
1417 if options.field.startswith('desc'): | 1429 if options.field.startswith('desc'): |
1418 print cl.GetDescription() | 1430 print cl.GetDescription() |
1419 elif options.field == 'id': | 1431 elif options.field == 'id': |
1420 issueid = cl.GetIssue() | 1432 issueid = cl.GetIssue() |
1421 if issueid: | 1433 if issueid: |
1422 print issueid | 1434 print issueid |
1423 elif options.field == 'patch': | 1435 elif options.field == 'patch': |
1424 patchset = cl.GetPatchset() | 1436 patchset = cl.GetPatchset() |
1425 if patchset: | 1437 if patchset: |
1426 print patchset | 1438 print patchset |
1427 elif options.field == 'url': | 1439 elif options.field == 'url': |
1428 url = cl.GetIssueURL() | 1440 url = cl.GetIssueURL() |
1429 if url: | 1441 if url: |
1430 print url | 1442 print url |
1431 return 0 | 1443 return 0 |
1432 | 1444 |
1433 branches = RunGit(['for-each-ref', '--format=%(refname)', 'refs/heads']) | 1445 branches = RunGit(['for-each-ref', '--format=%(refname)', 'refs/heads']) |
1434 if not branches: | 1446 if not branches: |
1435 print('No local branch found.') | 1447 print('No local branch found.') |
1436 return 0 | 1448 return 0 |
1437 | 1449 |
1438 changes = (Changelist(branchref=b) for b in branches.splitlines()) | 1450 changes = ( |
| 1451 Changelist(branchref=b, auth_config=auth_config) |
| 1452 for b in branches.splitlines()) |
1439 branches = [c.GetBranch() for c in changes] | 1453 branches = [c.GetBranch() for c in changes] |
1440 alignment = max(5, max(len(b) for b in branches)) | 1454 alignment = max(5, max(len(b) for b in branches)) |
1441 print 'Branches associated with reviews:' | 1455 print 'Branches associated with reviews:' |
1442 output = get_cl_statuses(branches, | 1456 output = get_cl_statuses(branches, |
1443 fine_grained=not options.fast, | 1457 fine_grained=not options.fast, |
1444 max_processes=options.maxjobs) | 1458 max_processes=options.maxjobs, |
| 1459 auth_config=auth_config) |
1445 | 1460 |
1446 branch_statuses = {} | 1461 branch_statuses = {} |
1447 alignment = max(5, max(len(ShortBranchName(b)) for b in branches)) | 1462 alignment = max(5, max(len(ShortBranchName(b)) for b in branches)) |
1448 for branch in sorted(branches): | 1463 for branch in sorted(branches): |
1449 while branch not in branch_statuses: | 1464 while branch not in branch_statuses: |
1450 b, i, color = output.next() | 1465 b, i, color = output.next() |
1451 branch_statuses[b] = (i, color) | 1466 branch_statuses[b] = (i, color) |
1452 issue, color = branch_statuses.pop(branch) | 1467 issue, color = branch_statuses.pop(branch) |
1453 reset = Fore.RESET | 1468 reset = Fore.RESET |
1454 if not sys.stdout.isatty(): | 1469 if not sys.stdout.isatty(): |
1455 color = '' | 1470 color = '' |
1456 reset = '' | 1471 reset = '' |
1457 print ' %*s : %s%s%s' % ( | 1472 print ' %*s : %s%s%s' % ( |
1458 alignment, ShortBranchName(branch), color, issue, reset) | 1473 alignment, ShortBranchName(branch), color, issue, reset) |
1459 | 1474 |
1460 cl = Changelist() | 1475 cl = Changelist(auth_config=auth_config) |
1461 print | 1476 print |
1462 print 'Current branch:', | 1477 print 'Current branch:', |
1463 if not cl.GetIssue(): | 1478 if not cl.GetIssue(): |
1464 print 'no issue assigned.' | 1479 print 'no issue assigned.' |
1465 return 0 | 1480 return 0 |
1466 print cl.GetBranch() | 1481 print cl.GetBranch() |
1467 print 'Issue number: %s (%s)' % (cl.GetIssue(), cl.GetIssueURL()) | 1482 print 'Issue number: %s (%s)' % (cl.GetIssue(), cl.GetIssueURL()) |
1468 if not options.fast: | 1483 if not options.fast: |
1469 print 'Issue description:' | 1484 print 'Issue description:' |
1470 print cl.GetDescription(pretty=True) | 1485 print cl.GetDescription(pretty=True) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1527 print 'Issue number: %s (%s)' % (cl.GetIssue(), cl.GetIssueURL()) | 1542 print 'Issue number: %s (%s)' % (cl.GetIssue(), cl.GetIssueURL()) |
1528 return 0 | 1543 return 0 |
1529 | 1544 |
1530 | 1545 |
1531 def CMDcomments(parser, args): | 1546 def CMDcomments(parser, args): |
1532 """Shows or posts review comments for any changelist.""" | 1547 """Shows or posts review comments for any changelist.""" |
1533 parser.add_option('-a', '--add-comment', dest='comment', | 1548 parser.add_option('-a', '--add-comment', dest='comment', |
1534 help='comment to add to an issue') | 1549 help='comment to add to an issue') |
1535 parser.add_option('-i', dest='issue', | 1550 parser.add_option('-i', dest='issue', |
1536 help="review issue id (defaults to current issue)") | 1551 help="review issue id (defaults to current issue)") |
| 1552 auth.add_auth_options(parser) |
1537 options, args = parser.parse_args(args) | 1553 options, args = parser.parse_args(args) |
| 1554 auth_config = auth.extract_auth_config_from_options(options) |
1538 | 1555 |
1539 issue = None | 1556 issue = None |
1540 if options.issue: | 1557 if options.issue: |
1541 try: | 1558 try: |
1542 issue = int(options.issue) | 1559 issue = int(options.issue) |
1543 except ValueError: | 1560 except ValueError: |
1544 DieWithError('A review issue id is expected to be a number') | 1561 DieWithError('A review issue id is expected to be a number') |
1545 | 1562 |
1546 cl = Changelist(issue=issue) | 1563 cl = Changelist(issue=issue, auth_config=auth_config) |
1547 | 1564 |
1548 if options.comment: | 1565 if options.comment: |
1549 cl.AddComment(options.comment) | 1566 cl.AddComment(options.comment) |
1550 return 0 | 1567 return 0 |
1551 | 1568 |
1552 data = cl.GetIssueProperties() | 1569 data = cl.GetIssueProperties() |
1553 for message in sorted(data.get('messages', []), key=lambda x: x['date']): | 1570 for message in sorted(data.get('messages', []), key=lambda x: x['date']): |
1554 if message['disapproval']: | 1571 if message['disapproval']: |
1555 color = Fore.RED | 1572 color = Fore.RED |
1556 elif message['approval']: | 1573 elif message['approval']: |
1557 color = Fore.GREEN | 1574 color = Fore.GREEN |
1558 elif message['sender'] == data['owner_email']: | 1575 elif message['sender'] == data['owner_email']: |
1559 color = Fore.MAGENTA | 1576 color = Fore.MAGENTA |
1560 else: | 1577 else: |
1561 color = Fore.BLUE | 1578 color = Fore.BLUE |
1562 print '\n%s%s %s%s' % ( | 1579 print '\n%s%s %s%s' % ( |
1563 color, message['date'].split('.', 1)[0], message['sender'], | 1580 color, message['date'].split('.', 1)[0], message['sender'], |
1564 Fore.RESET) | 1581 Fore.RESET) |
1565 if message['text'].strip(): | 1582 if message['text'].strip(): |
1566 print '\n'.join(' ' + l for l in message['text'].splitlines()) | 1583 print '\n'.join(' ' + l for l in message['text'].splitlines()) |
1567 return 0 | 1584 return 0 |
1568 | 1585 |
1569 | 1586 |
1570 def CMDdescription(parser, args): | 1587 def CMDdescription(parser, args): |
1571 """Brings up the editor for the current CL's description.""" | 1588 """Brings up the editor for the current CL's description.""" |
1572 parser.parse_args(args) | 1589 auth.add_auth_options(parser) |
1573 cl = Changelist() | 1590 options, _ = parser.parse_args(args) |
| 1591 auth_config = auth.extract_auth_config_from_options(options) |
| 1592 cl = Changelist(auth_config=auth_config) |
1574 if not cl.GetIssue(): | 1593 if not cl.GetIssue(): |
1575 DieWithError('This branch has no associated changelist.') | 1594 DieWithError('This branch has no associated changelist.') |
1576 description = ChangeDescription(cl.GetDescription()) | 1595 description = ChangeDescription(cl.GetDescription()) |
1577 description.prompt() | 1596 description.prompt() |
1578 if cl.GetDescription() != description.description: | 1597 if cl.GetDescription() != description.description: |
1579 cl.UpdateDescription(description.description) | 1598 cl.UpdateDescription(description.description) |
1580 return 0 | 1599 return 0 |
1581 | 1600 |
1582 | 1601 |
1583 def CreateDescriptionFromLog(args): | 1602 def CreateDescriptionFromLog(args): |
1584 """Pulls out the commit log to use as a base for the CL description.""" | 1603 """Pulls out the commit log to use as a base for the CL description.""" |
1585 log_args = [] | 1604 log_args = [] |
1586 if len(args) == 1 and not args[0].endswith('.'): | 1605 if len(args) == 1 and not args[0].endswith('.'): |
1587 log_args = [args[0] + '..'] | 1606 log_args = [args[0] + '..'] |
1588 elif len(args) == 1 and args[0].endswith('...'): | 1607 elif len(args) == 1 and args[0].endswith('...'): |
1589 log_args = [args[0][:-1]] | 1608 log_args = [args[0][:-1]] |
1590 elif len(args) == 2: | 1609 elif len(args) == 2: |
1591 log_args = [args[0] + '..' + args[1]] | 1610 log_args = [args[0] + '..' + args[1]] |
1592 else: | 1611 else: |
1593 log_args = args[:] # Hope for the best! | 1612 log_args = args[:] # Hope for the best! |
1594 return RunGit(['log', '--pretty=format:%s\n\n%b'] + log_args) | 1613 return RunGit(['log', '--pretty=format:%s\n\n%b'] + log_args) |
1595 | 1614 |
1596 | 1615 |
1597 def CMDlint(parser, args): | 1616 def CMDlint(parser, args): |
1598 """Runs cpplint on the current changelist.""" | 1617 """Runs cpplint on the current changelist.""" |
1599 parser.add_option('--filter', action='append', metavar='-x,+y', | 1618 parser.add_option('--filter', action='append', metavar='-x,+y', |
1600 help='Comma-separated list of cpplint\'s category-filters') | 1619 help='Comma-separated list of cpplint\'s category-filters') |
1601 (options, args) = parser.parse_args(args) | 1620 auth.add_auth_options(parser) |
| 1621 options, args = parser.parse_args(args) |
| 1622 auth_config = auth.extract_auth_config_from_options(options) |
1602 | 1623 |
1603 # Access to a protected member _XX of a client class | 1624 # Access to a protected member _XX of a client class |
1604 # pylint: disable=W0212 | 1625 # pylint: disable=W0212 |
1605 try: | 1626 try: |
1606 import cpplint | 1627 import cpplint |
1607 import cpplint_chromium | 1628 import cpplint_chromium |
1608 except ImportError: | 1629 except ImportError: |
1609 print "Your depot_tools is missing cpplint.py and/or cpplint_chromium.py." | 1630 print "Your depot_tools is missing cpplint.py and/or cpplint_chromium.py." |
1610 return 1 | 1631 return 1 |
1611 | 1632 |
1612 # Change the current working directory before calling lint so that it | 1633 # Change the current working directory before calling lint so that it |
1613 # shows the correct base. | 1634 # shows the correct base. |
1614 previous_cwd = os.getcwd() | 1635 previous_cwd = os.getcwd() |
1615 os.chdir(settings.GetRoot()) | 1636 os.chdir(settings.GetRoot()) |
1616 try: | 1637 try: |
1617 cl = Changelist() | 1638 cl = Changelist(auth_config=auth_config) |
1618 change = cl.GetChange(cl.GetCommonAncestorWithUpstream(), None) | 1639 change = cl.GetChange(cl.GetCommonAncestorWithUpstream(), None) |
1619 files = [f.LocalPath() for f in change.AffectedFiles()] | 1640 files = [f.LocalPath() for f in change.AffectedFiles()] |
1620 if not files: | 1641 if not files: |
1621 print "Cannot lint an empty CL" | 1642 print "Cannot lint an empty CL" |
1622 return 1 | 1643 return 1 |
1623 | 1644 |
1624 # Process cpplints arguments if any. | 1645 # Process cpplints arguments if any. |
1625 command = args + files | 1646 command = args + files |
1626 if options.filter: | 1647 if options.filter: |
1627 command = ['--filter=' + ','.join(options.filter)] + command | 1648 command = ['--filter=' + ','.join(options.filter)] + command |
(...skipping 18 matching lines...) Expand all Loading... |
1646 return 1 | 1667 return 1 |
1647 return 0 | 1668 return 0 |
1648 | 1669 |
1649 | 1670 |
1650 def CMDpresubmit(parser, args): | 1671 def CMDpresubmit(parser, args): |
1651 """Runs presubmit tests on the current changelist.""" | 1672 """Runs presubmit tests on the current changelist.""" |
1652 parser.add_option('-u', '--upload', action='store_true', | 1673 parser.add_option('-u', '--upload', action='store_true', |
1653 help='Run upload hook instead of the push/dcommit hook') | 1674 help='Run upload hook instead of the push/dcommit hook') |
1654 parser.add_option('-f', '--force', action='store_true', | 1675 parser.add_option('-f', '--force', action='store_true', |
1655 help='Run checks even if tree is dirty') | 1676 help='Run checks even if tree is dirty') |
1656 (options, args) = parser.parse_args(args) | 1677 auth.add_auth_options(parser) |
| 1678 options, args = parser.parse_args(args) |
| 1679 auth_config = auth.extract_auth_config_from_options(options) |
1657 | 1680 |
1658 if not options.force and is_dirty_git_tree('presubmit'): | 1681 if not options.force and is_dirty_git_tree('presubmit'): |
1659 print 'use --force to check even if tree is dirty.' | 1682 print 'use --force to check even if tree is dirty.' |
1660 return 1 | 1683 return 1 |
1661 | 1684 |
1662 cl = Changelist() | 1685 cl = Changelist(auth_config=auth_config) |
1663 if args: | 1686 if args: |
1664 base_branch = args[0] | 1687 base_branch = args[0] |
1665 else: | 1688 else: |
1666 # Default to diffing against the common ancestor of the upstream branch. | 1689 # Default to diffing against the common ancestor of the upstream branch. |
1667 base_branch = cl.GetCommonAncestorWithUpstream() | 1690 base_branch = cl.GetCommonAncestorWithUpstream() |
1668 | 1691 |
1669 cl.RunHook( | 1692 cl.RunHook( |
1670 committing=not options.upload, | 1693 committing=not options.upload, |
1671 may_prompt=False, | 1694 may_prompt=False, |
1672 verbose=options.verbose, | 1695 verbose=options.verbose, |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1852 # If a pending prefix exists then replace refs/ with it. | 1875 # If a pending prefix exists then replace refs/ with it. |
1853 if pending_prefix: | 1876 if pending_prefix: |
1854 remote_branch = remote_branch.replace('refs/', pending_prefix) | 1877 remote_branch = remote_branch.replace('refs/', pending_prefix) |
1855 return remote_branch | 1878 return remote_branch |
1856 | 1879 |
1857 | 1880 |
1858 def RietveldUpload(options, args, cl, change): | 1881 def RietveldUpload(options, args, cl, change): |
1859 """upload the patch to rietveld.""" | 1882 """upload the patch to rietveld.""" |
1860 upload_args = ['--assume_yes'] # Don't ask about untracked files. | 1883 upload_args = ['--assume_yes'] # Don't ask about untracked files. |
1861 upload_args.extend(['--server', cl.GetRietveldServer()]) | 1884 upload_args.extend(['--server', cl.GetRietveldServer()]) |
| 1885 upload_args.extend(auth.auth_config_to_command_options(cl.auth_config)) |
1862 if options.emulate_svn_auto_props: | 1886 if options.emulate_svn_auto_props: |
1863 upload_args.append('--emulate_svn_auto_props') | 1887 upload_args.append('--emulate_svn_auto_props') |
1864 | 1888 |
1865 change_desc = None | 1889 change_desc = None |
1866 | 1890 |
1867 if options.email is not None: | 1891 if options.email is not None: |
1868 upload_args.extend(['--email', options.email]) | 1892 upload_args.extend(['--email', options.email]) |
1869 | 1893 |
1870 if cl.GetIssue(): | 1894 if cl.GetIssue(): |
1871 if options.title: | 1895 if options.title: |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2023 help='Squash multiple commits into one (Gerrit only)') | 2047 help='Squash multiple commits into one (Gerrit only)') |
2024 parser.add_option('--email', default=None, | 2048 parser.add_option('--email', default=None, |
2025 help='email address to use to connect to Rietveld') | 2049 help='email address to use to connect to Rietveld') |
2026 parser.add_option('--tbr-owners', dest='tbr_owners', action='store_true', | 2050 parser.add_option('--tbr-owners', dest='tbr_owners', action='store_true', |
2027 help='add a set of OWNERS to TBR') | 2051 help='add a set of OWNERS to TBR') |
2028 parser.add_option('--cq-dry-run', dest='cq_dry_run', action='store_true', | 2052 parser.add_option('--cq-dry-run', dest='cq_dry_run', action='store_true', |
2029 help='Send the patchset to do a CQ dry run right after ' | 2053 help='Send the patchset to do a CQ dry run right after ' |
2030 'upload.') | 2054 'upload.') |
2031 | 2055 |
2032 add_git_similarity(parser) | 2056 add_git_similarity(parser) |
| 2057 auth.add_auth_options(parser) |
2033 (options, args) = parser.parse_args(args) | 2058 (options, args) = parser.parse_args(args) |
| 2059 auth_config = auth.extract_auth_config_from_options(options) |
2034 | 2060 |
2035 if is_dirty_git_tree('upload'): | 2061 if is_dirty_git_tree('upload'): |
2036 return 1 | 2062 return 1 |
2037 | 2063 |
2038 options.reviewers = cleanup_list(options.reviewers) | 2064 options.reviewers = cleanup_list(options.reviewers) |
2039 options.cc = cleanup_list(options.cc) | 2065 options.cc = cleanup_list(options.cc) |
2040 | 2066 |
2041 cl = Changelist() | 2067 cl = Changelist(auth_config=auth_config) |
2042 if args: | 2068 if args: |
2043 # TODO(ukai): is it ok for gerrit case? | 2069 # TODO(ukai): is it ok for gerrit case? |
2044 base_branch = args[0] | 2070 base_branch = args[0] |
2045 else: | 2071 else: |
2046 if cl.GetBranch() is None: | 2072 if cl.GetBranch() is None: |
2047 DieWithError('Can\'t upload from detached HEAD state. Get on a branch!') | 2073 DieWithError('Can\'t upload from detached HEAD state. Get on a branch!') |
2048 | 2074 |
2049 # Default to diffing against common ancestor of upstream branch | 2075 # Default to diffing against common ancestor of upstream branch |
2050 base_branch = cl.GetCommonAncestorWithUpstream() | 2076 base_branch = cl.GetCommonAncestorWithUpstream() |
2051 args = [base_branch, 'HEAD'] | 2077 args = [base_branch, 'HEAD'] |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2125 help='bypass upload presubmit hook') | 2151 help='bypass upload presubmit hook') |
2126 parser.add_option('-m', dest='message', | 2152 parser.add_option('-m', dest='message', |
2127 help="override review description") | 2153 help="override review description") |
2128 parser.add_option('-f', action='store_true', dest='force', | 2154 parser.add_option('-f', action='store_true', dest='force', |
2129 help="force yes to questions (don't prompt)") | 2155 help="force yes to questions (don't prompt)") |
2130 parser.add_option('-c', dest='contributor', | 2156 parser.add_option('-c', dest='contributor', |
2131 help="external contributor for patch (appended to " + | 2157 help="external contributor for patch (appended to " + |
2132 "description and used as author for git). Should be " + | 2158 "description and used as author for git). Should be " + |
2133 "formatted as 'First Last <email@example.com>'") | 2159 "formatted as 'First Last <email@example.com>'") |
2134 add_git_similarity(parser) | 2160 add_git_similarity(parser) |
| 2161 auth.add_auth_options(parser) |
2135 (options, args) = parser.parse_args(args) | 2162 (options, args) = parser.parse_args(args) |
2136 cl = Changelist() | 2163 auth_config = auth.extract_auth_config_from_options(options) |
| 2164 |
| 2165 cl = Changelist(auth_config=auth_config) |
2137 | 2166 |
2138 current = cl.GetBranch() | 2167 current = cl.GetBranch() |
2139 remote, upstream_branch = cl.FetchUpstreamTuple(cl.GetBranch()) | 2168 remote, upstream_branch = cl.FetchUpstreamTuple(cl.GetBranch()) |
2140 if not settings.GetIsGitSvn() and remote == '.': | 2169 if not settings.GetIsGitSvn() and remote == '.': |
2141 print | 2170 print |
2142 print 'Attempting to push branch %r into another local branch!' % current | 2171 print 'Attempting to push branch %r into another local branch!' % current |
2143 print | 2172 print |
2144 print 'Either reparent this branch on top of origin/master:' | 2173 print 'Either reparent this branch on top of origin/master:' |
2145 print ' git reparent-branch --root' | 2174 print ' git reparent-branch --root' |
2146 print | 2175 print |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2524 parser.add_option('-f', '--force', action='store_true', | 2553 parser.add_option('-f', '--force', action='store_true', |
2525 help='with -b, clobber any existing branch') | 2554 help='with -b, clobber any existing branch') |
2526 parser.add_option('-d', '--directory', action='store', metavar='DIR', | 2555 parser.add_option('-d', '--directory', action='store', metavar='DIR', |
2527 help='Change to the directory DIR immediately, ' | 2556 help='Change to the directory DIR immediately, ' |
2528 'before doing anything else.') | 2557 'before doing anything else.') |
2529 parser.add_option('--reject', action='store_true', | 2558 parser.add_option('--reject', action='store_true', |
2530 help='failed patches spew .rej files rather than ' | 2559 help='failed patches spew .rej files rather than ' |
2531 'attempting a 3-way merge') | 2560 'attempting a 3-way merge') |
2532 parser.add_option('-n', '--no-commit', action='store_true', dest='nocommit', | 2561 parser.add_option('-n', '--no-commit', action='store_true', dest='nocommit', |
2533 help="don't commit after patch applies") | 2562 help="don't commit after patch applies") |
| 2563 auth.add_auth_options(parser) |
2534 (options, args) = parser.parse_args(args) | 2564 (options, args) = parser.parse_args(args) |
| 2565 auth_config = auth.extract_auth_config_from_options(options) |
| 2566 |
2535 if len(args) != 1: | 2567 if len(args) != 1: |
2536 parser.print_help() | 2568 parser.print_help() |
2537 return 1 | 2569 return 1 |
2538 issue_arg = args[0] | 2570 issue_arg = args[0] |
2539 | 2571 |
2540 # We don't want uncommitted changes mixed up with the patch. | 2572 # We don't want uncommitted changes mixed up with the patch. |
2541 if is_dirty_git_tree('patch'): | 2573 if is_dirty_git_tree('patch'): |
2542 return 1 | 2574 return 1 |
2543 | 2575 |
2544 # TODO(maruel): Use apply_issue.py | 2576 # TODO(maruel): Use apply_issue.py |
2545 # TODO(ukai): use gerrit-cherry-pick for gerrit repository? | 2577 # TODO(ukai): use gerrit-cherry-pick for gerrit repository? |
2546 | 2578 |
2547 if options.newbranch: | 2579 if options.newbranch: |
2548 if options.force: | 2580 if options.force: |
2549 RunGit(['branch', '-D', options.newbranch], | 2581 RunGit(['branch', '-D', options.newbranch], |
2550 stderr=subprocess2.PIPE, error_ok=True) | 2582 stderr=subprocess2.PIPE, error_ok=True) |
2551 RunGit(['checkout', '-b', options.newbranch, | 2583 RunGit(['checkout', '-b', options.newbranch, |
2552 Changelist().GetUpstreamBranch()]) | 2584 Changelist().GetUpstreamBranch()]) |
2553 | 2585 |
2554 return PatchIssue(issue_arg, options.reject, options.nocommit, | 2586 return PatchIssue(issue_arg, options.reject, options.nocommit, |
2555 options.directory) | 2587 options.directory, auth_config) |
2556 | 2588 |
2557 | 2589 |
2558 def PatchIssue(issue_arg, reject, nocommit, directory): | 2590 def PatchIssue(issue_arg, reject, nocommit, directory, auth_config): |
2559 # There's a "reset --hard" when failing to apply the patch. In order | 2591 # There's a "reset --hard" when failing to apply the patch. In order |
2560 # not to destroy users' data, make sure the tree is not dirty here. | 2592 # not to destroy users' data, make sure the tree is not dirty here. |
2561 assert(not is_dirty_git_tree('apply')) | 2593 assert(not is_dirty_git_tree('apply')) |
2562 | 2594 |
2563 if type(issue_arg) is int or issue_arg.isdigit(): | 2595 if type(issue_arg) is int or issue_arg.isdigit(): |
2564 # Input is an issue id. Figure out the URL. | 2596 # Input is an issue id. Figure out the URL. |
2565 issue = int(issue_arg) | 2597 issue = int(issue_arg) |
2566 cl = Changelist(issue=issue) | 2598 cl = Changelist(issue=issue, auth_config=auth_config) |
2567 patchset = cl.GetMostRecentPatchset() | 2599 patchset = cl.GetMostRecentPatchset() |
2568 patch_data = cl.GetPatchSetDiff(issue, patchset) | 2600 patch_data = cl.GetPatchSetDiff(issue, patchset) |
2569 else: | 2601 else: |
2570 # Assume it's a URL to the patch. Default to https. | 2602 # Assume it's a URL to the patch. Default to https. |
2571 issue_url = gclient_utils.UpgradeToHttps(issue_arg) | 2603 issue_url = gclient_utils.UpgradeToHttps(issue_arg) |
2572 match = re.match(r'.*?/issue(\d+)_(\d+).diff', issue_url) | 2604 match = re.match(r'.*?/issue(\d+)_(\d+).diff', issue_url) |
2573 if not match: | 2605 if not match: |
2574 DieWithError('Must pass an issue ID or full URL for ' | 2606 DieWithError('Must pass an issue ID or full URL for ' |
2575 '\'Download raw patch set\'') | 2607 '\'Download raw patch set\'') |
2576 issue = int(match.group(1)) | 2608 issue = int(match.group(1)) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2609 stdin=patch_data, stdout=subprocess2.VOID) | 2641 stdin=patch_data, stdout=subprocess2.VOID) |
2610 except subprocess2.CalledProcessError: | 2642 except subprocess2.CalledProcessError: |
2611 RunGit(['reset', '--hard']) | 2643 RunGit(['reset', '--hard']) |
2612 DieWithError('Failed to apply the patch') | 2644 DieWithError('Failed to apply the patch') |
2613 | 2645 |
2614 # If we had an issue, commit the current state and register the issue. | 2646 # If we had an issue, commit the current state and register the issue. |
2615 if not nocommit: | 2647 if not nocommit: |
2616 RunGit(['commit', '-m', ('patch from issue %(i)s at patchset ' | 2648 RunGit(['commit', '-m', ('patch from issue %(i)s at patchset ' |
2617 '%(p)s (http://crrev.com/%(i)s#ps%(p)s)' | 2649 '%(p)s (http://crrev.com/%(i)s#ps%(p)s)' |
2618 % {'i': issue, 'p': patchset})]) | 2650 % {'i': issue, 'p': patchset})]) |
2619 cl = Changelist() | 2651 cl = Changelist(auth_config=auth_config) |
2620 cl.SetIssue(issue) | 2652 cl.SetIssue(issue) |
2621 cl.SetPatchset(patchset) | 2653 cl.SetPatchset(patchset) |
2622 print "Committed patch locally." | 2654 print "Committed patch locally." |
2623 else: | 2655 else: |
2624 print "Patch applied to index." | 2656 print "Patch applied to index." |
2625 return 0 | 2657 return 0 |
2626 | 2658 |
2627 | 2659 |
2628 def CMDrebase(parser, args): | 2660 def CMDrebase(parser, args): |
2629 """Rebases current branch on top of svn repo.""" | 2661 """Rebases current branch on top of svn repo.""" |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2729 "-c", "--clobber", action="store_true", default=False, | 2761 "-c", "--clobber", action="store_true", default=False, |
2730 help="Force a clobber before building; e.g. don't do an " | 2762 help="Force a clobber before building; e.g. don't do an " |
2731 "incremental build") | 2763 "incremental build") |
2732 group.add_option( | 2764 group.add_option( |
2733 "--project", | 2765 "--project", |
2734 help="Override which project to use. Projects are defined " | 2766 help="Override which project to use. Projects are defined " |
2735 "server-side to define what default bot set to use") | 2767 "server-side to define what default bot set to use") |
2736 group.add_option( | 2768 group.add_option( |
2737 "-n", "--name", help="Try job name; default to current branch name") | 2769 "-n", "--name", help="Try job name; default to current branch name") |
2738 parser.add_option_group(group) | 2770 parser.add_option_group(group) |
| 2771 auth.add_auth_options(parser) |
2739 options, args = parser.parse_args(args) | 2772 options, args = parser.parse_args(args) |
| 2773 auth_config = auth.extract_auth_config_from_options(options) |
2740 | 2774 |
2741 if args: | 2775 if args: |
2742 parser.error('Unknown arguments: %s' % args) | 2776 parser.error('Unknown arguments: %s' % args) |
2743 | 2777 |
2744 cl = Changelist() | 2778 cl = Changelist(auth_config=auth_config) |
2745 if not cl.GetIssue(): | 2779 if not cl.GetIssue(): |
2746 parser.error('Need to upload first') | 2780 parser.error('Need to upload first') |
2747 | 2781 |
2748 props = cl.GetIssueProperties() | 2782 props = cl.GetIssueProperties() |
2749 if props.get('closed'): | 2783 if props.get('closed'): |
2750 parser.error('Cannot send tryjobs for a closed CL') | 2784 parser.error('Cannot send tryjobs for a closed CL') |
2751 | 2785 |
2752 if props.get('private'): | 2786 if props.get('private'): |
2753 parser.error('Cannot use trybots with private issue') | 2787 parser.error('Cannot use trybots with private issue') |
2754 | 2788 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2882 if not issue_url: | 2916 if not issue_url: |
2883 print >> sys.stderr, 'ERROR No issue to open' | 2917 print >> sys.stderr, 'ERROR No issue to open' |
2884 return 1 | 2918 return 1 |
2885 | 2919 |
2886 webbrowser.open(issue_url) | 2920 webbrowser.open(issue_url) |
2887 return 0 | 2921 return 0 |
2888 | 2922 |
2889 | 2923 |
2890 def CMDset_commit(parser, args): | 2924 def CMDset_commit(parser, args): |
2891 """Sets the commit bit to trigger the Commit Queue.""" | 2925 """Sets the commit bit to trigger the Commit Queue.""" |
2892 _, args = parser.parse_args(args) | 2926 auth.add_auth_options(parser) |
| 2927 options, args = parser.parse_args(args) |
| 2928 auth_config = auth.extract_auth_config_from_options(options) |
2893 if args: | 2929 if args: |
2894 parser.error('Unrecognized args: %s' % ' '.join(args)) | 2930 parser.error('Unrecognized args: %s' % ' '.join(args)) |
2895 cl = Changelist() | 2931 cl = Changelist(auth_config=auth_config) |
2896 props = cl.GetIssueProperties() | 2932 props = cl.GetIssueProperties() |
2897 if props.get('private'): | 2933 if props.get('private'): |
2898 parser.error('Cannot set commit on private issue') | 2934 parser.error('Cannot set commit on private issue') |
2899 cl.SetFlag('commit', '1') | 2935 cl.SetFlag('commit', '1') |
2900 return 0 | 2936 return 0 |
2901 | 2937 |
2902 | 2938 |
2903 def CMDset_close(parser, args): | 2939 def CMDset_close(parser, args): |
2904 """Closes the issue.""" | 2940 """Closes the issue.""" |
2905 _, args = parser.parse_args(args) | 2941 auth.add_auth_options(parser) |
| 2942 options, args = parser.parse_args(args) |
| 2943 auth_config = auth.extract_auth_config_from_options(options) |
2906 if args: | 2944 if args: |
2907 parser.error('Unrecognized args: %s' % ' '.join(args)) | 2945 parser.error('Unrecognized args: %s' % ' '.join(args)) |
2908 cl = Changelist() | 2946 cl = Changelist(auth_config=auth_config) |
2909 # Ensure there actually is an issue to close. | 2947 # Ensure there actually is an issue to close. |
2910 cl.GetDescription() | 2948 cl.GetDescription() |
2911 cl.CloseIssue() | 2949 cl.CloseIssue() |
2912 return 0 | 2950 return 0 |
2913 | 2951 |
2914 | 2952 |
2915 def CMDdiff(parser, args): | 2953 def CMDdiff(parser, args): |
2916 """Shows differences between local tree and last upload.""" | 2954 """Shows differences between local tree and last upload.""" |
2917 parser.parse_args(args) | 2955 auth.add_auth_options(parser) |
| 2956 options, args = parser.parse_args(args) |
| 2957 auth_config = auth.extract_auth_config_from_options(options) |
| 2958 if args: |
| 2959 parser.error('Unrecognized args: %s' % ' '.join(args)) |
2918 | 2960 |
2919 # Uncommitted (staged and unstaged) changes will be destroyed by | 2961 # Uncommitted (staged and unstaged) changes will be destroyed by |
2920 # "git reset --hard" if there are merging conflicts in PatchIssue(). | 2962 # "git reset --hard" if there are merging conflicts in PatchIssue(). |
2921 # Staged changes would be committed along with the patch from last | 2963 # Staged changes would be committed along with the patch from last |
2922 # upload, hence counted toward the "last upload" side in the final | 2964 # upload, hence counted toward the "last upload" side in the final |
2923 # diff output, and this is not what we want. | 2965 # diff output, and this is not what we want. |
2924 if is_dirty_git_tree('diff'): | 2966 if is_dirty_git_tree('diff'): |
2925 return 1 | 2967 return 1 |
2926 | 2968 |
2927 cl = Changelist() | 2969 cl = Changelist(auth_config=auth_config) |
2928 issue = cl.GetIssue() | 2970 issue = cl.GetIssue() |
2929 branch = cl.GetBranch() | 2971 branch = cl.GetBranch() |
2930 if not issue: | 2972 if not issue: |
2931 DieWithError('No issue found for current branch (%s)' % branch) | 2973 DieWithError('No issue found for current branch (%s)' % branch) |
2932 TMP_BRANCH = 'git-cl-diff' | 2974 TMP_BRANCH = 'git-cl-diff' |
2933 base_branch = cl.GetCommonAncestorWithUpstream() | 2975 base_branch = cl.GetCommonAncestorWithUpstream() |
2934 | 2976 |
2935 # Create a new branch based on the merge-base | 2977 # Create a new branch based on the merge-base |
2936 RunGit(['checkout', '-q', '-b', TMP_BRANCH, base_branch]) | 2978 RunGit(['checkout', '-q', '-b', TMP_BRANCH, base_branch]) |
2937 try: | 2979 try: |
2938 # Patch in the latest changes from rietveld. | 2980 # Patch in the latest changes from rietveld. |
2939 rtn = PatchIssue(issue, False, False, None) | 2981 rtn = PatchIssue(issue, False, False, None, auth_config) |
2940 if rtn != 0: | 2982 if rtn != 0: |
2941 return rtn | 2983 return rtn |
2942 | 2984 |
2943 # Switch back to starting branch and diff against the temporary | 2985 # Switch back to starting branch and diff against the temporary |
2944 # branch containing the latest rietveld patch. | 2986 # branch containing the latest rietveld patch. |
2945 subprocess2.check_call(['git', 'diff', TMP_BRANCH, branch, '--']) | 2987 subprocess2.check_call(['git', 'diff', TMP_BRANCH, branch, '--']) |
2946 finally: | 2988 finally: |
2947 RunGit(['checkout', '-q', branch]) | 2989 RunGit(['checkout', '-q', branch]) |
2948 RunGit(['branch', '-D', TMP_BRANCH]) | 2990 RunGit(['branch', '-D', TMP_BRANCH]) |
2949 | 2991 |
2950 return 0 | 2992 return 0 |
2951 | 2993 |
2952 | 2994 |
2953 def CMDowners(parser, args): | 2995 def CMDowners(parser, args): |
2954 """Interactively find the owners for reviewing.""" | 2996 """Interactively find the owners for reviewing.""" |
2955 parser.add_option( | 2997 parser.add_option( |
2956 '--no-color', | 2998 '--no-color', |
2957 action='store_true', | 2999 action='store_true', |
2958 help='Use this option to disable color output') | 3000 help='Use this option to disable color output') |
| 3001 auth.add_auth_options(parser) |
2959 options, args = parser.parse_args(args) | 3002 options, args = parser.parse_args(args) |
| 3003 auth_config = auth.extract_auth_config_from_options(options) |
2960 | 3004 |
2961 author = RunGit(['config', 'user.email']).strip() or None | 3005 author = RunGit(['config', 'user.email']).strip() or None |
2962 | 3006 |
2963 cl = Changelist() | 3007 cl = Changelist(auth_config=auth_config) |
2964 | 3008 |
2965 if args: | 3009 if args: |
2966 if len(args) > 1: | 3010 if len(args) > 1: |
2967 parser.error('Unknown args') | 3011 parser.error('Unknown args') |
2968 base_branch = args[0] | 3012 base_branch = args[0] |
2969 else: | 3013 else: |
2970 # Default to diffing against the common ancestor of the upstream branch. | 3014 # Default to diffing against the common ancestor of the upstream branch. |
2971 base_branch = cl.GetCommonAncestorWithUpstream() | 3015 base_branch = cl.GetCommonAncestorWithUpstream() |
2972 | 3016 |
2973 change = cl.GetChange(base_branch, None) | 3017 change = cl.GetChange(base_branch, None) |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3161 if __name__ == '__main__': | 3205 if __name__ == '__main__': |
3162 # These affect sys.stdout so do it outside of main() to simplify mocks in | 3206 # These affect sys.stdout so do it outside of main() to simplify mocks in |
3163 # unit testing. | 3207 # unit testing. |
3164 fix_encoding.fix_encoding() | 3208 fix_encoding.fix_encoding() |
3165 colorama.init() | 3209 colorama.init() |
3166 try: | 3210 try: |
3167 sys.exit(main(sys.argv[1:])) | 3211 sys.exit(main(sys.argv[1:])) |
3168 except KeyboardInterrupt: | 3212 except KeyboardInterrupt: |
3169 sys.stderr.write('interrupted\n') | 3213 sys.stderr.write('interrupted\n') |
3170 sys.exit(1) | 3214 sys.exit(1) |
OLD | NEW |