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

Side by Side Diff: git_cl.py

Issue 938583002: Make git-map-branches -vvv show CL status colors. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: address_comments Created 5 years, 9 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 | git_map_branches.py » ('j') | 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.""" 8 """A git-command for integrating reviews on Rietveld."""
9 9
10 from distutils.version import LooseVersion 10 from distutils.version import LooseVersion
11 import base64 11 import base64
12 import glob 12 import glob
13 import json 13 import json
14 import logging 14 import logging
15 import multiprocessing
15 import optparse 16 import optparse
16 import os 17 import os
17 import Queue 18 import Queue
18 import re 19 import re
19 import stat 20 import stat
20 import sys 21 import sys
21 import tempfile 22 import tempfile
22 import textwrap 23 import textwrap
23 import threading
24 import urllib2 24 import urllib2
25 import urlparse 25 import urlparse
26 import webbrowser 26 import webbrowser
27 import zlib 27 import zlib
28 28
29 try: 29 try:
30 import readline # pylint: disable=F0401,W0611 30 import readline # pylint: disable=F0401,W0611
31 except ImportError: 31 except ImportError:
32 pass 32 pass
33 33
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 return { 1331 return {
1332 'unsent': Fore.RED, 1332 'unsent': Fore.RED,
1333 'waiting': Fore.BLUE, 1333 'waiting': Fore.BLUE,
1334 'reply': Fore.YELLOW, 1334 'reply': Fore.YELLOW,
1335 'lgtm': Fore.GREEN, 1335 'lgtm': Fore.GREEN,
1336 'commit': Fore.MAGENTA, 1336 'commit': Fore.MAGENTA,
1337 'closed': Fore.CYAN, 1337 'closed': Fore.CYAN,
1338 'error': Fore.WHITE, 1338 'error': Fore.WHITE,
1339 }.get(status, Fore.WHITE) 1339 }.get(status, Fore.WHITE)
1340 1340
1341 def fetch_cl_status(b):
1342 """Fetches information for an issue and returns (branch, issue, color)."""
1343 c = Changelist(branchref=b)
1344 i = c.GetIssueURL()
1345 status = c.GetStatus()
1346 color = color_for_status(status)
1347
1348 if i and (not status or status == 'error'):
1349 # The issue probably doesn't exist anymore.
1350 i += ' (broken)'
1351
1352 return (b, i, color)
1353
1354 def get_cl_statuses(branches, fine_grained, max_processes=None):
1355 """Returns a blocking iterable of (branch, issue, color) for given branches.
1356
1357 If fine_grained is true, this will fetch CL statuses from the server.
1358 Otherwise, simply indicate if there's a matching url for the given branches.
1359
1360 If max_processes is specified, it is used as the maximum number of processes
1361 to spawn to fetch CL status from the server. Otherwise 1 process per branch is
1362 spawned.
1363 """
1364 # Silence upload.py otherwise it becomes unwieldly.
1365 upload.verbosity = 0
1366
1367 if fine_grained:
1368 # Process one branch synchronously to work through authentication, then
1369 # spawn processes to process all the other branches in parallel.
1370 if branches:
1371 yield fetch_cl_status(branches[0])
1372
1373 branches_to_fetch = branches[1:]
1374 pool = multiprocessing.Pool(
1375 min(max_processes, len(branches_to_fetch))
1376 if max_processes is not None
1377 else len(branches_to_fetch))
1378 for x in pool.imap_unordered(fetch_cl_status, branches_to_fetch):
1379 yield x
1380 else:
1381 # Do not use GetApprovingReviewers(), since it requires an HTTP request.
1382 for b in branches:
1383 c = Changelist(branchref=b)
1384 url = c.GetIssueURL()
1385 yield (b, url, Fore.BLUE if url else Fore.WHITE)
1341 1386
1342 def CMDstatus(parser, args): 1387 def CMDstatus(parser, args):
1343 """Show status of changelists. 1388 """Show status of changelists.
1344 1389
1345 Colors are used to tell the state of the CL unless --fast is used: 1390 Colors are used to tell the state of the CL unless --fast is used:
1346 - Red not sent for review or broken 1391 - Red not sent for review or broken
1347 - Blue waiting for review 1392 - Blue waiting for review
1348 - Yellow waiting for you to reply to review 1393 - Yellow waiting for you to reply to review
1349 - Green LGTM'ed 1394 - Green LGTM'ed
1350 - Magenta in the commit queue 1395 - Magenta in the commit queue
1351 - Cyan was committed, branch can be deleted 1396 - Cyan was committed, branch can be deleted
1352 1397
1353 Also see 'git cl comments'. 1398 Also see 'git cl comments'.
1354 """ 1399 """
1355 parser.add_option('--field', 1400 parser.add_option('--field',
1356 help='print only specific field (desc|id|patch|url)') 1401 help='print only specific field (desc|id|patch|url)')
1357 parser.add_option('-f', '--fast', action='store_true', 1402 parser.add_option('-f', '--fast', action='store_true',
1358 help='Do not retrieve review status') 1403 help='Do not retrieve review status')
1404 parser.add_option(
1405 '-j', '--maxjobs', action='store', type=int,
1406 help='The maximum number of jobs to use when retrieving review status')
1359 (options, args) = parser.parse_args(args) 1407 (options, args) = parser.parse_args(args)
1360 if args: 1408 if args:
1361 parser.error('Unsupported args: %s' % args) 1409 parser.error('Unsupported args: %s' % args)
1362 1410
1363 if options.field: 1411 if options.field:
1364 cl = Changelist() 1412 cl = Changelist()
1365 if options.field.startswith('desc'): 1413 if options.field.startswith('desc'):
1366 print cl.GetDescription() 1414 print cl.GetDescription()
1367 elif options.field == 'id': 1415 elif options.field == 'id':
1368 issueid = cl.GetIssue() 1416 issueid = cl.GetIssue()
(...skipping 11 matching lines...) Expand all
1380 1428
1381 branches = RunGit(['for-each-ref', '--format=%(refname)', 'refs/heads']) 1429 branches = RunGit(['for-each-ref', '--format=%(refname)', 'refs/heads'])
1382 if not branches: 1430 if not branches:
1383 print('No local branch found.') 1431 print('No local branch found.')
1384 return 0 1432 return 0
1385 1433
1386 changes = (Changelist(branchref=b) for b in branches.splitlines()) 1434 changes = (Changelist(branchref=b) for b in branches.splitlines())
1387 branches = [c.GetBranch() for c in changes] 1435 branches = [c.GetBranch() for c in changes]
1388 alignment = max(5, max(len(b) for b in branches)) 1436 alignment = max(5, max(len(b) for b in branches))
1389 print 'Branches associated with reviews:' 1437 print 'Branches associated with reviews:'
1390 # Adhoc thread pool to request data concurrently. 1438 output = get_cl_statuses(branches,
1391 output = Queue.Queue() 1439 fine_grained=not options.fast,
1392 1440 max_processes=options.maxjobs)
1393 # Silence upload.py otherwise it becomes unweldly.
1394 upload.verbosity = 0
1395
1396 if not options.fast:
1397 def fetch(b):
1398 """Fetches information for an issue and returns (branch, issue, color)."""
1399 c = Changelist(branchref=b)
1400 i = c.GetIssueURL()
1401 status = c.GetStatus()
1402 color = color_for_status(status)
1403
1404 if i and (not status or status == 'error'):
1405 # The issue probably doesn't exist anymore.
1406 i += ' (broken)'
1407
1408 output.put((b, i, color))
1409
1410 # Process one branch synchronously to work through authentication, then
1411 # spawn threads to process all the other branches in parallel.
1412 if branches:
1413 fetch(branches[0])
1414 threads = [
1415 threading.Thread(target=fetch, args=(b,)) for b in branches[1:]]
1416 for t in threads:
1417 t.daemon = True
1418 t.start()
1419 else:
1420 # Do not use GetApprovingReviewers(), since it requires an HTTP request.
1421 for b in branches:
1422 c = Changelist(branchref=b)
1423 url = c.GetIssueURL()
1424 output.put((b, url, Fore.BLUE if url else Fore.WHITE))
1425 1441
1426 tmp = {} 1442 tmp = {}
iannucci 2015/03/11 20:18:46 can we rename this to e.g. branch_status or someth
calamity 2015/03/11 22:28:27 Done.
1427 alignment = max(5, max(len(ShortBranchName(b)) for b in branches)) 1443 alignment = max(5, max(len(ShortBranchName(b)) for b in branches))
1428 for branch in sorted(branches): 1444 for branch in sorted(branches):
1429 while branch not in tmp: 1445 while branch not in tmp:
1430 b, i, color = output.get() 1446 b, i, color = output.next()
1431 tmp[b] = (i, color) 1447 tmp[b] = (i, color)
1432 issue, color = tmp.pop(branch) 1448 issue, color = tmp.pop(branch)
1433 reset = Fore.RESET 1449 reset = Fore.RESET
1434 if not sys.stdout.isatty(): 1450 if not sys.stdout.isatty():
1435 color = '' 1451 color = ''
1436 reset = '' 1452 reset = ''
1437 print ' %*s : %s%s%s' % ( 1453 print ' %*s : %s%s%s' % (
1438 alignment, ShortBranchName(branch), color, issue, reset) 1454 alignment, ShortBranchName(branch), color, issue, reset)
1439 1455
1440 cl = Changelist() 1456 cl = Changelist()
(...skipping 1653 matching lines...) Expand 10 before | Expand all | Expand 10 after
3094 if __name__ == '__main__': 3110 if __name__ == '__main__':
3095 # These affect sys.stdout so do it outside of main() to simplify mocks in 3111 # These affect sys.stdout so do it outside of main() to simplify mocks in
3096 # unit testing. 3112 # unit testing.
3097 fix_encoding.fix_encoding() 3113 fix_encoding.fix_encoding()
3098 colorama.init() 3114 colorama.init()
3099 try: 3115 try:
3100 sys.exit(main(sys.argv[1:])) 3116 sys.exit(main(sys.argv[1:]))
3101 except KeyboardInterrupt: 3117 except KeyboardInterrupt:
3102 sys.stderr.write('interrupted\n') 3118 sys.stderr.write('interrupted\n')
3103 sys.exit(1) 3119 sys.exit(1)
OLDNEW
« no previous file with comments | « no previous file | git_map_branches.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698