OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 # Copyright (C) 2008 Evan Martin <martine@danga.com> | 6 # Copyright (C) 2008 Evan Martin <martine@danga.com> |
7 | 7 |
8 """A git-command for integrating reviews on Rietveld.""" | 8 """A git-command for integrating reviews on Rietveld.""" |
9 | 9 |
10 import errno | 10 import errno |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 error_ok=True)) | 188 error_ok=True)) |
189 if error_ok: | 189 if error_ok: |
190 return self.default_server | 190 return self.default_server |
191 if not self.default_server: | 191 if not self.default_server: |
192 error_message = ('Could not find settings file. You must configure ' | 192 error_message = ('Could not find settings file. You must configure ' |
193 'your review setup by running "git cl config".') | 193 'your review setup by running "git cl config".') |
194 self.default_server = FixUrl(self._GetConfig( | 194 self.default_server = FixUrl(self._GetConfig( |
195 'rietveld.server', error_message=error_message)) | 195 'rietveld.server', error_message=error_message)) |
196 return self.default_server | 196 return self.default_server |
197 | 197 |
198 def GetCCList(self): | |
199 """Return the users cc'd on this CL. | |
200 | |
201 Return is a string suitable for passing to gcl with the --cc flag. | |
202 """ | |
203 if self.cc is None: | |
204 base_cc = self._GetConfig('rietveld.cc', error_ok=True) | |
205 more_cc = self._GetConfig('rietveld.extracc', error_ok=True) | |
206 self.cc = ','.join(filter(None, (base_cc, more_cc))) or '' | |
207 return self.cc | |
208 | |
209 def GetRoot(self): | 198 def GetRoot(self): |
210 if not self.root: | 199 if not self.root: |
211 self.root = os.path.abspath(RunGit(['rev-parse', '--show-cdup']).strip()) | 200 self.root = os.path.abspath(RunGit(['rev-parse', '--show-cdup']).strip()) |
212 return self.root | 201 return self.root |
213 | 202 |
214 def GetIsGitSvn(self): | 203 def GetIsGitSvn(self): |
215 """Return true if this repo looks like it's using git-svn.""" | 204 """Return true if this repo looks like it's using git-svn.""" |
216 if self.is_git_svn is None: | 205 if self.is_git_svn is None: |
217 # If you have any "svn-remote.*" config keys, we think you're using svn. | 206 # If you have any "svn-remote.*" config keys, we think you're using svn. |
218 self.is_git_svn = RunGitWithCode( | 207 self.is_git_svn = RunGitWithCode( |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 self.tree_status_url = self._GetConfig('rietveld.tree-status-url', | 277 self.tree_status_url = self._GetConfig('rietveld.tree-status-url', |
289 error_ok=error_ok, | 278 error_ok=error_ok, |
290 error_message=error_message) | 279 error_message=error_message) |
291 return self.tree_status_url | 280 return self.tree_status_url |
292 | 281 |
293 def GetViewVCUrl(self): | 282 def GetViewVCUrl(self): |
294 if not self.viewvc_url: | 283 if not self.viewvc_url: |
295 self.viewvc_url = self._GetConfig('rietveld.viewvc-url', error_ok=True) | 284 self.viewvc_url = self._GetConfig('rietveld.viewvc-url', error_ok=True) |
296 return self.viewvc_url | 285 return self.viewvc_url |
297 | 286 |
| 287 def GetDefaultCCList(self): |
| 288 return self._GetConfig('rietveld.cc', error_ok=True) |
| 289 |
298 def _GetConfig(self, param, **kwargs): | 290 def _GetConfig(self, param, **kwargs): |
299 self.LazyUpdateIfNeeded() | 291 self.LazyUpdateIfNeeded() |
300 return RunGit(['config', param], **kwargs).strip() | 292 return RunGit(['config', param], **kwargs).strip() |
301 | 293 |
302 | 294 |
303 settings = Settings() | 295 settings = Settings() |
304 | 296 |
305 | 297 |
306 did_migrate_check = False | 298 did_migrate_check = False |
307 def CheckForMigration(): | 299 def CheckForMigration(): |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 self.branch = None | 339 self.branch = None |
348 self.rietveld_server = None | 340 self.rietveld_server = None |
349 self.upstream_branch = None | 341 self.upstream_branch = None |
350 self.has_issue = False | 342 self.has_issue = False |
351 self.issue = None | 343 self.issue = None |
352 self.has_description = False | 344 self.has_description = False |
353 self.description = None | 345 self.description = None |
354 self.has_patchset = False | 346 self.has_patchset = False |
355 self.patchset = None | 347 self.patchset = None |
356 self._rpc_server = None | 348 self._rpc_server = None |
| 349 self.cc = None |
| 350 self.watchers = () |
| 351 |
| 352 def GetCCList(self): |
| 353 """Return the users cc'd on this CL. |
| 354 |
| 355 Return is a string suitable for passing to gcl with the --cc flag. |
| 356 """ |
| 357 if self.cc is None: |
| 358 base_cc = settings .GetDefaultCCList() |
| 359 more_cc = ','.join(self.watchers) |
| 360 self.cc = ','.join(filter(None, (base_cc, more_cc))) or '' |
| 361 return self.cc |
| 362 |
| 363 def SetWatchers(self, watchers): |
| 364 """Set the list of email addresses that should be cc'd based on the changed |
| 365 files in this CL. |
| 366 """ |
| 367 self.watchers = watchers |
357 | 368 |
358 def GetBranch(self): | 369 def GetBranch(self): |
359 """Returns the short branch name, e.g. 'master'.""" | 370 """Returns the short branch name, e.g. 'master'.""" |
360 if not self.branch: | 371 if not self.branch: |
361 self.branchref = RunGit(['symbolic-ref', 'HEAD']).strip() | 372 self.branchref = RunGit(['symbolic-ref', 'HEAD']).strip() |
362 self.branch = ShortBranchName(self.branchref) | 373 self.branch = ShortBranchName(self.branchref) |
363 return self.branch | 374 return self.branch |
364 | 375 |
365 def GetBranchRef(self): | 376 def GetBranchRef(self): |
366 """Returns the full branch name, e.g. 'refs/heads/master'.""" | 377 """Returns the full branch name, e.g. 'refs/heads/master'.""" |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 def SetProperty(initial, caption, name): | 560 def SetProperty(initial, caption, name): |
550 prompt = caption | 561 prompt = caption |
551 if initial: | 562 if initial: |
552 prompt += ' ("x" to clear) [%s]' % initial | 563 prompt += ' ("x" to clear) [%s]' % initial |
553 new_val = ask_for_data(prompt + ':') | 564 new_val = ask_for_data(prompt + ':') |
554 if new_val == 'x': | 565 if new_val == 'x': |
555 RunGit(['config', '--unset-all', 'rietveld.' + name], error_ok=True) | 566 RunGit(['config', '--unset-all', 'rietveld.' + name], error_ok=True) |
556 elif new_val and new_val != initial: | 567 elif new_val and new_val != initial: |
557 RunGit(['config', 'rietveld.' + name, new_val]) | 568 RunGit(['config', 'rietveld.' + name, new_val]) |
558 | 569 |
559 SetProperty(settings.GetCCList(), 'CC list', 'cc') | 570 SetProperty(settings.GetDefaultCCList(), 'CC list', 'cc') |
560 SetProperty(settings.GetTreeStatusUrl(error_ok=True), 'Tree status URL', | 571 SetProperty(settings.GetTreeStatusUrl(error_ok=True), 'Tree status URL', |
561 'tree-status-url') | 572 'tree-status-url') |
562 SetProperty(settings.GetViewVCUrl(), 'ViewVC URL', 'viewvc-url') | 573 SetProperty(settings.GetViewVCUrl(), 'ViewVC URL', 'viewvc-url') |
563 | 574 |
564 # TODO: configure a default branch to diff against, rather than this | 575 # TODO: configure a default branch to diff against, rather than this |
565 # svn-based hackery. | 576 # svn-based hackery. |
566 | 577 |
567 | 578 |
568 class ChangeDescription(object): | 579 class ChangeDescription(object): |
569 """Contains a parsed form of the change description.""" | 580 """Contains a parsed form of the change description.""" |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 # with these log messages. | 834 # with these log messages. |
824 description = RunCommand(['git', 'log', '--pretty=format:%s%n%n%b', | 835 description = RunCommand(['git', 'log', '--pretty=format:%s%n%n%b', |
825 '%s...' % (upstream_branch)]).strip() | 836 '%s...' % (upstream_branch)]).strip() |
826 change = presubmit_support.GitChange(name, description, absroot, files, | 837 change = presubmit_support.GitChange(name, description, absroot, files, |
827 issue, patchset) | 838 issue, patchset) |
828 | 839 |
829 # Apply watchlists on upload. | 840 # Apply watchlists on upload. |
830 if not committing: | 841 if not committing: |
831 watchlist = watchlists.Watchlists(change.RepositoryRoot()) | 842 watchlist = watchlists.Watchlists(change.RepositoryRoot()) |
832 files = [f.LocalPath() for f in change.AffectedFiles()] | 843 files = [f.LocalPath() for f in change.AffectedFiles()] |
833 watchers = watchlist.GetWatchersForPaths(files) | 844 cl.SetWatchers(watchlist.GetWatchersForPaths(files)) |
834 RunCommand(['git', 'config', '--replace-all', | |
835 'rietveld.extracc', ','.join(watchers)]) | |
836 | 845 |
837 output = presubmit_support.DoPresubmitChecks(change, committing, | 846 output = presubmit_support.DoPresubmitChecks(change, committing, |
838 verbose=False, output_stream=sys.stdout, input_stream=sys.stdin, | 847 verbose=False, output_stream=sys.stdout, input_stream=sys.stdin, |
839 default_presubmit=None, may_prompt=may_prompt, tbr=tbr, | 848 default_presubmit=None, may_prompt=may_prompt, tbr=tbr, |
840 host_url=cl.GetRietveldServer()) | 849 host_url=cl.GetRietveldServer()) |
841 | 850 |
842 # TODO(dpranke): We should propagate the error out instead of calling exit(). | 851 # TODO(dpranke): We should propagate the error out instead of calling exit(). |
843 if not output.should_continue(): | 852 if not output.should_continue(): |
844 sys.exit(1) | 853 sys.exit(1) |
845 | 854 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
954 change_desc.Update() | 963 change_desc.Update() |
955 | 964 |
956 if change_desc.IsEmpty(): | 965 if change_desc.IsEmpty(): |
957 print "Description is empty; aborting." | 966 print "Description is empty; aborting." |
958 return 1 | 967 return 1 |
959 | 968 |
960 upload_args.extend(['--message', change_desc.subject]) | 969 upload_args.extend(['--message', change_desc.subject]) |
961 upload_args.extend(['--description', change_desc.description]) | 970 upload_args.extend(['--description', change_desc.description]) |
962 if change_desc.reviewers: | 971 if change_desc.reviewers: |
963 upload_args.extend(['--reviewers', change_desc.reviewers]) | 972 upload_args.extend(['--reviewers', change_desc.reviewers]) |
964 cc = ','.join(filter(None, (settings.GetCCList(), options.cc))) | 973 cc = ','.join(filter(None, (cl.GetCCList(), options.cc))) |
965 if cc: | 974 if cc: |
966 upload_args.extend(['--cc', cc]) | 975 upload_args.extend(['--cc', cc]) |
967 | 976 |
968 # Include the upstream repo's URL in the change -- this is useful for | 977 # Include the upstream repo's URL in the change -- this is useful for |
969 # projects that have their source spread across multiple repos. | 978 # projects that have their source spread across multiple repos. |
970 remote_url = None | 979 remote_url = None |
971 if settings.GetIsGitSvn(): | 980 if settings.GetIsGitSvn(): |
972 # URL is dependent on the current directory. | 981 # URL is dependent on the current directory. |
973 data = RunGit(['svn', 'info'], cwd=settings.GetRoot()) | 982 data = RunGit(['svn', 'info'], cwd=settings.GetRoot()) |
974 if data: | 983 if data: |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1424 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 1433 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
1425 | 1434 |
1426 # Not a known command. Default to help. | 1435 # Not a known command. Default to help. |
1427 GenUsage(parser, 'help') | 1436 GenUsage(parser, 'help') |
1428 return CMDhelp(parser, argv) | 1437 return CMDhelp(parser, argv) |
1429 | 1438 |
1430 | 1439 |
1431 if __name__ == '__main__': | 1440 if __name__ == '__main__': |
1432 fix_encoding.fix_encoding() | 1441 fix_encoding.fix_encoding() |
1433 sys.exit(main(sys.argv[1:])) | 1442 sys.exit(main(sys.argv[1:])) |
OLD | NEW |