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

Side by Side Diff: git_cl.py

Issue 1875163002: Refactor CMDUpload further to avoid checks IsGerrit(). (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@R100
Patch Set: git co R25 Created 4 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
« 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/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 and Gerrit.""" 8 """A git-command for integrating reviews on Rietveld and Gerrit."""
9 9
10 from distutils.version import LooseVersion 10 from distutils.version import LooseVersion
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 else: 1306 else:
1307 # Assume url. 1307 # Assume url.
1308 parsed_issue_arg = self._codereview_impl.ParseIssueURL( 1308 parsed_issue_arg = self._codereview_impl.ParseIssueURL(
1309 urlparse.urlparse(issue_arg)) 1309 urlparse.urlparse(issue_arg))
1310 if not parsed_issue_arg or not parsed_issue_arg.valid: 1310 if not parsed_issue_arg or not parsed_issue_arg.valid:
1311 DieWithError('Failed to parse issue argument "%s". ' 1311 DieWithError('Failed to parse issue argument "%s". '
1312 'Must be an issue number or a valid URL.' % issue_arg) 1312 'Must be an issue number or a valid URL.' % issue_arg)
1313 return self._codereview_impl.CMDPatchWithParsedIssue( 1313 return self._codereview_impl.CMDPatchWithParsedIssue(
1314 parsed_issue_arg, reject, nocommit, directory) 1314 parsed_issue_arg, reject, nocommit, directory)
1315 1315
1316 def CMDUpload(self, options, git_diff_args, orig_args):
1317 """Uploads a change to codereview."""
1318 if git_diff_args:
1319 # TODO(ukai): is it ok for gerrit case?
1320 base_branch = git_diff_args[0]
1321 else:
1322 if self.GetBranch() is None:
1323 DieWithError('Can\'t upload from detached HEAD state. Get on a branch!')
1324
1325 # Default to diffing against common ancestor of upstream branch
1326 base_branch = self.GetCommonAncestorWithUpstream()
1327 git_diff_args = [base_branch, 'HEAD']
1328
1329 # Make sure authenticated to codereview before running potentially expensive
1330 # hooks. It is a fast, best efforts check. Codereview still can reject the
1331 # authentication during the actual upload.
1332 self._codereview_impl.EnsureAuthenticated()
1333
1334 # Apply watchlists on upload.
1335 change = self.GetChange(base_branch, None)
1336 watchlist = watchlists.Watchlists(change.RepositoryRoot())
1337 files = [f.LocalPath() for f in change.AffectedFiles()]
1338 if not options.bypass_watchlists:
1339 self.SetWatchers(watchlist.GetWatchersForPaths(files))
1340
1341 if not options.bypass_hooks:
1342 if options.reviewers or options.tbr_owners:
1343 # Set the reviewer list now so that presubmit checks can access it.
1344 change_description = ChangeDescription(change.FullDescriptionText())
1345 change_description.update_reviewers(options.reviewers,
1346 options.tbr_owners,
1347 change)
1348 change.SetDescriptionText(change_description.description)
1349 hook_results = self.RunHook(committing=False,
1350 may_prompt=not options.force,
1351 verbose=options.verbose,
1352 change=change)
1353 if not hook_results.should_continue():
1354 return 1
1355 if not options.reviewers and hook_results.reviewers:
1356 options.reviewers = hook_results.reviewers.split(',')
1357
1358 if self.GetIssue():
1359 latest_patchset = self.GetMostRecentPatchset()
1360 local_patchset = self.GetPatchset()
1361 if (latest_patchset and local_patchset and
1362 local_patchset != latest_patchset):
1363 print ('The last upload made from this repository was patchset #%d but '
1364 'the most recent patchset on the server is #%d.'
1365 % (local_patchset, latest_patchset))
1366 print ('Uploading will still work, but if you\'ve uploaded to this '
1367 'issue from another machine or branch the patch you\'re '
1368 'uploading now might not include those changes.')
1369 ask_for_data('About to upload; enter to confirm.')
1370
1371 print_stats(options.similarity, options.find_copies, git_diff_args)
1372 ret = self.CMDUploadChange(options, git_diff_args, change)
1373 if not ret:
1374 git_set_branch_value('last-upload-hash',
1375 RunGit(['rev-parse', 'HEAD']).strip())
1376 # Run post upload hooks, if specified.
1377 if settings.GetRunPostUploadHook():
1378 presubmit_support.DoPostUploadExecuter(
1379 change,
1380 self,
1381 settings.GetRoot(),
1382 options.verbose,
1383 sys.stdout)
1384
1385 # Upload all dependencies if specified.
1386 if options.dependencies:
1387 print
1388 print '--dependencies has been specified.'
1389 print 'All dependent local branches will be re-uploaded.'
1390 print
1391 # Remove the dependencies flag from args so that we do not end up in a
1392 # loop.
1393 orig_args.remove('--dependencies')
1394 ret = upload_branch_deps(self, orig_args)
1395 return ret
1396
1316 # Forward methods to codereview specific implementation. 1397 # Forward methods to codereview specific implementation.
1317 1398
1318 def CloseIssue(self): 1399 def CloseIssue(self):
1319 return self._codereview_impl.CloseIssue() 1400 return self._codereview_impl.CloseIssue()
1320 1401
1321 def GetStatus(self): 1402 def GetStatus(self):
1322 return self._codereview_impl.GetStatus() 1403 return self._codereview_impl.GetStatus()
1323 1404
1324 def GetCodereviewServer(self): 1405 def GetCodereviewServer(self):
1325 return self._codereview_impl.GetCodereviewServer() 1406 return self._codereview_impl.GetCodereviewServer()
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 directory: switch to directory before applying the patch. Rietveld only. 1500 directory: switch to directory before applying the patch. Rietveld only.
1420 """ 1501 """
1421 raise NotImplementedError() 1502 raise NotImplementedError()
1422 1503
1423 @staticmethod 1504 @staticmethod
1424 def ParseIssueURL(parsed_url): 1505 def ParseIssueURL(parsed_url):
1425 """Parses url and returns instance of _ParsedIssueNumberArgument or None if 1506 """Parses url and returns instance of _ParsedIssueNumberArgument or None if
1426 failed.""" 1507 failed."""
1427 raise NotImplementedError() 1508 raise NotImplementedError()
1428 1509
1510 def EnsureAuthenticated(self):
1511 """Best effort check that user is authenticated with codereview server."""
1512 raise NotImplementedError()
1513
1429 def CMDUploadChange(self, options, args, change): 1514 def CMDUploadChange(self, options, args, change):
1430 """Uploads a change to codereview.""" 1515 """Uploads a change to codereview."""
1431 raise NotImplementedError() 1516 raise NotImplementedError()
1432 1517
1433 1518
1434 class _RietveldChangelistImpl(_ChangelistCodereviewBase): 1519 class _RietveldChangelistImpl(_ChangelistCodereviewBase):
1435 def __init__(self, changelist, auth_config=None, rietveld_server=None): 1520 def __init__(self, changelist, auth_config=None, rietveld_server=None):
1436 super(_RietveldChangelistImpl, self).__init__(changelist) 1521 super(_RietveldChangelistImpl, self).__init__(changelist)
1437 assert settings, 'must be initialized in _ChangelistCodereviewBase' 1522 assert settings, 'must be initialized in _ChangelistCodereviewBase'
1438 settings.GetDefaultServerUrl() 1523 settings.GetDefaultServerUrl()
1439 1524
1440 self._rietveld_server = rietveld_server 1525 self._rietveld_server = rietveld_server
1441 self._auth_config = auth_config 1526 self._auth_config = auth_config
1442 self._props = None 1527 self._props = None
1443 self._rpc_server = None 1528 self._rpc_server = None
1444 1529
1445 def GetCodereviewServer(self): 1530 def GetCodereviewServer(self):
1446 if not self._rietveld_server: 1531 if not self._rietveld_server:
1447 # If we're on a branch then get the server potentially associated 1532 # If we're on a branch then get the server potentially associated
1448 # with that branch. 1533 # with that branch.
1449 if self.GetIssue(): 1534 if self.GetIssue():
1450 rietveld_server_setting = self.GetCodereviewServerSetting() 1535 rietveld_server_setting = self.GetCodereviewServerSetting()
1451 if rietveld_server_setting: 1536 if rietveld_server_setting:
1452 self._rietveld_server = gclient_utils.UpgradeToHttps(RunGit( 1537 self._rietveld_server = gclient_utils.UpgradeToHttps(RunGit(
1453 ['config', rietveld_server_setting], error_ok=True).strip()) 1538 ['config', rietveld_server_setting], error_ok=True).strip())
1454 if not self._rietveld_server: 1539 if not self._rietveld_server:
1455 self._rietveld_server = settings.GetDefaultServerUrl() 1540 self._rietveld_server = settings.GetDefaultServerUrl()
1456 return self._rietveld_server 1541 return self._rietveld_server
1457 1542
1543 def EnsureAuthenticated(self):
1544 """Best effort check that user is authenticated with Rietveld server."""
1545 if self._auth_config.use_oauth2:
1546 authenticator = auth.get_authenticator_for_host(
1547 self.GetCodereviewServer(), self._auth_config)
1548 if not authenticator.has_cached_credentials():
1549 raise auth.LoginRequiredError(self.GetCodereviewServer())
1550
1458 def FetchDescription(self): 1551 def FetchDescription(self):
1459 issue = self.GetIssue() 1552 issue = self.GetIssue()
1460 assert issue 1553 assert issue
1461 try: 1554 try:
1462 return self.RpcServer().get_description(issue).strip() 1555 return self.RpcServer().get_description(issue).strip()
1463 except urllib2.HTTPError as e: 1556 except urllib2.HTTPError as e:
1464 if e.code == 404: 1557 if e.code == 404:
1465 DieWithError( 1558 DieWithError(
1466 ('\nWhile fetching the description for issue %d, received a ' 1559 ('\nWhile fetching the description for issue %d, received a '
1467 '404 (not found)\n' 1560 '404 (not found)\n'
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 auth_config = auth.extract_auth_config_from_options(options) 1883 auth_config = auth.extract_auth_config_from_options(options)
1791 branch_cl = Changelist(branchref=local_branch, 1884 branch_cl = Changelist(branchref=local_branch,
1792 auth_config=auth_config) 1885 auth_config=auth_config)
1793 branch_cl_issue_url = branch_cl.GetIssueURL() 1886 branch_cl_issue_url = branch_cl.GetIssueURL()
1794 branch_cl_issue = branch_cl.GetIssue() 1887 branch_cl_issue = branch_cl.GetIssue()
1795 branch_cl_patchset = branch_cl.GetPatchset() 1888 branch_cl_patchset = branch_cl.GetPatchset()
1796 if branch_cl_issue_url and branch_cl_issue and branch_cl_patchset: 1889 if branch_cl_issue_url and branch_cl_issue and branch_cl_patchset:
1797 upload_args.extend( 1890 upload_args.extend(
1798 ['--depends_on_patchset', '%s:%s' % ( 1891 ['--depends_on_patchset', '%s:%s' % (
1799 branch_cl_issue, branch_cl_patchset)]) 1892 branch_cl_issue, branch_cl_patchset)])
1800 print ( 1893 print(
1801 '\n' 1894 '\n'
1802 'The current branch (%s) is tracking a local branch (%s) with ' 1895 'The current branch (%s) is tracking a local branch (%s) with '
1803 'an associated CL.\n' 1896 'an associated CL.\n'
1804 'Adding %s/#ps%s as a dependency patchset.\n' 1897 'Adding %s/#ps%s as a dependency patchset.\n'
1805 '\n' % (self.GetBranch(), local_branch, branch_cl_issue_url, 1898 '\n' % (self.GetBranch(), local_branch, branch_cl_issue_url,
1806 branch_cl_patchset)) 1899 branch_cl_patchset))
1807 1900
1808 project = settings.GetProject() 1901 project = settings.GetProject()
1809 if project: 1902 if project:
1810 upload_args.extend(['--project', project]) 1903 upload_args.extend(['--project', project])
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 parts = urlparse.urlparse(self.GetRemoteUrl()).netloc.split('.') 1964 parts = urlparse.urlparse(self.GetRemoteUrl()).netloc.split('.')
1872 parts[0] = parts[0] + '-review' 1965 parts[0] = parts[0] + '-review'
1873 self._gerrit_host = '.'.join(parts) 1966 self._gerrit_host = '.'.join(parts)
1874 self._gerrit_server = 'https://%s' % self._gerrit_host 1967 self._gerrit_server = 'https://%s' % self._gerrit_host
1875 return self._gerrit_server 1968 return self._gerrit_server
1876 1969
1877 @classmethod 1970 @classmethod
1878 def IssueSettingPrefix(cls): 1971 def IssueSettingPrefix(cls):
1879 return 'gerritissue' 1972 return 'gerritissue'
1880 1973
1974 def EnsureAuthenticated(self):
1975 """Best effort check that user is authenticated with Gerrit server."""
1976 #TODO(tandrii): implement per bug http://crbug.com/583153.
1977
1881 def PatchsetSetting(self): 1978 def PatchsetSetting(self):
1882 """Return the git setting that stores this change's most recent patchset.""" 1979 """Return the git setting that stores this change's most recent patchset."""
1883 return 'branch.%s.gerritpatchset' % self.GetBranch() 1980 return 'branch.%s.gerritpatchset' % self.GetBranch()
1884 1981
1885 def GetCodereviewServerSetting(self): 1982 def GetCodereviewServerSetting(self):
1886 """Returns the git setting that stores this change's Gerrit server.""" 1983 """Returns the git setting that stores this change's Gerrit server."""
1887 branch = self.GetBranch() 1984 branch = self.GetBranch()
1888 if branch: 1985 if branch:
1889 return 'branch.%s.gerritserver' % branch 1986 return 'branch.%s.gerritserver' % branch
1890 return None 1987 return None
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
2072 match = re.match('(/c)?/(\d+)(/(\d+)?/?)?$', part) 2169 match = re.match('(/c)?/(\d+)(/(\d+)?/?)?$', part)
2073 if match: 2170 if match:
2074 return _ParsedIssueNumberArgument( 2171 return _ParsedIssueNumberArgument(
2075 issue=int(match.group(2)), 2172 issue=int(match.group(2)),
2076 patchset=int(match.group(4)) if match.group(4) else None, 2173 patchset=int(match.group(4)) if match.group(4) else None,
2077 hostname=parsed_url.netloc) 2174 hostname=parsed_url.netloc)
2078 return None 2175 return None
2079 2176
2080 def CMDUploadChange(self, options, args, change): 2177 def CMDUploadChange(self, options, args, change):
2081 """Upload the current branch to Gerrit.""" 2178 """Upload the current branch to Gerrit."""
2179 if options.squash and options.no_squash:
2180 DieWithError('Can only use one of --squash or --no-squash')
2181 options.squash = ((settings.GetSquashGerritUploads() or options.squash) and
2182 not options.no_squash)
2082 # We assume the remote called "origin" is the one we want. 2183 # We assume the remote called "origin" is the one we want.
2083 # It is probably not worthwhile to support different workflows. 2184 # It is probably not worthwhile to support different workflows.
2084 gerrit_remote = 'origin' 2185 gerrit_remote = 'origin'
2085 2186
2086 remote, remote_branch = self.GetRemoteBranch() 2187 remote, remote_branch = self.GetRemoteBranch()
2087 branch = GetTargetRef(remote, remote_branch, options.target_branch, 2188 branch = GetTargetRef(remote, remote_branch, options.target_branch,
2088 pending_prefix='') 2189 pending_prefix='')
2089 2190
2090 if options.title: 2191 if options.title:
2091 # TODO(tandrii): it's now supported by Gerrit, implement! 2192 # TODO(tandrii): it's now supported by Gerrit, implement!
(...skipping 1191 matching lines...) Expand 10 before | Expand all | Expand 10 after
3283 if git_common.is_dirty_git_tree('upload'): 3384 if git_common.is_dirty_git_tree('upload'):
3284 return 1 3385 return 1
3285 3386
3286 options.reviewers = cleanup_list(options.reviewers) 3387 options.reviewers = cleanup_list(options.reviewers)
3287 options.cc = cleanup_list(options.cc) 3388 options.cc = cleanup_list(options.cc)
3288 3389
3289 # For sanity of test expectations, do this otherwise lazy-loading *now*. 3390 # For sanity of test expectations, do this otherwise lazy-loading *now*.
3290 settings.GetIsGerrit() 3391 settings.GetIsGerrit()
3291 3392
3292 cl = Changelist(auth_config=auth_config) 3393 cl = Changelist(auth_config=auth_config)
3293 if args: 3394 return cl.CMDUpload(options, args, orig_args)
3294 # TODO(ukai): is it ok for gerrit case?
3295 base_branch = args[0]
3296 else:
3297 if cl.GetBranch() is None:
3298 DieWithError('Can\'t upload from detached HEAD state. Get on a branch!')
3299
3300 # Default to diffing against common ancestor of upstream branch
3301 base_branch = cl.GetCommonAncestorWithUpstream()
3302 args = [base_branch, 'HEAD']
3303
3304 # Make sure authenticated to Rietveld before running expensive hooks. It is
3305 # a fast, best efforts check. Rietveld still can reject the authentication
3306 # during the actual upload.
3307 if not cl.IsGerrit() and auth_config.use_oauth2:
3308 authenticator = auth.get_authenticator_for_host(
3309 cl.GetCodereviewServer(), auth_config)
3310 if not authenticator.has_cached_credentials():
3311 raise auth.LoginRequiredError(cl.GetCodereviewServer())
3312
3313 # Apply watchlists on upload.
3314 change = cl.GetChange(base_branch, None)
3315 watchlist = watchlists.Watchlists(change.RepositoryRoot())
3316 files = [f.LocalPath() for f in change.AffectedFiles()]
3317 if not options.bypass_watchlists:
3318 cl.SetWatchers(watchlist.GetWatchersForPaths(files))
3319
3320 if not options.bypass_hooks:
3321 if options.reviewers or options.tbr_owners:
3322 # Set the reviewer list now so that presubmit checks can access it.
3323 change_description = ChangeDescription(change.FullDescriptionText())
3324 change_description.update_reviewers(options.reviewers,
3325 options.tbr_owners,
3326 change)
3327 change.SetDescriptionText(change_description.description)
3328 hook_results = cl.RunHook(committing=False,
3329 may_prompt=not options.force,
3330 verbose=options.verbose,
3331 change=change)
3332 if not hook_results.should_continue():
3333 return 1
3334 if not options.reviewers and hook_results.reviewers:
3335 options.reviewers = hook_results.reviewers.split(',')
3336
3337 if cl.GetIssue():
3338 latest_patchset = cl.GetMostRecentPatchset()
3339 local_patchset = cl.GetPatchset()
3340 if latest_patchset and local_patchset and local_patchset != latest_patchset:
3341 print ('The last upload made from this repository was patchset #%d but '
3342 'the most recent patchset on the server is #%d.'
3343 % (local_patchset, latest_patchset))
3344 print ('Uploading will still work, but if you\'ve uploaded to this issue '
3345 'from another machine or branch the patch you\'re uploading now '
3346 'might not include those changes.')
3347 ask_for_data('About to upload; enter to confirm.')
3348
3349 print_stats(options.similarity, options.find_copies, args)
3350 if cl.IsGerrit():
3351 if options.squash and options.no_squash:
3352 DieWithError('Can only use one of --squash or --no-squash')
3353
3354 options.squash = ((settings.GetSquashGerritUploads() or options.squash) and
3355 not options.no_squash)
3356
3357 ret = cl.CMDUploadChange(options, args, change)
3358 if not ret:
3359 git_set_branch_value('last-upload-hash',
3360 RunGit(['rev-parse', 'HEAD']).strip())
3361 # Run post upload hooks, if specified.
3362 if settings.GetRunPostUploadHook():
3363 presubmit_support.DoPostUploadExecuter(
3364 change,
3365 cl,
3366 settings.GetRoot(),
3367 options.verbose,
3368 sys.stdout)
3369
3370 # Upload all dependencies if specified.
3371 if options.dependencies:
3372 print
3373 print '--dependencies has been specified.'
3374 print 'All dependent local branches will be re-uploaded.'
3375 print
3376 # Remove the dependencies flag from args so that we do not end up in a
3377 # loop.
3378 orig_args.remove('--dependencies')
3379 upload_branch_deps(cl, orig_args)
3380 return ret
3381 3395
3382 3396
3383 def IsSubmoduleMergeCommit(ref): 3397 def IsSubmoduleMergeCommit(ref):
3384 # When submodules are added to the repo, we expect there to be a single 3398 # When submodules are added to the repo, we expect there to be a single
3385 # non-git-svn merge commit at remote HEAD with a signature comment. 3399 # non-git-svn merge commit at remote HEAD with a signature comment.
3386 pattern = '^SVN changes up to revision [0-9]*$' 3400 pattern = '^SVN changes up to revision [0-9]*$'
3387 cmd = ['rev-list', '--merges', '--grep=%s' % pattern, '%s^!' % ref] 3401 cmd = ['rev-list', '--merges', '--grep=%s' % pattern, '%s^!' % ref]
3388 return RunGit(cmd) != '' 3402 return RunGit(cmd) != ''
3389 3403
3390 3404
(...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after
4637 if __name__ == '__main__': 4651 if __name__ == '__main__':
4638 # These affect sys.stdout so do it outside of main() to simplify mocks in 4652 # These affect sys.stdout so do it outside of main() to simplify mocks in
4639 # unit testing. 4653 # unit testing.
4640 fix_encoding.fix_encoding() 4654 fix_encoding.fix_encoding()
4641 setup_color.init() 4655 setup_color.init()
4642 try: 4656 try:
4643 sys.exit(main(sys.argv[1:])) 4657 sys.exit(main(sys.argv[1:]))
4644 except KeyboardInterrupt: 4658 except KeyboardInterrupt:
4645 sys.stderr.write('interrupted\n') 4659 sys.stderr.write('interrupted\n')
4646 sys.exit(1) 4660 sys.exit(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