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

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: rebase 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()
697 self.start = self.finish = None
686 698
687 def run(self, work_queue): 699 def run(self, work_queue):
688 """work_queue is passed as keyword argument so it should be 700 """work_queue is passed as keyword argument so it should be
689 the last parameters of the function when you override it.""" 701 the last parameters of the function when you override it."""
690 pass 702 pass
691 703
692 @property 704 @property
693 def name(self): 705 def name(self):
694 return self._name 706 return self._name
695 707
696 708
697 class ExecutionQueue(object): 709 class ExecutionQueue(object):
698 """Runs a set of WorkItem that have interdependencies and were WorkItem are 710 """Runs a set of WorkItem that have interdependencies and were WorkItem are
699 added as they are processed. 711 added as they are processed.
700 712
701 In gclient's case, Dependencies sometime needs to be run out of order due to 713 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 714 From() keyword. This class manages that all the required dependencies are run
703 before running each one. 715 before running each one.
704 716
705 Methods of this class are thread safe. 717 Methods of this class are thread safe.
706 """ 718 """
707 def __init__(self, jobs, progress, ignore_requirements): 719 def __init__(self, jobs, progress, ignore_requirements, verbose=False):
708 """jobs specifies the number of concurrent tasks to allow. progress is a 720 """jobs specifies the number of concurrent tasks to allow. progress is a
709 Progress instance.""" 721 Progress instance."""
710 # Set when a thread is done or a new item is enqueued. 722 # Set when a thread is done or a new item is enqueued.
711 self.ready_cond = threading.Condition() 723 self.ready_cond = threading.Condition()
712 # Maximum number of concurrent tasks. 724 # Maximum number of concurrent tasks.
713 self.jobs = jobs 725 self.jobs = jobs
714 # List of WorkItem, for gclient, these are Dependency instances. 726 # List of WorkItem, for gclient, these are Dependency instances.
715 self.queued = [] 727 self.queued = []
716 # List of strings representing each Dependency.name that was run. 728 # List of strings representing each Dependency.name that was run.
717 self.ran = [] 729 self.ran = []
718 # List of items currently running. 730 # List of items currently running.
719 self.running = [] 731 self.running = []
720 # Exceptions thrown if any. 732 # Exceptions thrown if any.
721 self.exceptions = Queue.Queue() 733 self.exceptions = Queue.Queue()
722 # Progress status 734 # Progress status
723 self.progress = progress 735 self.progress = progress
724 if self.progress: 736 if self.progress:
725 self.progress.update(0) 737 self.progress.update(0)
726 738
727 self.ignore_requirements = ignore_requirements 739 self.ignore_requirements = ignore_requirements
740 self.verbose = verbose
741 self.last_join = None
742 self.last_subproc_output = None
728 743
729 def enqueue(self, d): 744 def enqueue(self, d):
730 """Enqueue one Dependency to be executed later once its requirements are 745 """Enqueue one Dependency to be executed later once its requirements are
731 satisfied. 746 satisfied.
732 """ 747 """
733 assert isinstance(d, WorkItem) 748 assert isinstance(d, WorkItem)
734 self.ready_cond.acquire() 749 self.ready_cond.acquire()
735 try: 750 try:
736 self.queued.append(d) 751 self.queued.append(d)
737 total = len(self.queued) + len(self.ran) + len(self.running) 752 total = len(self.queued) + len(self.ran) + len(self.running)
738 logging.debug('enqueued(%s)' % d.name) 753 logging.debug('enqueued(%s)' % d.name)
739 if self.progress: 754 if self.progress:
740 self.progress._total = total + 1 755 self.progress._total = total + 1
741 self.progress.update(0) 756 self.progress.update(0)
742 self.ready_cond.notifyAll() 757 self.ready_cond.notifyAll()
743 finally: 758 finally:
744 self.ready_cond.release() 759 self.ready_cond.release()
745 760
761 def out_cb(self, _):
762 self.last_subproc_output = datetime.datetime.now()
763 return True
764
765 @staticmethod
766 def format_task_output(task, comment=''):
767 if comment:
768 comment = ' (%s)' % comment
769 if task.start and task.finish:
770 elapsed = ' (Elapsed: %s)' % (
771 str(task.finish - task.start).partition('.')[0])
772 else:
773 elapsed = ''
774 return """
775 %s%s%s
776 ----------------------------------------
777 %s
778 ----------------------------------------""" % (
779 task.name, comment, task.outbuf.getvalue().strip(), elapsed)
780
746 def flush(self, *args, **kwargs): 781 def flush(self, *args, **kwargs):
747 """Runs all enqueued items until all are executed.""" 782 """Runs all enqueued items until all are executed."""
748 kwargs['work_queue'] = self 783 kwargs['work_queue'] = self
784 self.last_subproc_output = self.last_join = datetime.datetime.now()
749 self.ready_cond.acquire() 785 self.ready_cond.acquire()
750 try: 786 try:
751 while True: 787 while True:
752 # Check for task to run first, then wait. 788 # Check for task to run first, then wait.
753 while True: 789 while True:
754 if not self.exceptions.empty(): 790 if not self.exceptions.empty():
755 # Systematically flush the queue when an exception logged. 791 # Systematically flush the queue when an exception logged.
756 self.queued = [] 792 self.queued = []
757 self._flush_terminated_threads() 793 self._flush_terminated_threads()
758 if (not self.queued and not self.running or 794 if (not self.queued and not self.running or
(...skipping 12 matching lines...) Expand all
771 else: 807 else:
772 # Couldn't find an item that could run. Break out the outher loop. 808 # Couldn't find an item that could run. Break out the outher loop.
773 break 809 break
774 810
775 if not self.queued and not self.running: 811 if not self.queued and not self.running:
776 # We're done. 812 # We're done.
777 break 813 break
778 # We need to poll here otherwise Ctrl-C isn't processed. 814 # We need to poll here otherwise Ctrl-C isn't processed.
779 try: 815 try:
780 self.ready_cond.wait(10) 816 self.ready_cond.wait(10)
817 # If we haven't printed to terminal for a while, but we have received
818 # spew from a suprocess, let the user know we're still progressing.
819 now = datetime.datetime.now()
820 if (now - self.last_join > datetime.timedelta(seconds=60) and
821 self.last_subproc_output > self.last_join):
822 if self.progress:
823 print >> sys.stdout, ''
824 elapsed = Elapsed()
825 print >> sys.stdout, '[%s] Still working on:' % elapsed
826 for task in self.running:
827 print >> sys.stdout, '[%s] %s' % (elapsed, task.item.name)
781 except KeyboardInterrupt: 828 except KeyboardInterrupt:
782 # Help debugging by printing some information: 829 # Help debugging by printing some information:
783 print >> sys.stderr, ( 830 print >> sys.stderr, (
784 ('\nAllowed parallel jobs: %d\n# queued: %d\nRan: %s\n' 831 ('\nAllowed parallel jobs: %d\n# queued: %d\nRan: %s\n'
785 'Running: %d') % ( 832 'Running: %d') % (
786 self.jobs, 833 self.jobs,
787 len(self.queued), 834 len(self.queued),
788 ', '.join(self.ran), 835 ', '.join(self.ran),
789 len(self.running))) 836 len(self.running)))
790 for i in self.queued: 837 for i in self.queued:
791 print >> sys.stderr, '%s: %s' % (i.name, ', '.join(i.requirements)) 838 print >> sys.stderr, '%s (not started): %s' % (
839 i.name, ', '.join(i.requirements))
840 for i in self.running:
841 print >> sys.stderr, self.format_task_output(i.item, 'interrupted')
792 raise 842 raise
793 # Something happened: self.enqueue() or a thread terminated. Loop again. 843 # Something happened: self.enqueue() or a thread terminated. Loop again.
794 finally: 844 finally:
795 self.ready_cond.release() 845 self.ready_cond.release()
796 846
797 assert not self.running, 'Now guaranteed to be single-threaded' 847 assert not self.running, 'Now guaranteed to be single-threaded'
798 if not self.exceptions.empty(): 848 if not self.exceptions.empty():
849 if self.progress:
850 print >> sys.stdout, ''
799 # To get back the stack location correctly, the raise a, b, c form must be 851 # 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. 852 # used, passing a tuple as the first argument doesn't work.
801 e = self.exceptions.get() 853 e, task = self.exceptions.get()
854 print >> sys.stderr, self.format_task_output(task.item, 'ERROR')
802 raise e[0], e[1], e[2] 855 raise e[0], e[1], e[2]
803 if self.progress: 856 elif self.progress:
804 self.progress.end() 857 self.progress.end()
805 858
806 def _flush_terminated_threads(self): 859 def _flush_terminated_threads(self):
807 """Flush threads that have terminated.""" 860 """Flush threads that have terminated."""
808 running = self.running 861 running = self.running
809 self.running = [] 862 self.running = []
810 for t in running: 863 for t in running:
811 if t.isAlive(): 864 if t.isAlive():
812 self.running.append(t) 865 self.running.append(t)
813 else: 866 else:
814 t.join() 867 t.join()
868 self.last_join = datetime.datetime.now()
815 sys.stdout.flush() 869 sys.stdout.flush()
870 if self.verbose:
871 print >> sys.stdout, self.format_task_output(t.item)
816 if self.progress: 872 if self.progress:
817 self.progress.update(1, t.item.name) 873 self.progress.update(1, t.item.name)
818 if t.item.name in self.ran: 874 if t.item.name in self.ran:
819 raise Error( 875 raise Error(
820 'gclient is confused, "%s" is already in "%s"' % ( 876 'gclient is confused, "%s" is already in "%s"' % (
821 t.item.name, ', '.join(self.ran))) 877 t.item.name, ', '.join(self.ran)))
822 if not t.item.name in self.ran: 878 if not t.item.name in self.ran:
823 self.ran.append(t.item.name) 879 self.ran.append(t.item.name)
824 880
825 def _run_one_task(self, task_item, args, kwargs): 881 def _run_one_task(self, task_item, args, kwargs):
826 if self.jobs > 1: 882 if self.jobs > 1:
827 # Start the thread. 883 # Start the thread.
828 index = len(self.ran) + len(self.running) + 1 884 index = len(self.ran) + len(self.running) + 1
829 new_thread = self._Worker(task_item, index, args, kwargs) 885 new_thread = self._Worker(task_item, index, args, kwargs)
830 self.running.append(new_thread) 886 self.running.append(new_thread)
831 new_thread.start() 887 new_thread.start()
832 else: 888 else:
833 # Run the 'thread' inside the main thread. Don't try to catch any 889 # Run the 'thread' inside the main thread. Don't try to catch any
834 # exception. 890 # exception.
835 task_item.run(*args, **kwargs) 891 try:
836 self.ran.append(task_item.name) 892 task_item.start = datetime.datetime.now()
837 if self.progress: 893 print >> task_item.outbuf, '[%s] Started.' % Elapsed(task_item.start)
838 self.progress.update(1, ', '.join(t.item.name for t in self.running)) 894 task_item.run(*args, **kwargs)
895 task_item.finish = datetime.datetime.now()
896 print >> task_item.outbuf, '[%s] Finished.' % Elapsed(task_item.finish)
897 self.ran.append(task_item.name)
898 if self.verbose:
899 if self.progress:
900 print >> sys.stdout, ''
901 print >> sys.stdout, self.format_task_output(task_item)
902 if self.progress:
903 self.progress.update(1, ', '.join(t.item.name for t in self.running))
904 except KeyboardInterrupt:
905 print >> sys.stderr, self.format_task_output(task_item, 'interrupted')
906 raise
907 except Exception:
908 print >> sys.stderr, self.format_task_output(task_item, 'ERROR')
909 raise
910
839 911
840 class _Worker(threading.Thread): 912 class _Worker(threading.Thread):
841 """One thread to execute one WorkItem.""" 913 """One thread to execute one WorkItem."""
842 def __init__(self, item, index, args, kwargs): 914 def __init__(self, item, index, args, kwargs):
843 threading.Thread.__init__(self, name=item.name or 'Worker') 915 threading.Thread.__init__(self, name=item.name or 'Worker')
844 logging.info('_Worker(%s) reqs:%s' % (item.name, item.requirements)) 916 logging.info('_Worker(%s) reqs:%s' % (item.name, item.requirements))
845 self.item = item 917 self.item = item
846 self.index = index 918 self.index = index
847 self.args = args 919 self.args = args
848 self.kwargs = kwargs 920 self.kwargs = kwargs
849 self.daemon = True 921 self.daemon = True
850 922
851 def run(self): 923 def run(self):
852 """Runs in its own thread.""" 924 """Runs in its own thread."""
853 logging.debug('_Worker.run(%s)' % self.item.name) 925 logging.debug('_Worker.run(%s)' % self.item.name)
854 work_queue = self.kwargs['work_queue'] 926 work_queue = self.kwargs['work_queue']
855 try: 927 try:
928 self.item.start = datetime.datetime.now()
929 print >> self.item.outbuf, '[%s] Started.' % Elapsed(self.item.start)
856 self.item.run(*self.args, **self.kwargs) 930 self.item.run(*self.args, **self.kwargs)
931 self.item.finish = datetime.datetime.now()
932 print >> self.item.outbuf, '[%s] Finished.' % Elapsed(self.item.finish)
857 except KeyboardInterrupt: 933 except KeyboardInterrupt:
858 logging.info('Caught KeyboardInterrupt in thread %s', self.item.name) 934 logging.info('Caught KeyboardInterrupt in thread %s', self.item.name)
859 logging.info(str(sys.exc_info())) 935 logging.info(str(sys.exc_info()))
860 work_queue.exceptions.put(sys.exc_info()) 936 work_queue.exceptions.put((sys.exc_info(), self))
861 raise 937 raise
862 except Exception: 938 except Exception:
863 # Catch exception location. 939 # Catch exception location.
864 logging.info('Caught exception in thread %s', self.item.name) 940 logging.info('Caught exception in thread %s', self.item.name)
865 logging.info(str(sys.exc_info())) 941 logging.info(str(sys.exc_info()))
866 work_queue.exceptions.put(sys.exc_info()) 942 work_queue.exceptions.put((sys.exc_info(), self))
867 finally: 943 finally:
868 logging.info('_Worker.run(%s) done', self.item.name) 944 logging.info('_Worker.run(%s) done', self.item.name)
869 work_queue.ready_cond.acquire() 945 work_queue.ready_cond.acquire()
870 try: 946 try:
871 work_queue.ready_cond.notifyAll() 947 work_queue.ready_cond.notifyAll()
872 finally: 948 finally:
873 work_queue.ready_cond.release() 949 work_queue.ready_cond.release()
874 950
875 951
876 def GetEditor(git, git_editor=None): 952 def GetEditor(git, git_editor=None):
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 def DefaultIndexPackConfig(url=''): 1077 def DefaultIndexPackConfig(url=''):
1002 """Return reasonable default values for configuring git-index-pack. 1078 """Return reasonable default values for configuring git-index-pack.
1003 1079
1004 Experiments suggest that higher values for pack.threads don't improve 1080 Experiments suggest that higher values for pack.threads don't improve
1005 performance.""" 1081 performance."""
1006 cache_limit = DefaultDeltaBaseCacheLimit() 1082 cache_limit = DefaultDeltaBaseCacheLimit()
1007 result = ['-c', 'core.deltaBaseCacheLimit=%s' % cache_limit] 1083 result = ['-c', 'core.deltaBaseCacheLimit=%s' % cache_limit]
1008 if url in THREADED_INDEX_PACK_BLACKLIST: 1084 if url in THREADED_INDEX_PACK_BLACKLIST:
1009 result.extend(['-c', 'pack.threads=1']) 1085 result.extend(['-c', 'pack.threads=1'])
1010 return result 1086 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