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

Side by Side Diff: gclient_utils.py

Issue 227163002: Revamped terminal output for update. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Fix tests Created 6 years, 8 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 | « gclient_scm.py ('k') | tests/gclient_scm_test.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 (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 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 """Generic utils.""" 5 """Generic utils."""
6 6
7 import codecs 7 import codecs
8 import cStringIO 8 import cStringIO
9 import datetime
9 import logging 10 import logging
10 import os 11 import os
11 import pipes 12 import pipes
12 import platform 13 import platform
13 import Queue 14 import Queue
14 import re 15 import re
15 import stat 16 import stat
16 import subprocess 17 import subprocess
17 import sys 18 import sys
18 import tempfile 19 import tempfile
19 import threading 20 import threading
20 import time 21 import time
21 import urlparse 22 import urlparse
22 23
23 import subprocess2 24 import subprocess2
24 25
25 26
26 RETRY_MAX = 3 27 RETRY_MAX = 3
27 RETRY_INITIAL_SLEEP = 0.5 28 RETRY_INITIAL_SLEEP = 0.5
29 START = datetime.datetime.now()
28 30
29 31
30 _WARNINGS = [] 32 _WARNINGS = []
31 33
32 34
33 # These repos are known to cause OOM errors on 32-bit platforms, due the the 35 # These repos are known to cause OOM errors on 32-bit platforms, due the the
34 # very large objects they contain. It is not safe to use threaded index-pack 36 # very large objects they contain. It is not safe to use threaded index-pack
35 # when cloning/fetching them. 37 # when cloning/fetching them.
36 THREADED_INDEX_PACK_BLACKLIST = [ 38 THREADED_INDEX_PACK_BLACKLIST = [
37 'https://chromium.googlesource.com/chromium/reference_builds/chrome_win.git' 39 'https://chromium.googlesource.com/chromium/reference_builds/chrome_win.git'
38 ] 40 ]
39 41
40 42
41 class Error(Exception): 43 class Error(Exception):
42 """gclient exception class.""" 44 """gclient exception class."""
43 def __init__(self, msg, *args, **kwargs): 45 def __init__(self, msg, *args, **kwargs):
44 index = getattr(threading.currentThread(), 'index', 0) 46 index = getattr(threading.currentThread(), 'index', 0)
45 if index: 47 if index:
46 msg = '\n'.join('%d> %s' % (index, l) for l in msg.splitlines()) 48 msg = '\n'.join('%d> %s' % (index, l) for l in msg.splitlines())
47 super(Error, self).__init__(msg, *args, **kwargs) 49 super(Error, self).__init__(msg, *args, **kwargs)
48 50
49 51
52 def Elapsed(until=None):
53 if until is None:
54 until = datetime.datetime.now()
55 return str(until - START).partition('.')[0]
56
57
50 def PrintWarnings(): 58 def PrintWarnings():
51 """Prints any accumulated warnings.""" 59 """Prints any accumulated warnings."""
52 if _WARNINGS: 60 if _WARNINGS:
53 print >> sys.stderr, '\n\nWarnings:' 61 print >> sys.stderr, '\n\nWarnings:'
54 for warning in _WARNINGS: 62 for warning in _WARNINGS:
55 print >> sys.stderr, warning 63 print >> sys.stderr, warning
56 64
57 65
58 def AddWarning(msg): 66 def AddWarning(msg):
59 """Adds the given warning message to the list of accumulated warnings.""" 67 """Adds the given warning message to the list of accumulated warnings."""
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 try: 484 try:
477 in_byte = kid.stdout.read(1) 485 in_byte = kid.stdout.read(1)
478 if in_byte: 486 if in_byte:
479 if call_filter_on_first_line: 487 if call_filter_on_first_line:
480 filter_fn(None) 488 filter_fn(None)
481 in_line = '' 489 in_line = ''
482 while in_byte: 490 while in_byte:
483 output.write(in_byte) 491 output.write(in_byte)
484 if print_stdout: 492 if print_stdout:
485 stdout.write(in_byte) 493 stdout.write(in_byte)
486 if in_byte != '\r': 494 if in_byte not in ['\r', '\n']:
487 if in_byte != '\n': 495 in_line += in_byte
488 in_line += in_byte
489 else:
490 filter_fn(in_line)
491 in_line = ''
492 else: 496 else:
493 filter_fn(in_line) 497 filter_fn(in_line)
494 in_line = '' 498 in_line = ''
495 in_byte = kid.stdout.read(1) 499 in_byte = kid.stdout.read(1)
496 # Flush the rest of buffered output. This is only an issue with 500 # Flush the rest of buffered output. This is only an issue with
497 # stdout/stderr not ending with a \n. 501 # stdout/stderr not ending with a \n.
498 if len(in_line): 502 if len(in_line):
499 filter_fn(in_line) 503 filter_fn(in_line)
500 rv = kid.wait() 504 rv = kid.wait()
501 505
(...skipping 16 matching lines...) Expand all
518 raise subprocess2.CalledProcessError( 522 raise subprocess2.CalledProcessError(
519 rv, args, kwargs.get('cwd', None), None, None) 523 rv, args, kwargs.get('cwd', None), None, None)
520 524
521 525
522 class GitFilter(object): 526 class GitFilter(object):
523 """A filter_fn implementation for quieting down git output messages. 527 """A filter_fn implementation for quieting down git output messages.
524 528
525 Allows a custom function to skip certain lines (predicate), and will throttle 529 Allows a custom function to skip certain lines (predicate), and will throttle
526 the output of percentage completed lines to only output every X seconds. 530 the output of percentage completed lines to only output every X seconds.
527 """ 531 """
528 PERCENT_RE = re.compile('.* ([0-9]{1,2})% .*') 532 PERCENT_RE = re.compile('(.*) ([0-9]{1,3})% .*')
529 533
530 def __init__(self, time_throttle=0, predicate=None): 534 def __init__(self, time_throttle=0, predicate=None, out_fh=None):
531 """ 535 """
532 Args: 536 Args:
533 time_throttle (int): GitFilter will throttle 'noisy' output (such as the 537 time_throttle (int): GitFilter will throttle 'noisy' output (such as the
534 XX% complete messages) to only be printed at least |time_throttle| 538 XX% complete messages) to only be printed at least |time_throttle|
535 seconds apart. 539 seconds apart.
536 predicate (f(line)): An optional function which is invoked for every line. 540 predicate (f(line)): An optional function which is invoked for every line.
537 The line will be skipped if predicate(line) returns False. 541 The line will be skipped if predicate(line) returns False.
542 out_fh: File handle to write output to.
538 """ 543 """
539 self.last_time = 0 544 self.last_time = 0
540 self.time_throttle = time_throttle 545 self.time_throttle = time_throttle
541 self.predicate = predicate 546 self.predicate = predicate
547 self.out_fh = out_fh or sys.stdout
548 self.progress_prefix = None
542 549
543 def __call__(self, line): 550 def __call__(self, line):
544 # git uses an escape sequence to clear the line; elide it. 551 # git uses an escape sequence to clear the line; elide it.
545 esc = line.find(unichr(033)) 552 esc = line.find(unichr(033))
546 if esc > -1: 553 if esc > -1:
547 line = line[:esc] 554 line = line[:esc]
548 if self.predicate and not self.predicate(line): 555 if self.predicate and not self.predicate(line):
549 return 556 return
550 now = time.time() 557 now = time.time()
551 match = self.PERCENT_RE.match(line) 558 match = self.PERCENT_RE.match(line)
552 if not match: 559 if match:
553 self.last_time = 0 560 if match.group(1) != self.progress_prefix:
554 if (now - self.last_time) >= self.time_throttle: 561 self.progress_prefix = match.group(1)
555 self.last_time = now 562 elif now - self.last_time < self.time_throttle:
556 print line 563 return
564 self.last_time = now
565 self.out_fh.write('[%s] ' % Elapsed())
566 print >> self.out_fh, line
557 567
558 568
559 def FindGclientRoot(from_dir, filename='.gclient'): 569 def FindGclientRoot(from_dir, filename='.gclient'):
560 """Tries to find the gclient root.""" 570 """Tries to find the gclient root."""
561 real_from_dir = os.path.realpath(from_dir) 571 real_from_dir = os.path.realpath(from_dir)
562 path = real_from_dir 572 path = real_from_dir
563 while not os.path.exists(os.path.join(path, filename)): 573 while not os.path.exists(os.path.join(path, filename)):
564 split_path = os.path.split(path) 574 split_path = os.path.split(path)
565 if not split_path[1]: 575 if not split_path[1]:
566 return None 576 return None
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 class WorkItem(object): 686 class WorkItem(object):
677 """One work item.""" 687 """One work item."""
678 # On cygwin, creating a lock throwing randomly when nearing ~100 locks. 688 # On cygwin, creating a lock throwing randomly when nearing ~100 locks.
679 # As a workaround, use a single lock. Yep you read it right. Single lock for 689 # As a workaround, use a single lock. Yep you read it right. Single lock for
680 # all the 100 objects. 690 # all the 100 objects.
681 lock = threading.Lock() 691 lock = threading.Lock()
682 692
683 def __init__(self, name): 693 def __init__(self, name):
684 # A unique string representing this work item. 694 # A unique string representing this work item.
685 self._name = name 695 self._name = name
696 self.outbuf = cStringIO.StringIO()
686 697
687 def run(self, work_queue): 698 def run(self, work_queue):
688 """work_queue is passed as keyword argument so it should be 699 """work_queue is passed as keyword argument so it should be
689 the last parameters of the function when you override it.""" 700 the last parameters of the function when you override it."""
690 pass 701 pass
691 702
692 @property 703 @property
693 def name(self): 704 def name(self):
694 return self._name 705 return self._name
695 706
696 707
697 class ExecutionQueue(object): 708 class ExecutionQueue(object):
698 """Runs a set of WorkItem that have interdependencies and were WorkItem are 709 """Runs a set of WorkItem that have interdependencies and were WorkItem are
699 added as they are processed. 710 added as they are processed.
700 711
701 In gclient's case, Dependencies sometime needs to be run out of order due to 712 In gclient's case, Dependencies sometime needs to be run out of order due to
702 From() keyword. This class manages that all the required dependencies are run 713 From() keyword. This class manages that all the required dependencies are run
703 before running each one. 714 before running each one.
704 715
705 Methods of this class are thread safe. 716 Methods of this class are thread safe.
706 """ 717 """
707 def __init__(self, jobs, progress, ignore_requirements): 718 def __init__(self, jobs, progress, ignore_requirements, verbose=False):
708 """jobs specifies the number of concurrent tasks to allow. progress is a 719 """jobs specifies the number of concurrent tasks to allow. progress is a
709 Progress instance.""" 720 Progress instance."""
710 # Set when a thread is done or a new item is enqueued. 721 # Set when a thread is done or a new item is enqueued.
711 self.ready_cond = threading.Condition() 722 self.ready_cond = threading.Condition()
712 # Maximum number of concurrent tasks. 723 # Maximum number of concurrent tasks.
713 self.jobs = jobs 724 self.jobs = jobs
714 # List of WorkItem, for gclient, these are Dependency instances. 725 # List of WorkItem, for gclient, these are Dependency instances.
715 self.queued = [] 726 self.queued = []
716 # List of strings representing each Dependency.name that was run. 727 # List of strings representing each Dependency.name that was run.
717 self.ran = [] 728 self.ran = []
718 # List of items currently running. 729 # List of items currently running.
719 self.running = [] 730 self.running = []
720 # Exceptions thrown if any. 731 # Exceptions thrown if any.
721 self.exceptions = Queue.Queue() 732 self.exceptions = Queue.Queue()
722 # Progress status 733 # Progress status
723 self.progress = progress 734 self.progress = progress
724 if self.progress: 735 if self.progress:
725 self.progress.update(0) 736 self.progress.update(0)
726 737
727 self.ignore_requirements = ignore_requirements 738 self.ignore_requirements = ignore_requirements
739 self.verbose = verbose
740 self.last_join = None
741 self.last_subproc_output = None
728 742
729 def enqueue(self, d): 743 def enqueue(self, d):
730 """Enqueue one Dependency to be executed later once its requirements are 744 """Enqueue one Dependency to be executed later once its requirements are
731 satisfied. 745 satisfied.
732 """ 746 """
733 assert isinstance(d, WorkItem) 747 assert isinstance(d, WorkItem)
734 self.ready_cond.acquire() 748 self.ready_cond.acquire()
735 try: 749 try:
736 self.queued.append(d) 750 self.queued.append(d)
737 total = len(self.queued) + len(self.ran) + len(self.running) 751 total = len(self.queued) + len(self.ran) + len(self.running)
738 logging.debug('enqueued(%s)' % d.name) 752 logging.debug('enqueued(%s)' % d.name)
739 if self.progress: 753 if self.progress:
740 self.progress._total = total + 1 754 self.progress._total = total + 1
741 self.progress.update(0) 755 self.progress.update(0)
742 self.ready_cond.notifyAll() 756 self.ready_cond.notifyAll()
743 finally: 757 finally:
744 self.ready_cond.release() 758 self.ready_cond.release()
745 759
760 def out_cb(self, _):
Ryan Tseng 2014/04/07 20:56:38 What does "cb" stand for?
szager1 2014/04/08 20:41:14 CallBack
761 self.last_subproc_output = datetime.datetime.now()
762 return True
763
764 @staticmethod
765 def format_task_output(task, comment=''):
766 if comment:
767 comment = ' (%s)' % comment
768 return """
769 %s%s
770 ----------------------------------------
771 %s
772 ---------------------------------------- """ % (
773 task.name, comment, task.outbuf.getvalue())
Ryan Tseng 2014/04/07 20:56:38 trim task.outbuf.getvalue(), there seems to be an
szager1 2014/04/08 20:41:14 Done.
774
746 def flush(self, *args, **kwargs): 775 def flush(self, *args, **kwargs):
747 """Runs all enqueued items until all are executed.""" 776 """Runs all enqueued items until all are executed."""
748 kwargs['work_queue'] = self 777 kwargs['work_queue'] = self
778 self.last_subproc_output = self.last_join = datetime.datetime.now()
749 self.ready_cond.acquire() 779 self.ready_cond.acquire()
750 try: 780 try:
751 while True: 781 while True:
752 # Check for task to run first, then wait. 782 # Check for task to run first, then wait.
753 while True: 783 while True:
754 if not self.exceptions.empty(): 784 if not self.exceptions.empty():
755 # Systematically flush the queue when an exception logged. 785 # Systematically flush the queue when an exception logged.
756 self.queued = [] 786 self.queued = []
757 self._flush_terminated_threads() 787 self._flush_terminated_threads()
758 if (not self.queued and not self.running or 788 if (not self.queued and not self.running or
(...skipping 12 matching lines...) Expand all
771 else: 801 else:
772 # Couldn't find an item that could run. Break out the outher loop. 802 # Couldn't find an item that could run. Break out the outher loop.
773 break 803 break
774 804
775 if not self.queued and not self.running: 805 if not self.queued and not self.running:
776 # We're done. 806 # We're done.
777 break 807 break
778 # We need to poll here otherwise Ctrl-C isn't processed. 808 # We need to poll here otherwise Ctrl-C isn't processed.
779 try: 809 try:
780 self.ready_cond.wait(10) 810 self.ready_cond.wait(10)
811 # If we haven't printed to terminal for a while, but we have received
812 # spew from a suprocess, let the user know we're still progressing.
813 now = datetime.datetime.now()
Ryan Tseng 2014/04/07 20:56:38 nit: time.time()? To match timekeeping style earli
szager1 2014/04/08 20:41:14 Nice thing about datetime is the elegant arithmeti
814 if (now - self.last_join > datetime.timedelta(seconds=60) and
815 self.last_subproc_output > self.last_join):
816 if self.progress:
817 print >> sys.stdout, ''
818 print >> sys.stdout, '[%s] Still working...' % Elapsed()
Ryan Tseng 2014/04/07 20:56:38 Not always clear what process is causing this to p
szager1 2014/04/08 20:41:14 Done.
781 except KeyboardInterrupt: 819 except KeyboardInterrupt:
782 # Help debugging by printing some information: 820 # Help debugging by printing some information:
783 print >> sys.stderr, ( 821 print >> sys.stderr, (
784 ('\nAllowed parallel jobs: %d\n# queued: %d\nRan: %s\n' 822 ('\nAllowed parallel jobs: %d\n# queued: %d\nRan: %s\n'
785 'Running: %d') % ( 823 'Running: %d') % (
786 self.jobs, 824 self.jobs,
787 len(self.queued), 825 len(self.queued),
788 ', '.join(self.ran), 826 ', '.join(self.ran),
789 len(self.running))) 827 len(self.running)))
790 for i in self.queued: 828 for i in self.queued:
791 print >> sys.stderr, '%s: %s' % (i.name, ', '.join(i.requirements)) 829 print >> sys.stderr, '%s (not started): %s' % (
830 i.name, ', '.join(i.requirements))
831 for i in self.running:
832 print >> sys.stderr, self.format_task_output(i.item, 'interrupted')
792 raise 833 raise
793 # Something happened: self.enqueue() or a thread terminated. Loop again. 834 # Something happened: self.enqueue() or a thread terminated. Loop again.
794 finally: 835 finally:
795 self.ready_cond.release() 836 self.ready_cond.release()
796 837
797 assert not self.running, 'Now guaranteed to be single-threaded' 838 assert not self.running, 'Now guaranteed to be single-threaded'
798 if not self.exceptions.empty(): 839 if not self.exceptions.empty():
840 if self.progress:
841 sys.stdout.write('\n')
Ryan Tseng 2014/04/07 20:56:38 nit: print >> sys.stdout, '', to match print style
szager1 2014/04/08 20:41:14 Done.
799 # To get back the stack location correctly, the raise a, b, c form must be 842 # To get back the stack location correctly, the raise a, b, c form must be
800 # used, passing a tuple as the first argument doesn't work. 843 # used, passing a tuple as the first argument doesn't work.
801 e = self.exceptions.get() 844 e, task = self.exceptions.get()
845 print >> sys.stderr, self.format_task_output(task.item, 'ERROR')
802 raise e[0], e[1], e[2] 846 raise e[0], e[1], e[2]
803 if self.progress: 847 elif self.progress:
804 self.progress.end() 848 self.progress.end()
805 849
806 def _flush_terminated_threads(self): 850 def _flush_terminated_threads(self):
807 """Flush threads that have terminated.""" 851 """Flush threads that have terminated."""
808 running = self.running 852 running = self.running
809 self.running = [] 853 self.running = []
810 for t in running: 854 for t in running:
811 if t.isAlive(): 855 if t.isAlive():
812 self.running.append(t) 856 self.running.append(t)
813 else: 857 else:
814 t.join() 858 t.join()
859 self.last_join = datetime.datetime.now()
815 sys.stdout.flush() 860 sys.stdout.flush()
861 if self.verbose:
862 print >> sys.stdout, self.format_task_output(t.item)
Ryan Tseng 2014/04/07 20:56:38 I think it'd be useful to also print the # of minu
szager1 2014/04/08 20:41:14 Done.
816 if self.progress: 863 if self.progress:
817 self.progress.update(1, t.item.name) 864 self.progress.update(1, t.item.name)
818 if t.item.name in self.ran: 865 if t.item.name in self.ran:
819 raise Error( 866 raise Error(
820 'gclient is confused, "%s" is already in "%s"' % ( 867 'gclient is confused, "%s" is already in "%s"' % (
821 t.item.name, ', '.join(self.ran))) 868 t.item.name, ', '.join(self.ran)))
822 if not t.item.name in self.ran: 869 if not t.item.name in self.ran:
823 self.ran.append(t.item.name) 870 self.ran.append(t.item.name)
824 871
825 def _run_one_task(self, task_item, args, kwargs): 872 def _run_one_task(self, task_item, args, kwargs):
826 if self.jobs > 1: 873 if self.jobs > 1:
827 # Start the thread. 874 # Start the thread.
828 index = len(self.ran) + len(self.running) + 1 875 index = len(self.ran) + len(self.running) + 1
829 new_thread = self._Worker(task_item, index, args, kwargs) 876 new_thread = self._Worker(task_item, index, args, kwargs)
830 self.running.append(new_thread) 877 self.running.append(new_thread)
831 new_thread.start() 878 new_thread.start()
832 else: 879 else:
833 # Run the 'thread' inside the main thread. Don't try to catch any 880 # Run the 'thread' inside the main thread. Don't try to catch any
834 # exception. 881 # exception.
835 task_item.run(*args, **kwargs) 882 try:
836 self.ran.append(task_item.name) 883 task_item.run(*args, **kwargs)
837 if self.progress: 884 self.ran.append(task_item.name)
838 self.progress.update(1, ', '.join(t.item.name for t in self.running)) 885 if self.verbose:
886 if self.progress:
887 print >> sys.stdout, ''
888 print >> sys.stdout, self.format_task_output(task_item)
889 if self.progress:
890 self.progress.update(1, ', '.join(t.item.name for t in self.running))
891 except KeyboardInterrupt:
892 print >> sys.stderr, self.format_task_output(task_item, 'interrupted')
893 raise
894 except Exception:
895 print >> sys.stderr, self.format_task_output(task_item, 'ERROR')
896 raise
897
839 898
840 class _Worker(threading.Thread): 899 class _Worker(threading.Thread):
841 """One thread to execute one WorkItem.""" 900 """One thread to execute one WorkItem."""
842 def __init__(self, item, index, args, kwargs): 901 def __init__(self, item, index, args, kwargs):
843 threading.Thread.__init__(self, name=item.name or 'Worker') 902 threading.Thread.__init__(self, name=item.name or 'Worker')
844 logging.info('_Worker(%s) reqs:%s' % (item.name, item.requirements)) 903 logging.info('_Worker(%s) reqs:%s' % (item.name, item.requirements))
845 self.item = item 904 self.item = item
846 self.index = index 905 self.index = index
847 self.args = args 906 self.args = args
848 self.kwargs = kwargs 907 self.kwargs = kwargs
849 self.daemon = True 908 self.daemon = True
850 909
851 def run(self): 910 def run(self):
852 """Runs in its own thread.""" 911 """Runs in its own thread."""
853 logging.debug('_Worker.run(%s)' % self.item.name) 912 logging.debug('_Worker.run(%s)' % self.item.name)
854 work_queue = self.kwargs['work_queue'] 913 work_queue = self.kwargs['work_queue']
855 try: 914 try:
856 self.item.run(*self.args, **self.kwargs) 915 self.item.run(*self.args, **self.kwargs)
857 except KeyboardInterrupt: 916 except KeyboardInterrupt:
858 logging.info('Caught KeyboardInterrupt in thread %s', self.item.name) 917 logging.info('Caught KeyboardInterrupt in thread %s', self.item.name)
859 logging.info(str(sys.exc_info())) 918 logging.info(str(sys.exc_info()))
860 work_queue.exceptions.put(sys.exc_info()) 919 work_queue.exceptions.put((sys.exc_info(), self))
861 raise 920 raise
862 except Exception: 921 except Exception:
863 # Catch exception location. 922 # Catch exception location.
864 logging.info('Caught exception in thread %s', self.item.name) 923 logging.info('Caught exception in thread %s', self.item.name)
865 logging.info(str(sys.exc_info())) 924 logging.info(str(sys.exc_info()))
866 work_queue.exceptions.put(sys.exc_info()) 925 work_queue.exceptions.put((sys.exc_info(), self))
867 finally: 926 finally:
868 logging.info('_Worker.run(%s) done', self.item.name) 927 logging.info('_Worker.run(%s) done', self.item.name)
869 work_queue.ready_cond.acquire() 928 work_queue.ready_cond.acquire()
870 try: 929 try:
871 work_queue.ready_cond.notifyAll() 930 work_queue.ready_cond.notifyAll()
872 finally: 931 finally:
873 work_queue.ready_cond.release() 932 work_queue.ready_cond.release()
874 933
875 934
876 def GetEditor(git, git_editor=None): 935 def GetEditor(git, git_editor=None):
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 def DefaultIndexPackConfig(url=''): 1060 def DefaultIndexPackConfig(url=''):
1002 """Return reasonable default values for configuring git-index-pack. 1061 """Return reasonable default values for configuring git-index-pack.
1003 1062
1004 Experiments suggest that higher values for pack.threads don't improve 1063 Experiments suggest that higher values for pack.threads don't improve
1005 performance.""" 1064 performance."""
1006 cache_limit = DefaultDeltaBaseCacheLimit() 1065 cache_limit = DefaultDeltaBaseCacheLimit()
1007 result = ['-c', 'core.deltaBaseCacheLimit=%s' % cache_limit] 1066 result = ['-c', 'core.deltaBaseCacheLimit=%s' % cache_limit]
1008 if url in THREADED_INDEX_PACK_BLACKLIST: 1067 if url in THREADED_INDEX_PACK_BLACKLIST:
1009 result.extend(['-c', 'pack.threads=1']) 1068 result.extend(['-c', 'pack.threads=1'])
1010 return result 1069 return result
OLDNEW
« no previous file with comments | « gclient_scm.py ('k') | tests/gclient_scm_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698