| Index: git_cl.py
|
| diff --git a/git_cl.py b/git_cl.py
|
| index 4eee3f152853d4a746bc901c465da0355397c3e5..41ec428ead6cfa3c329367ef119973e021c06f3a 100755
|
| --- a/git_cl.py
|
| +++ b/git_cl.py
|
| @@ -34,6 +34,7 @@ except ImportError:
|
|
|
| from third_party import colorama
|
| from third_party import upload
|
| +import auth
|
| import breakpad # pylint: disable=W0611
|
| import clang_format
|
| import dart_format
|
| @@ -498,7 +499,7 @@ def ShortBranchName(branch):
|
|
|
|
|
| class Changelist(object):
|
| - def __init__(self, branchref=None, issue=None):
|
| + def __init__(self, branchref=None, issue=None, auth_config=None):
|
| # Poke settings so we get the "configure your server" message if necessary.
|
| global settings
|
| if not settings:
|
| @@ -518,11 +519,16 @@ class Changelist(object):
|
| self.description = None
|
| self.lookedup_patchset = False
|
| self.patchset = None
|
| - self._rpc_server = None
|
| self.cc = None
|
| self.watchers = ()
|
| - self._remote = None
|
| + self._auth_config = auth_config
|
| self._props = None
|
| + self._remote = None
|
| + self._rpc_server = None
|
| +
|
| + @property
|
| + def auth_config(self):
|
| + return self._auth_config
|
|
|
| def GetCCList(self):
|
| """Return the users cc'd on this CL.
|
| @@ -985,7 +991,8 @@ or verify this branch is set up to track another (via the --track argument to
|
| """
|
| if not self._rpc_server:
|
| self._rpc_server = rietveld.CachingRietveld(
|
| - self.GetRietveldServer(), None, None)
|
| + self.GetRietveldServer(),
|
| + self._auth_config or auth.make_auth_config())
|
| return self._rpc_server
|
|
|
| def _IssueSetting(self):
|
| @@ -1342,9 +1349,9 @@ def color_for_status(status):
|
| 'error': Fore.WHITE,
|
| }.get(status, Fore.WHITE)
|
|
|
| -def fetch_cl_status(b):
|
| +def fetch_cl_status(b, auth_config=None):
|
| """Fetches information for an issue and returns (branch, issue, color)."""
|
| - c = Changelist(branchref=b)
|
| + c = Changelist(branchref=b, auth_config=auth_config)
|
| i = c.GetIssueURL()
|
| status = c.GetStatus()
|
| color = color_for_status(status)
|
| @@ -1355,7 +1362,8 @@ def fetch_cl_status(b):
|
|
|
| return (b, i, color)
|
|
|
| -def get_cl_statuses(branches, fine_grained, max_processes=None):
|
| +def get_cl_statuses(
|
| + branches, fine_grained, max_processes=None, auth_config=None):
|
| """Returns a blocking iterable of (branch, issue, color) for given branches.
|
|
|
| If fine_grained is true, this will fetch CL statuses from the server.
|
| @@ -1372,19 +1380,20 @@ def get_cl_statuses(branches, fine_grained, max_processes=None):
|
| # Process one branch synchronously to work through authentication, then
|
| # spawn processes to process all the other branches in parallel.
|
| if branches:
|
| - yield fetch_cl_status(branches[0])
|
| + fetch = lambda branch: fetch_cl_status(branch, auth_config=auth_config)
|
| + yield fetch(branches[0])
|
|
|
| branches_to_fetch = branches[1:]
|
| pool = ThreadPool(
|
| min(max_processes, len(branches_to_fetch))
|
| if max_processes is not None
|
| else len(branches_to_fetch))
|
| - for x in pool.imap_unordered(fetch_cl_status, branches_to_fetch):
|
| + for x in pool.imap_unordered(fetch, branches_to_fetch):
|
| yield x
|
| else:
|
| # Do not use GetApprovingReviewers(), since it requires an HTTP request.
|
| for b in branches:
|
| - c = Changelist(branchref=b)
|
| + c = Changelist(branchref=b, auth_config=auth_config)
|
| url = c.GetIssueURL()
|
| yield (b, url, Fore.BLUE if url else Fore.WHITE)
|
|
|
| @@ -1408,12 +1417,15 @@ def CMDstatus(parser, args):
|
| parser.add_option(
|
| '-j', '--maxjobs', action='store', type=int,
|
| help='The maximum number of jobs to use when retrieving review status')
|
| - (options, args) = parser.parse_args(args)
|
| +
|
| + auth.add_auth_options(parser)
|
| + options, args = parser.parse_args(args)
|
| if args:
|
| parser.error('Unsupported args: %s' % args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
|
|
| if options.field:
|
| - cl = Changelist()
|
| + cl = Changelist(auth_config=auth_config)
|
| if options.field.startswith('desc'):
|
| print cl.GetDescription()
|
| elif options.field == 'id':
|
| @@ -1435,13 +1447,16 @@ def CMDstatus(parser, args):
|
| print('No local branch found.')
|
| return 0
|
|
|
| - changes = (Changelist(branchref=b) for b in branches.splitlines())
|
| + changes = (
|
| + Changelist(branchref=b, auth_config=auth_config)
|
| + for b in branches.splitlines())
|
| branches = [c.GetBranch() for c in changes]
|
| alignment = max(5, max(len(b) for b in branches))
|
| print 'Branches associated with reviews:'
|
| output = get_cl_statuses(branches,
|
| fine_grained=not options.fast,
|
| - max_processes=options.maxjobs)
|
| + max_processes=options.maxjobs,
|
| + auth_config=auth_config)
|
|
|
| branch_statuses = {}
|
| alignment = max(5, max(len(ShortBranchName(b)) for b in branches))
|
| @@ -1457,7 +1472,7 @@ def CMDstatus(parser, args):
|
| print ' %*s : %s%s%s' % (
|
| alignment, ShortBranchName(branch), color, issue, reset)
|
|
|
| - cl = Changelist()
|
| + cl = Changelist(auth_config=auth_config)
|
| print
|
| print 'Current branch:',
|
| if not cl.GetIssue():
|
| @@ -1534,7 +1549,9 @@ def CMDcomments(parser, args):
|
| help='comment to add to an issue')
|
| parser.add_option('-i', dest='issue',
|
| help="review issue id (defaults to current issue)")
|
| + auth.add_auth_options(parser)
|
| options, args = parser.parse_args(args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
|
|
| issue = None
|
| if options.issue:
|
| @@ -1543,7 +1560,7 @@ def CMDcomments(parser, args):
|
| except ValueError:
|
| DieWithError('A review issue id is expected to be a number')
|
|
|
| - cl = Changelist(issue=issue)
|
| + cl = Changelist(issue=issue, auth_config=auth_config)
|
|
|
| if options.comment:
|
| cl.AddComment(options.comment)
|
| @@ -1569,8 +1586,10 @@ def CMDcomments(parser, args):
|
|
|
| def CMDdescription(parser, args):
|
| """Brings up the editor for the current CL's description."""
|
| - parser.parse_args(args)
|
| - cl = Changelist()
|
| + auth.add_auth_options(parser)
|
| + options, _ = parser.parse_args(args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
| + cl = Changelist(auth_config=auth_config)
|
| if not cl.GetIssue():
|
| DieWithError('This branch has no associated changelist.')
|
| description = ChangeDescription(cl.GetDescription())
|
| @@ -1598,7 +1617,9 @@ def CMDlint(parser, args):
|
| """Runs cpplint on the current changelist."""
|
| parser.add_option('--filter', action='append', metavar='-x,+y',
|
| help='Comma-separated list of cpplint\'s category-filters')
|
| - (options, args) = parser.parse_args(args)
|
| + auth.add_auth_options(parser)
|
| + options, args = parser.parse_args(args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
|
|
| # Access to a protected member _XX of a client class
|
| # pylint: disable=W0212
|
| @@ -1614,7 +1635,7 @@ def CMDlint(parser, args):
|
| previous_cwd = os.getcwd()
|
| os.chdir(settings.GetRoot())
|
| try:
|
| - cl = Changelist()
|
| + cl = Changelist(auth_config=auth_config)
|
| change = cl.GetChange(cl.GetCommonAncestorWithUpstream(), None)
|
| files = [f.LocalPath() for f in change.AffectedFiles()]
|
| if not files:
|
| @@ -1653,13 +1674,15 @@ def CMDpresubmit(parser, args):
|
| help='Run upload hook instead of the push/dcommit hook')
|
| parser.add_option('-f', '--force', action='store_true',
|
| help='Run checks even if tree is dirty')
|
| - (options, args) = parser.parse_args(args)
|
| + auth.add_auth_options(parser)
|
| + options, args = parser.parse_args(args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
|
|
| if not options.force and is_dirty_git_tree('presubmit'):
|
| print 'use --force to check even if tree is dirty.'
|
| return 1
|
|
|
| - cl = Changelist()
|
| + cl = Changelist(auth_config=auth_config)
|
| if args:
|
| base_branch = args[0]
|
| else:
|
| @@ -1859,6 +1882,7 @@ def RietveldUpload(options, args, cl, change):
|
| """upload the patch to rietveld."""
|
| upload_args = ['--assume_yes'] # Don't ask about untracked files.
|
| upload_args.extend(['--server', cl.GetRietveldServer()])
|
| + upload_args.extend(auth.auth_config_to_command_options(cl.auth_config))
|
| if options.emulate_svn_auto_props:
|
| upload_args.append('--emulate_svn_auto_props')
|
|
|
| @@ -2030,7 +2054,9 @@ def CMDupload(parser, args):
|
| 'upload.')
|
|
|
| add_git_similarity(parser)
|
| + auth.add_auth_options(parser)
|
| (options, args) = parser.parse_args(args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
|
|
| if is_dirty_git_tree('upload'):
|
| return 1
|
| @@ -2038,7 +2064,7 @@ def CMDupload(parser, args):
|
| options.reviewers = cleanup_list(options.reviewers)
|
| options.cc = cleanup_list(options.cc)
|
|
|
| - cl = Changelist()
|
| + cl = Changelist(auth_config=auth_config)
|
| if args:
|
| # TODO(ukai): is it ok for gerrit case?
|
| base_branch = args[0]
|
| @@ -2132,8 +2158,11 @@ def SendUpstream(parser, args, cmd):
|
| "description and used as author for git). Should be " +
|
| "formatted as 'First Last <email@example.com>'")
|
| add_git_similarity(parser)
|
| + auth.add_auth_options(parser)
|
| (options, args) = parser.parse_args(args)
|
| - cl = Changelist()
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
| +
|
| + cl = Changelist(auth_config=auth_config)
|
|
|
| current = cl.GetBranch()
|
| remote, upstream_branch = cl.FetchUpstreamTuple(cl.GetBranch())
|
| @@ -2531,7 +2560,10 @@ def CMDpatch(parser, args):
|
| 'attempting a 3-way merge')
|
| parser.add_option('-n', '--no-commit', action='store_true', dest='nocommit',
|
| help="don't commit after patch applies")
|
| + auth.add_auth_options(parser)
|
| (options, args) = parser.parse_args(args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
| +
|
| if len(args) != 1:
|
| parser.print_help()
|
| return 1
|
| @@ -2552,10 +2584,10 @@ def CMDpatch(parser, args):
|
| Changelist().GetUpstreamBranch()])
|
|
|
| return PatchIssue(issue_arg, options.reject, options.nocommit,
|
| - options.directory)
|
| + options.directory, auth_config)
|
|
|
|
|
| -def PatchIssue(issue_arg, reject, nocommit, directory):
|
| +def PatchIssue(issue_arg, reject, nocommit, directory, auth_config):
|
| # There's a "reset --hard" when failing to apply the patch. In order
|
| # not to destroy users' data, make sure the tree is not dirty here.
|
| assert(not is_dirty_git_tree('apply'))
|
| @@ -2563,7 +2595,7 @@ def PatchIssue(issue_arg, reject, nocommit, directory):
|
| if type(issue_arg) is int or issue_arg.isdigit():
|
| # Input is an issue id. Figure out the URL.
|
| issue = int(issue_arg)
|
| - cl = Changelist(issue=issue)
|
| + cl = Changelist(issue=issue, auth_config=auth_config)
|
| patchset = cl.GetMostRecentPatchset()
|
| patch_data = cl.GetPatchSetDiff(issue, patchset)
|
| else:
|
| @@ -2616,7 +2648,7 @@ def PatchIssue(issue_arg, reject, nocommit, directory):
|
| RunGit(['commit', '-m', ('patch from issue %(i)s at patchset '
|
| '%(p)s (http://crrev.com/%(i)s#ps%(p)s)'
|
| % {'i': issue, 'p': patchset})])
|
| - cl = Changelist()
|
| + cl = Changelist(auth_config=auth_config)
|
| cl.SetIssue(issue)
|
| cl.SetPatchset(patchset)
|
| print "Committed patch locally."
|
| @@ -2736,12 +2768,14 @@ def CMDtry(parser, args):
|
| group.add_option(
|
| "-n", "--name", help="Try job name; default to current branch name")
|
| parser.add_option_group(group)
|
| + auth.add_auth_options(parser)
|
| options, args = parser.parse_args(args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
|
|
| if args:
|
| parser.error('Unknown arguments: %s' % args)
|
|
|
| - cl = Changelist()
|
| + cl = Changelist(auth_config=auth_config)
|
| if not cl.GetIssue():
|
| parser.error('Need to upload first')
|
|
|
| @@ -2889,10 +2923,12 @@ def CMDweb(parser, args):
|
|
|
| def CMDset_commit(parser, args):
|
| """Sets the commit bit to trigger the Commit Queue."""
|
| - _, args = parser.parse_args(args)
|
| + auth.add_auth_options(parser)
|
| + options, args = parser.parse_args(args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
| if args:
|
| parser.error('Unrecognized args: %s' % ' '.join(args))
|
| - cl = Changelist()
|
| + cl = Changelist(auth_config=auth_config)
|
| props = cl.GetIssueProperties()
|
| if props.get('private'):
|
| parser.error('Cannot set commit on private issue')
|
| @@ -2902,10 +2938,12 @@ def CMDset_commit(parser, args):
|
|
|
| def CMDset_close(parser, args):
|
| """Closes the issue."""
|
| - _, args = parser.parse_args(args)
|
| + auth.add_auth_options(parser)
|
| + options, args = parser.parse_args(args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
| if args:
|
| parser.error('Unrecognized args: %s' % ' '.join(args))
|
| - cl = Changelist()
|
| + cl = Changelist(auth_config=auth_config)
|
| # Ensure there actually is an issue to close.
|
| cl.GetDescription()
|
| cl.CloseIssue()
|
| @@ -2914,7 +2952,11 @@ def CMDset_close(parser, args):
|
|
|
| def CMDdiff(parser, args):
|
| """Shows differences between local tree and last upload."""
|
| - parser.parse_args(args)
|
| + auth.add_auth_options(parser)
|
| + options, args = parser.parse_args(args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
| + if args:
|
| + parser.error('Unrecognized args: %s' % ' '.join(args))
|
|
|
| # Uncommitted (staged and unstaged) changes will be destroyed by
|
| # "git reset --hard" if there are merging conflicts in PatchIssue().
|
| @@ -2924,7 +2966,7 @@ def CMDdiff(parser, args):
|
| if is_dirty_git_tree('diff'):
|
| return 1
|
|
|
| - cl = Changelist()
|
| + cl = Changelist(auth_config=auth_config)
|
| issue = cl.GetIssue()
|
| branch = cl.GetBranch()
|
| if not issue:
|
| @@ -2936,7 +2978,7 @@ def CMDdiff(parser, args):
|
| RunGit(['checkout', '-q', '-b', TMP_BRANCH, base_branch])
|
| try:
|
| # Patch in the latest changes from rietveld.
|
| - rtn = PatchIssue(issue, False, False, None)
|
| + rtn = PatchIssue(issue, False, False, None, auth_config)
|
| if rtn != 0:
|
| return rtn
|
|
|
| @@ -2956,11 +2998,13 @@ def CMDowners(parser, args):
|
| '--no-color',
|
| action='store_true',
|
| help='Use this option to disable color output')
|
| + auth.add_auth_options(parser)
|
| options, args = parser.parse_args(args)
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
|
|
| author = RunGit(['config', 'user.email']).strip() or None
|
|
|
| - cl = Changelist()
|
| + cl = Changelist(auth_config=auth_config)
|
|
|
| if args:
|
| if len(args) > 1:
|
|
|