Chromium Code Reviews| 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 821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 832 return presubmit_support.GitChange( | 832 return presubmit_support.GitChange( |
| 833 name, | 833 name, |
| 834 description, | 834 description, |
| 835 absroot, | 835 absroot, |
| 836 files, | 836 files, |
| 837 issue, | 837 issue, |
| 838 patchset, | 838 patchset, |
| 839 author, | 839 author, |
| 840 upstream=upstream_branch) | 840 upstream=upstream_branch) |
| 841 | 841 |
| 842 def GetStatus(self): | |
| 843 """Apply a rough heuristic to give a simple summary of an issue's review | |
| 844 or CQ status, assuming adherence to a common workflow. | |
| 845 | |
| 846 Returns None if no issue for this branch, or one of the following keywords: | |
| 847 * 'error' - error from review tool (including deleted issues) | |
| 848 * 'unsent' - not sent for review | |
| 849 * 'waiting' - waiting for review | |
| 850 * 'reply' - waiting for owner to reply to review | |
| 851 * 'lgtm' - LGTM from at least one approved reviewer | |
| 852 * 'commit' - in the commit queue | |
| 853 * 'closed' - closed | |
| 854 """ | |
| 855 if not self.GetIssue(): | |
| 856 return None | |
| 857 | |
| 858 try: | |
| 859 props = self.GetIssueProperties() | |
| 860 except urllib2.HTTPError: | |
| 861 return 'error' | |
| 862 | |
| 863 if props.get('closed'): | |
| 864 # Issue is closed. | |
| 865 return 'closed' | |
| 866 if props.get('commit'): | |
| 867 # Issue is in the commit queue. | |
| 868 return 'commit' | |
| 869 | |
| 870 try: | |
| 871 reviewers = self.GetApprovingReviewers() | |
| 872 except urllib2.HTTPError: | |
| 873 return 'error' | |
| 874 | |
| 875 if reviewers: | |
| 876 # Was LGTM'ed. | |
| 877 return 'lgtm' | |
| 878 | |
| 879 messages = props.get('messages') or [] | |
| 880 | |
| 881 if not messages: | |
| 882 # No message was sent. | |
| 883 return 'unsent' | |
| 884 if messages[-1]['sender'] != props.get('owner_email'): | |
| 885 # Non-LGTM reply from non-owner | |
| 886 return 'reply' | |
| 887 return 'waiting' | |
| 888 | |
| 842 def RunHook(self, committing, may_prompt, verbose, change): | 889 def RunHook(self, committing, may_prompt, verbose, change): |
| 843 """Calls sys.exit() if the hook fails; returns a HookResults otherwise.""" | 890 """Calls sys.exit() if the hook fails; returns a HookResults otherwise.""" |
| 844 | 891 |
| 845 try: | 892 try: |
| 846 return presubmit_support.DoPresubmitChecks(change, committing, | 893 return presubmit_support.DoPresubmitChecks(change, committing, |
| 847 verbose=verbose, output_stream=sys.stdout, input_stream=sys.stdin, | 894 verbose=verbose, output_stream=sys.stdout, input_stream=sys.stdin, |
| 848 default_presubmit=None, may_prompt=may_prompt, | 895 default_presubmit=None, may_prompt=may_prompt, |
| 849 rietveld_obj=self.RpcServer()) | 896 rietveld_obj=self.RpcServer()) |
| 850 except presubmit_support.PresubmitFailure, e: | 897 except presubmit_support.PresubmitFailure, e: |
| 851 DieWithError( | 898 DieWithError( |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1211 if not args: | 1258 if not args: |
| 1212 print("Current base-url:") | 1259 print("Current base-url:") |
| 1213 return RunGit(['config', 'branch.%s.base-url' % branch], | 1260 return RunGit(['config', 'branch.%s.base-url' % branch], |
| 1214 error_ok=False).strip() | 1261 error_ok=False).strip() |
| 1215 else: | 1262 else: |
| 1216 print("Setting base-url to %s" % args[0]) | 1263 print("Setting base-url to %s" % args[0]) |
| 1217 return RunGit(['config', 'branch.%s.base-url' % branch, args[0]], | 1264 return RunGit(['config', 'branch.%s.base-url' % branch, args[0]], |
| 1218 error_ok=False).strip() | 1265 error_ok=False).strip() |
| 1219 | 1266 |
| 1220 | 1267 |
| 1268 def color_for_status(status): | |
| 1269 """Maps a Changelist status to color, for CMDstatus and other tools.""" | |
| 1270 if not status or status == 'error': | |
| 1271 return Fore.WHITE | |
| 1272 return { | |
| 1273 'unsent': Fore.RED, | |
| 1274 'waiting': Fore.BLUE, | |
| 1275 'reply': Fore.YELLOW, | |
| 1276 'lgtm': Fore.GREEN, | |
| 1277 'commit': Fore.MAGENTA, | |
| 1278 'closed': Fore.CYAN, | |
| 1279 }[status] | |
|
iannucci
2014/09/10 22:44:30
why not just put error in here and then just do
r
jsbell
2014/09/11 17:27:55
Done.
| |
| 1280 | |
| 1281 | |
| 1221 def CMDstatus(parser, args): | 1282 def CMDstatus(parser, args): |
| 1222 """Show status of changelists. | 1283 """Show status of changelists. |
| 1223 | 1284 |
| 1224 Colors are used to tell the state of the CL unless --fast is used: | 1285 Colors are used to tell the state of the CL unless --fast is used: |
| 1225 - Red not sent for review or broken | 1286 - Red not sent for review or broken |
| 1226 - Blue waiting for review | 1287 - Blue waiting for review |
| 1227 - Yellow waiting for you to reply to review | 1288 - Yellow waiting for you to reply to review |
| 1228 - Green LGTM'ed | 1289 - Green LGTM'ed |
| 1229 - Magenta in the commit queue | 1290 - Magenta in the commit queue |
| 1230 - Cyan was committed, branch can be deleted | 1291 - Cyan was committed, branch can be deleted |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1269 # Adhoc thread pool to request data concurrently. | 1330 # Adhoc thread pool to request data concurrently. |
| 1270 output = Queue.Queue() | 1331 output = Queue.Queue() |
| 1271 | 1332 |
| 1272 # Silence upload.py otherwise it becomes unweldly. | 1333 # Silence upload.py otherwise it becomes unweldly. |
| 1273 upload.verbosity = 0 | 1334 upload.verbosity = 0 |
| 1274 | 1335 |
| 1275 if not options.fast: | 1336 if not options.fast: |
| 1276 def fetch(b): | 1337 def fetch(b): |
| 1277 """Fetches information for an issue and returns (branch, issue, color).""" | 1338 """Fetches information for an issue and returns (branch, issue, color).""" |
| 1278 c = Changelist(branchref=b) | 1339 c = Changelist(branchref=b) |
| 1340 status = c.GetStatus() | |
| 1341 color = color_for_status(status) | |
| 1279 i = c.GetIssueURL() | 1342 i = c.GetIssueURL() |
| 1280 props = {} | |
| 1281 r = None | |
| 1282 if i: | |
| 1283 try: | |
| 1284 props = c.GetIssueProperties() | |
| 1285 r = c.GetApprovingReviewers() if i else None | |
| 1286 except urllib2.HTTPError: | |
| 1287 # The issue probably doesn't exist anymore. | |
| 1288 i += ' (broken)' | |
| 1289 | 1343 |
| 1290 msgs = props.get('messages') or [] | 1344 if not status or status == 'error': |
| 1345 # The issue probably doesn't exist anymore. | |
| 1346 i += ' (broken)' | |
| 1291 | 1347 |
| 1292 if not i: | |
| 1293 color = Fore.WHITE | |
| 1294 elif props.get('closed'): | |
| 1295 # Issue is closed. | |
| 1296 color = Fore.CYAN | |
| 1297 elif props.get('commit'): | |
| 1298 # Issue is in the commit queue. | |
| 1299 color = Fore.MAGENTA | |
| 1300 elif r: | |
| 1301 # Was LGTM'ed. | |
| 1302 color = Fore.GREEN | |
| 1303 elif not msgs: | |
| 1304 # No message was sent. | |
| 1305 color = Fore.RED | |
| 1306 elif msgs[-1]['sender'] != props.get('owner_email'): | |
| 1307 color = Fore.YELLOW | |
| 1308 else: | |
| 1309 color = Fore.BLUE | |
| 1310 output.put((b, i, color)) | 1348 output.put((b, i, color)) |
| 1311 | 1349 |
| 1312 # Process one branch synchronously to work through authentication, then | 1350 # Process one branch synchronously to work through authentication, then |
| 1313 # spawn threads to process all the other branches in parallel. | 1351 # spawn threads to process all the other branches in parallel. |
| 1314 if branches: | 1352 if branches: |
| 1315 fetch(branches[0]) | 1353 fetch(branches[0]) |
| 1316 threads = [ | 1354 threads = [ |
| 1317 threading.Thread(target=fetch, args=(b,)) for b in branches[1:]] | 1355 threading.Thread(target=fetch, args=(b,)) for b in branches[1:]] |
| 1318 for t in threads: | 1356 for t in threads: |
| 1319 t.daemon = True | 1357 t.daemon = True |
| (...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2837 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' | 2875 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' |
| 2838 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 2876 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
| 2839 | 2877 |
| 2840 | 2878 |
| 2841 if __name__ == '__main__': | 2879 if __name__ == '__main__': |
| 2842 # These affect sys.stdout so do it outside of main() to simplify mocks in | 2880 # These affect sys.stdout so do it outside of main() to simplify mocks in |
| 2843 # unit testing. | 2881 # unit testing. |
| 2844 fix_encoding.fix_encoding() | 2882 fix_encoding.fix_encoding() |
| 2845 colorama.init() | 2883 colorama.init() |
| 2846 sys.exit(main(sys.argv[1:])) | 2884 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |