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 |