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 import logging | 10 import logging |
(...skipping 25 matching lines...) Expand all Loading... |
36 import breakpad # pylint: disable=W0611 | 36 import breakpad # pylint: disable=W0611 |
37 import fix_encoding | 37 import fix_encoding |
38 import gclient_utils | 38 import gclient_utils |
39 import presubmit_support | 39 import presubmit_support |
40 import rietveld | 40 import rietveld |
41 import scm | 41 import scm |
42 import subprocess2 | 42 import subprocess2 |
43 import watchlists | 43 import watchlists |
44 | 44 |
45 | 45 |
46 DEFAULT_SERVER = 'http://codereview.appspot.com' | 46 DEFAULT_SERVER = 'https://codereview.appspot.com' |
47 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s' | 47 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s' |
48 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' | 48 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' |
49 | 49 |
50 | 50 |
51 # Initialized in main() | 51 # Initialized in main() |
52 settings = None | 52 settings = None |
53 | 53 |
54 | 54 |
55 def DieWithError(message): | 55 def DieWithError(message): |
56 print >> sys.stderr, message | 56 print >> sys.stderr, message |
(...skipping 30 matching lines...) Expand all Loading... |
87 | 87 |
88 | 88 |
89 def ask_for_data(prompt): | 89 def ask_for_data(prompt): |
90 try: | 90 try: |
91 return raw_input(prompt) | 91 return raw_input(prompt) |
92 except KeyboardInterrupt: | 92 except KeyboardInterrupt: |
93 # Hide the exception. | 93 # Hide the exception. |
94 sys.exit(1) | 94 sys.exit(1) |
95 | 95 |
96 | 96 |
97 def FixUrl(server): | |
98 """Fix a server url to defaults protocol to http:// if none is specified.""" | |
99 if not server: | |
100 return server | |
101 if not re.match(r'[a-z]+\://.*', server): | |
102 return 'http://' + server | |
103 return server | |
104 | |
105 | |
106 def MatchSvnGlob(url, base_url, glob_spec, allow_wildcards): | 97 def MatchSvnGlob(url, base_url, glob_spec, allow_wildcards): |
107 """Return the corresponding git ref if |base_url| together with |glob_spec| | 98 """Return the corresponding git ref if |base_url| together with |glob_spec| |
108 matches the full |url|. | 99 matches the full |url|. |
109 | 100 |
110 If |allow_wildcards| is true, |glob_spec| can contain wildcards (see below). | 101 If |allow_wildcards| is true, |glob_spec| can contain wildcards (see below). |
111 """ | 102 """ |
112 fetch_suburl, as_ref = glob_spec.split(':') | 103 fetch_suburl, as_ref = glob_spec.split(':') |
113 if allow_wildcards: | 104 if allow_wildcards: |
114 glob_match = re.match('(.+/)?(\*|{[^/]*})(/.+)?', fetch_suburl) | 105 glob_match = re.match('(.+/)?(\*|{[^/]*})(/.+)?', fetch_suburl) |
115 if glob_match: | 106 if glob_match: |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 """Updates the settings from a codereview.settings file, if available.""" | 152 """Updates the settings from a codereview.settings file, if available.""" |
162 if not self.updated: | 153 if not self.updated: |
163 cr_settings_file = FindCodereviewSettingsFile() | 154 cr_settings_file = FindCodereviewSettingsFile() |
164 if cr_settings_file: | 155 if cr_settings_file: |
165 LoadCodereviewSettingsFromFile(cr_settings_file) | 156 LoadCodereviewSettingsFromFile(cr_settings_file) |
166 self.updated = True | 157 self.updated = True |
167 | 158 |
168 def GetDefaultServerUrl(self, error_ok=False): | 159 def GetDefaultServerUrl(self, error_ok=False): |
169 if not self.default_server: | 160 if not self.default_server: |
170 self.LazyUpdateIfNeeded() | 161 self.LazyUpdateIfNeeded() |
171 self.default_server = FixUrl(self._GetConfig('rietveld.server', | 162 self.default_server = gclient_utils.UpgradeToHttps( |
172 error_ok=True)) | 163 self._GetConfig('rietveld.server', error_ok=True)) |
173 if error_ok: | 164 if error_ok: |
174 return self.default_server | 165 return self.default_server |
175 if not self.default_server: | 166 if not self.default_server: |
176 error_message = ('Could not find settings file. You must configure ' | 167 error_message = ('Could not find settings file. You must configure ' |
177 'your review setup by running "git cl config".') | 168 'your review setup by running "git cl config".') |
178 self.default_server = FixUrl(self._GetConfig( | 169 self.default_server = gclient_utils.UpgradeToHttps( |
179 'rietveld.server', error_message=error_message)) | 170 self._GetConfig('rietveld.server', error_message=error_message)) |
180 return self.default_server | 171 return self.default_server |
181 | 172 |
182 def GetRoot(self): | 173 def GetRoot(self): |
183 if not self.root: | 174 if not self.root: |
184 self.root = os.path.abspath(RunGit(['rev-parse', '--show-cdup']).strip()) | 175 self.root = os.path.abspath(RunGit(['rev-parse', '--show-cdup']).strip()) |
185 return self.root | 176 return self.root |
186 | 177 |
187 def GetIsGitSvn(self): | 178 def GetIsGitSvn(self): |
188 """Return true if this repo looks like it's using git-svn.""" | 179 """Return true if this repo looks like it's using git-svn.""" |
189 if self.is_git_svn is None: | 180 if self.is_git_svn is None: |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 if not self.tree_status_url: | 250 if not self.tree_status_url: |
260 error_message = ('You must configure your tree status URL by running ' | 251 error_message = ('You must configure your tree status URL by running ' |
261 '"git cl config".') | 252 '"git cl config".') |
262 self.tree_status_url = self._GetConfig('rietveld.tree-status-url', | 253 self.tree_status_url = self._GetConfig('rietveld.tree-status-url', |
263 error_ok=error_ok, | 254 error_ok=error_ok, |
264 error_message=error_message) | 255 error_message=error_message) |
265 return self.tree_status_url | 256 return self.tree_status_url |
266 | 257 |
267 def GetViewVCUrl(self): | 258 def GetViewVCUrl(self): |
268 if not self.viewvc_url: | 259 if not self.viewvc_url: |
269 self.viewvc_url = self._GetConfig('rietveld.viewvc-url', error_ok=True) | 260 self.viewvc_url = gclient_utils.UpgradeToHttps( |
| 261 self._GetConfig('rietveld.viewvc-url', error_ok=True)) |
270 return self.viewvc_url | 262 return self.viewvc_url |
271 | 263 |
272 def GetDefaultCCList(self): | 264 def GetDefaultCCList(self): |
273 return self._GetConfig('rietveld.cc', error_ok=True) | 265 return self._GetConfig('rietveld.cc', error_ok=True) |
274 | 266 |
275 def _GetConfig(self, param, **kwargs): | 267 def _GetConfig(self, param, **kwargs): |
276 self.LazyUpdateIfNeeded() | 268 self.LazyUpdateIfNeeded() |
277 return RunGit(['config', param], **kwargs).strip() | 269 return RunGit(['config', param], **kwargs).strip() |
278 | 270 |
279 | 271 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 if remote == '.': | 411 if remote == '.': |
420 return None | 412 return None |
421 return RunGit(['config', 'remote.%s.url' % remote], error_ok=True).strip() | 413 return RunGit(['config', 'remote.%s.url' % remote], error_ok=True).strip() |
422 | 414 |
423 def GetIssue(self): | 415 def GetIssue(self): |
424 if not self.has_issue: | 416 if not self.has_issue: |
425 CheckForMigration() | 417 CheckForMigration() |
426 issue = RunGit(['config', self._IssueSetting()], error_ok=True).strip() | 418 issue = RunGit(['config', self._IssueSetting()], error_ok=True).strip() |
427 if issue: | 419 if issue: |
428 self.issue = issue | 420 self.issue = issue |
429 self.rietveld_server = FixUrl(RunGit( | 421 self.rietveld_server = gclient_utils.UpgradeToHttps(RunGit( |
430 ['config', self._RietveldServer()], error_ok=True).strip()) | 422 ['config', self._RietveldServer()], error_ok=True).strip()) |
431 else: | 423 else: |
432 self.issue = None | 424 self.issue = None |
433 if not self.rietveld_server: | 425 if not self.rietveld_server: |
434 self.rietveld_server = settings.GetDefaultServerUrl() | 426 self.rietveld_server = settings.GetDefaultServerUrl() |
435 self.has_issue = True | 427 self.has_issue = True |
436 return self.issue | 428 return self.issue |
437 | 429 |
438 def GetRietveldServer(self): | 430 def GetRietveldServer(self): |
439 self.GetIssue() | 431 self.GetIssue() |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 | 610 |
619 | 611 |
620 def GetCodereviewSettingsInteractively(): | 612 def GetCodereviewSettingsInteractively(): |
621 """Prompt the user for settings.""" | 613 """Prompt the user for settings.""" |
622 server = settings.GetDefaultServerUrl(error_ok=True) | 614 server = settings.GetDefaultServerUrl(error_ok=True) |
623 prompt = 'Rietveld server (host[:port])' | 615 prompt = 'Rietveld server (host[:port])' |
624 prompt += ' [%s]' % (server or DEFAULT_SERVER) | 616 prompt += ' [%s]' % (server or DEFAULT_SERVER) |
625 newserver = ask_for_data(prompt + ':') | 617 newserver = ask_for_data(prompt + ':') |
626 if not server and not newserver: | 618 if not server and not newserver: |
627 newserver = DEFAULT_SERVER | 619 newserver = DEFAULT_SERVER |
628 if newserver and newserver != server: | 620 if newserver: |
629 RunGit(['config', 'rietveld.server', newserver]) | 621 newserver = gclient_utils.UpgradeToHttps(newserver) |
| 622 if newserver != server: |
| 623 RunGit(['config', 'rietveld.server', newserver]) |
630 | 624 |
631 def SetProperty(initial, caption, name): | 625 def SetProperty(initial, caption, name, is_url): |
632 prompt = caption | 626 prompt = caption |
633 if initial: | 627 if initial: |
634 prompt += ' ("x" to clear) [%s]' % initial | 628 prompt += ' ("x" to clear) [%s]' % initial |
635 new_val = ask_for_data(prompt + ':') | 629 new_val = ask_for_data(prompt + ':') |
636 if new_val == 'x': | 630 if new_val == 'x': |
637 RunGit(['config', '--unset-all', 'rietveld.' + name], error_ok=True) | 631 RunGit(['config', '--unset-all', 'rietveld.' + name], error_ok=True) |
638 elif new_val and new_val != initial: | 632 elif new_val: |
639 RunGit(['config', 'rietveld.' + name, new_val]) | 633 if is_url: |
| 634 new_val = gclient_utils.UpgradeToHttps(new_val) |
| 635 if new_val != initial: |
| 636 RunGit(['config', 'rietveld.' + name, new_val]) |
640 | 637 |
641 SetProperty(settings.GetDefaultCCList(), 'CC list', 'cc') | 638 SetProperty(settings.GetDefaultCCList(), 'CC list', 'cc', False) |
642 SetProperty(settings.GetTreeStatusUrl(error_ok=True), 'Tree status URL', | 639 SetProperty(settings.GetTreeStatusUrl(error_ok=True), 'Tree status URL', |
643 'tree-status-url') | 640 'tree-status-url', False) |
644 SetProperty(settings.GetViewVCUrl(), 'ViewVC URL', 'viewvc-url') | 641 SetProperty(settings.GetViewVCUrl(), 'ViewVC URL', 'viewvc-url', True) |
645 | 642 |
646 # TODO: configure a default branch to diff against, rather than this | 643 # TODO: configure a default branch to diff against, rather than this |
647 # svn-based hackery. | 644 # svn-based hackery. |
648 | 645 |
649 | 646 |
650 class ChangeDescription(object): | 647 class ChangeDescription(object): |
651 """Contains a parsed form of the change description.""" | 648 """Contains a parsed form of the change description.""" |
652 def __init__(self, subject, log_desc, reviewers): | 649 def __init__(self, subject, log_desc, reviewers): |
653 self.subject = subject | 650 self.subject = subject |
654 self.log_desc = log_desc | 651 self.log_desc = log_desc |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 return 1 | 1228 return 1 |
1232 issue_arg = args[0] | 1229 issue_arg = args[0] |
1233 | 1230 |
1234 # TODO(maruel): Use apply_issue.py | 1231 # TODO(maruel): Use apply_issue.py |
1235 | 1232 |
1236 if re.match(r'\d+', issue_arg): | 1233 if re.match(r'\d+', issue_arg): |
1237 # Input is an issue id. Figure out the URL. | 1234 # Input is an issue id. Figure out the URL. |
1238 issue = issue_arg | 1235 issue = issue_arg |
1239 patch_data = Changelist().GetPatchSetDiff(issue) | 1236 patch_data = Changelist().GetPatchSetDiff(issue) |
1240 else: | 1237 else: |
1241 # Assume it's a URL to the patch. Default to http. | 1238 # Assume it's a URL to the patch. Default to https. |
1242 issue_url = FixUrl(issue_arg) | 1239 issue_url = gclient_utils.UpgradeToHttps(issue_arg) |
1243 match = re.match(r'.*?/issue(\d+)_\d+.diff', issue_url) | 1240 match = re.match(r'.*?/issue(\d+)_\d+.diff', issue_url) |
1244 if not match: | 1241 if not match: |
1245 DieWithError('Must pass an issue ID or full URL for ' | 1242 DieWithError('Must pass an issue ID or full URL for ' |
1246 '\'Download raw patch set\'') | 1243 '\'Download raw patch set\'') |
1247 issue = match.group(1) | 1244 issue = match.group(1) |
1248 patch_data = urllib2.urlopen(issue_arg).read() | 1245 patch_data = urllib2.urlopen(issue_arg).read() |
1249 | 1246 |
1250 if options.newbranch: | 1247 if options.newbranch: |
1251 if options.force: | 1248 if options.force: |
1252 RunGit(['branch', '-D', options.newbranch], | 1249 RunGit(['branch', '-D', options.newbranch], |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 1428 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
1432 | 1429 |
1433 # Not a known command. Default to help. | 1430 # Not a known command. Default to help. |
1434 GenUsage(parser, 'help') | 1431 GenUsage(parser, 'help') |
1435 return CMDhelp(parser, argv) | 1432 return CMDhelp(parser, argv) |
1436 | 1433 |
1437 | 1434 |
1438 if __name__ == '__main__': | 1435 if __name__ == '__main__': |
1439 fix_encoding.fix_encoding() | 1436 fix_encoding.fix_encoding() |
1440 sys.exit(main(sys.argv[1:])) | 1437 sys.exit(main(sys.argv[1:])) |
OLD | NEW |