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

Side by Side Diff: git_common.py

Issue 2075603002: Refactor git_common config and die (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Fix unintended change Created 4 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | git_map.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 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 # Monkeypatch IMapIterator so that Ctrl-C can kill everything properly. 5 # Monkeypatch IMapIterator so that Ctrl-C can kill everything properly.
6 # Derived from https://gist.github.com/aljungberg/626518 6 # Derived from https://gist.github.com/aljungberg/626518
7 import multiprocessing.pool 7 import multiprocessing.pool
8 from multiprocessing.pool import IMapIterator 8 from multiprocessing.pool import IMapIterator
9 def wrapper(func): 9 def wrapper(func):
10 def wrap(self, timeout=None): 10 def wrap(self, timeout=None):
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 how many times the decorated |function| is called.""" 274 how many times the decorated |function| is called."""
275 def _inner_gen(): 275 def _inner_gen():
276 yield function() 276 yield function()
277 while True: 277 while True:
278 yield 278 yield
279 return _inner_gen().next 279 return _inner_gen().next
280 280
281 281
282 ## Git functions 282 ## Git functions
283 283
284 def die(message, *args):
285 print >> sys.stderr, textwrap.dedent(message % args)
286 sys.exit(1)
287
284 288
285 def blame(filename, revision=None, porcelain=False, *_args): 289 def blame(filename, revision=None, porcelain=False, *_args):
286 command = ['blame'] 290 command = ['blame']
287 if porcelain: 291 if porcelain:
288 command.append('-p') 292 command.append('-p')
289 if revision is not None: 293 if revision is not None:
290 command.append(revision) 294 command.append(revision)
291 command.extend(['--', filename]) 295 command.extend(['--', filename])
292 return run(*command) 296 return run(*command)
293 297
294 298
295 def branch_config(branch, option, default=None): 299 def branch_config(branch, option, default=None):
296 return config('branch.%s.%s' % (branch, option), default=default) 300 return get_config('branch.%s.%s' % (branch, option), default=default)
297
298
299 def config_regexp(pattern):
300 if IS_WIN: # pragma: no cover
301 # this madness is because we call git.bat which calls git.exe which calls
302 # bash.exe (or something to that effect). Each layer divides the number of
303 # ^'s by 2.
304 pattern = pattern.replace('^', '^' * 8)
305 return run('config', '--get-regexp', pattern).splitlines()
306 301
307 302
308 def branch_config_map(option): 303 def branch_config_map(option):
309 """Return {branch: <|option| value>} for all branches.""" 304 """Return {branch: <|option| value>} for all branches."""
310 try: 305 try:
311 reg = re.compile(r'^branch\.(.*)\.%s$' % option) 306 reg = re.compile(r'^branch\.(.*)\.%s$' % option)
312 lines = config_regexp(reg.pattern) 307 lines = get_config_regexp(reg.pattern)
313 return {reg.match(k).group(1): v for k, v in (l.split() for l in lines)} 308 return {reg.match(k).group(1): v for k, v in (l.split() for l in lines)}
314 except subprocess2.CalledProcessError: 309 except subprocess2.CalledProcessError:
315 return {} 310 return {}
316 311
317 312
318 def branches(*args): 313 def branches(*args):
319 NO_BRANCH = ('* (no branch', '* (detached', '* (HEAD detached') 314 NO_BRANCH = ('* (no branch', '* (detached', '* (HEAD detached')
320 315
321 key = 'depot-tools.branch-limit' 316 key = 'depot-tools.branch-limit'
322 limit = 20 317 limit = get_config_int(key, 20)
323 try:
324 limit = int(config(key, limit))
325 except ValueError:
326 pass
327 318
328 raw_branches = run('branch', *args).splitlines() 319 raw_branches = run('branch', *args).splitlines()
329 320
330 num = len(raw_branches) 321 num = len(raw_branches)
322
331 if num > limit: 323 if num > limit:
332 print >> sys.stderr, textwrap.dedent("""\ 324 die("""\
333 Your git repo has too many branches (%d/%d) for this tool to work well. 325 Your git repo has too many branches (%d/%d) for this tool to work well.
334 326
335 You may adjust this limit by running: 327 You may adjust this limit by running:
336 git config %s <new_limit> 328 git config %s <new_limit>
337 """ % (num, limit, key)) 329
338 sys.exit(1) 330 You may also try cleaning up your old branches by running:
331 git cl archive
332 """, num, limit, key)
339 333
340 for line in raw_branches: 334 for line in raw_branches:
341 if line.startswith(NO_BRANCH): 335 if line.startswith(NO_BRANCH):
342 continue 336 continue
343 yield line.split()[-1] 337 yield line.split()[-1]
344 338
345 339
346 def config(option, default=None): 340 def get_config(option, default=None):
347 try: 341 try:
348 return run('config', '--get', option) or default 342 return run('config', '--get', option) or default
349 except subprocess2.CalledProcessError: 343 except subprocess2.CalledProcessError:
350 return default 344 return default
351 345
352 346
353 def config_list(option): 347 def get_config_int(option, default=0):
348 assert isinstance(default, int)
349 try:
350 return int(get_config(option, default))
351 except ValueError:
352 return default
353
354
355 def get_config_list(option):
354 try: 356 try:
355 return run('config', '--get-all', option).split() 357 return run('config', '--get-all', option).split()
356 except subprocess2.CalledProcessError: 358 except subprocess2.CalledProcessError:
357 return [] 359 return []
358 360
359 361
362 def get_config_regexp(pattern):
363 if IS_WIN: # pragma: no cover
364 # this madness is because we call git.bat which calls git.exe which calls
365 # bash.exe (or something to that effect). Each layer divides the number of
366 # ^'s by 2.
367 pattern = pattern.replace('^', '^' * 8)
368 return run('config', '--get-regexp', pattern).splitlines()
369
370
360 def current_branch(): 371 def current_branch():
361 try: 372 try:
362 return run('rev-parse', '--abbrev-ref', 'HEAD') 373 return run('rev-parse', '--abbrev-ref', 'HEAD')
363 except subprocess2.CalledProcessError: 374 except subprocess2.CalledProcessError:
364 return None 375 return None
365 376
366 377
367 def del_branch_config(branch, option, scope='local'): 378 def del_branch_config(branch, option, scope='local'):
368 del_config('branch.%s.%s' % (branch, option), scope=scope) 379 del_config('branch.%s.%s' % (branch, option), scope=scope)
369 380
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 del_branch_config(branch, 'base') 571 del_branch_config(branch, 'base')
561 del_branch_config(branch, 'base-upstream') 572 del_branch_config(branch, 'base-upstream')
562 573
563 574
564 def repo_root(): 575 def repo_root():
565 """Returns the absolute path to the repository root.""" 576 """Returns the absolute path to the repository root."""
566 return run('rev-parse', '--show-toplevel') 577 return run('rev-parse', '--show-toplevel')
567 578
568 579
569 def root(): 580 def root():
570 return config('depot-tools.upstream', 'origin/master') 581 return get_config('depot-tools.upstream', 'origin/master')
571 582
572 583
573 @contextlib.contextmanager 584 @contextlib.contextmanager
574 def less(): # pragma: no cover 585 def less(): # pragma: no cover
575 """Runs 'less' as context manager yielding its stdin as a PIPE. 586 """Runs 'less' as context manager yielding its stdin as a PIPE.
576 587
577 Automatically checks if sys.stdout is a non-TTY stream. If so, it avoids 588 Automatically checks if sys.stdout is a non-TTY stream. If so, it avoids
578 running less and just yields sys.stdout. 589 running less and just yields sys.stdout.
579 """ 590 """
580 if not setup_color.IS_TTY: 591 if not setup_color.IS_TTY:
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 ['HEAD']) 915 ['HEAD'])
905 916
906 917
907 def clone_file(repository, new_workdir, link, operation): 918 def clone_file(repository, new_workdir, link, operation):
908 if not os.path.exists(os.path.join(repository, link)): 919 if not os.path.exists(os.path.join(repository, link)):
909 return 920 return
910 link_dir = os.path.dirname(os.path.join(new_workdir, link)) 921 link_dir = os.path.dirname(os.path.join(new_workdir, link))
911 if not os.path.exists(link_dir): 922 if not os.path.exists(link_dir):
912 os.makedirs(link_dir) 923 os.makedirs(link_dir)
913 operation(os.path.join(repository, link), os.path.join(new_workdir, link)) 924 operation(os.path.join(repository, link), os.path.join(new_workdir, link))
OLDNEW
« no previous file with comments | « no previous file | git_map.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698