| OLD | NEW |
| 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 """Gclient-specific SCM-specific operations.""" | 5 """Gclient-specific SCM-specific operations.""" |
| 6 | 6 |
| 7 import collections | 7 import collections |
| 8 import logging | 8 import logging |
| 9 import os | 9 import os |
| 10 import posixpath | 10 import posixpath |
| 11 import re | 11 import re |
| 12 import sys | 12 import sys |
| 13 import tempfile | 13 import tempfile |
| 14 import threading | 14 import threading |
| 15 import time | |
| 16 import traceback | 15 import traceback |
| 17 import urlparse | 16 import urlparse |
| 18 | 17 |
| 19 import download_from_google_storage | 18 import download_from_google_storage |
| 20 import gclient_utils | 19 import gclient_utils |
| 21 import scm | 20 import scm |
| 22 import subprocess2 | 21 import subprocess2 |
| 23 | 22 |
| 24 | 23 |
| 25 THIS_FILE_PATH = os.path.abspath(__file__) | 24 THIS_FILE_PATH = os.path.abspath(__file__) |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 if not command in commands: | 135 if not command in commands: |
| 137 raise gclient_utils.Error('Unknown command %s' % command) | 136 raise gclient_utils.Error('Unknown command %s' % command) |
| 138 | 137 |
| 139 if not command in dir(self): | 138 if not command in dir(self): |
| 140 raise gclient_utils.Error('Command %s not implemented in %s wrapper' % ( | 139 raise gclient_utils.Error('Command %s not implemented in %s wrapper' % ( |
| 141 command, self.__class__.__name__)) | 140 command, self.__class__.__name__)) |
| 142 | 141 |
| 143 return getattr(self, command)(options, args, file_list) | 142 return getattr(self, command)(options, args, file_list) |
| 144 | 143 |
| 145 | 144 |
| 146 class GitFilter(object): | |
| 147 """A filter_fn implementation for quieting down git output messages. | |
| 148 | |
| 149 Allows a custom function to skip certain lines (predicate), and will throttle | |
| 150 the output of percentage completed lines to only output every X seconds. | |
| 151 """ | |
| 152 PERCENT_RE = re.compile('.* ([0-9]{1,2})% .*') | |
| 153 | |
| 154 def __init__(self, time_throttle=0, predicate=None): | |
| 155 """ | |
| 156 Args: | |
| 157 time_throttle (int): GitFilter will throttle 'noisy' output (such as the | |
| 158 XX% complete messages) to only be printed at least |time_throttle| | |
| 159 seconds apart. | |
| 160 predicate (f(line)): An optional function which is invoked for every line. | |
| 161 The line will be skipped if predicate(line) returns False. | |
| 162 """ | |
| 163 self.last_time = 0 | |
| 164 self.time_throttle = time_throttle | |
| 165 self.predicate = predicate | |
| 166 | |
| 167 def __call__(self, line): | |
| 168 # git uses an escape sequence to clear the line; elide it. | |
| 169 esc = line.find(unichr(033)) | |
| 170 if esc > -1: | |
| 171 line = line[:esc] | |
| 172 if self.predicate and not self.predicate(line): | |
| 173 return | |
| 174 now = time.time() | |
| 175 match = self.PERCENT_RE.match(line) | |
| 176 if not match: | |
| 177 self.last_time = 0 | |
| 178 if (now - self.last_time) >= self.time_throttle: | |
| 179 self.last_time = now | |
| 180 print line | |
| 181 | |
| 182 | |
| 183 class GitWrapper(SCMWrapper): | 145 class GitWrapper(SCMWrapper): |
| 184 """Wrapper for Git""" | 146 """Wrapper for Git""" |
| 185 name = 'git' | 147 name = 'git' |
| 186 remote = 'origin' | 148 remote = 'origin' |
| 187 | 149 |
| 188 cache_dir = None | 150 cache_dir = None |
| 189 # If a given cache is used in a solution more than once, prevent multiple | 151 # If a given cache is used in a solution more than once, prevent multiple |
| 190 # threads from updating it simultaneously. | 152 # threads from updating it simultaneously. |
| 191 cache_locks = collections.defaultdict(threading.Lock) | 153 cache_locks = collections.defaultdict(threading.Lock) |
| 192 | 154 |
| (...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 if fetch: | 1019 if fetch: |
| 1058 fetch_cmd = ['-c', 'core.deltaBaseCacheLimit=2g', 'fetch', self.remote] | 1020 fetch_cmd = ['-c', 'core.deltaBaseCacheLimit=2g', 'fetch', self.remote] |
| 1059 if options.verbose: | 1021 if options.verbose: |
| 1060 fetch_cmd.append('--verbose') | 1022 fetch_cmd.append('--verbose') |
| 1061 self._Run(fetch_cmd, options, retry=True) | 1023 self._Run(fetch_cmd, options, retry=True) |
| 1062 | 1024 |
| 1063 def _Run(self, args, options, **kwargs): | 1025 def _Run(self, args, options, **kwargs): |
| 1064 kwargs.setdefault('cwd', self.checkout_path) | 1026 kwargs.setdefault('cwd', self.checkout_path) |
| 1065 git_filter = not options.verbose | 1027 git_filter = not options.verbose |
| 1066 if git_filter: | 1028 if git_filter: |
| 1067 kwargs['filter_fn'] = GitFilter(kwargs.get('filter_fn')) | 1029 kwargs['filter_fn'] = gclient_utils.GitFilter(kwargs.get('filter_fn')) |
| 1068 kwargs.setdefault('print_stdout', False) | 1030 kwargs.setdefault('print_stdout', False) |
| 1069 # Don't prompt for passwords; just fail quickly and noisily. | 1031 # Don't prompt for passwords; just fail quickly and noisily. |
| 1070 # By default, git will use an interactive terminal prompt when a username/ | 1032 # By default, git will use an interactive terminal prompt when a username/ |
| 1071 # password is needed. That shouldn't happen in the chromium workflow, | 1033 # password is needed. That shouldn't happen in the chromium workflow, |
| 1072 # and if it does, then gclient may hide the prompt in the midst of a flood | 1034 # and if it does, then gclient may hide the prompt in the midst of a flood |
| 1073 # of terminal spew. The only indication that something has gone wrong | 1035 # of terminal spew. The only indication that something has gone wrong |
| 1074 # will be when gclient hangs unresponsively. Instead, we disable the | 1036 # will be when gclient hangs unresponsively. Instead, we disable the |
| 1075 # password prompt and simply allow git to fail noisily. The error | 1037 # password prompt and simply allow git to fail noisily. The error |
| 1076 # message produced by git will be copied to gclient's output. | 1038 # message produced by git will be copied to gclient's output. |
| 1077 env = kwargs.get('env') or kwargs.setdefault('env', os.environ.copy()) | 1039 env = kwargs.get('env') or kwargs.setdefault('env', os.environ.copy()) |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1544 new_command.append('--force') | 1506 new_command.append('--force') |
| 1545 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1507 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1546 new_command.extend(('--accept', 'theirs-conflict')) | 1508 new_command.extend(('--accept', 'theirs-conflict')) |
| 1547 elif options.manually_grab_svn_rev: | 1509 elif options.manually_grab_svn_rev: |
| 1548 new_command.append('--force') | 1510 new_command.append('--force') |
| 1549 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1511 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1550 new_command.extend(('--accept', 'postpone')) | 1512 new_command.extend(('--accept', 'postpone')) |
| 1551 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1513 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1552 new_command.extend(('--accept', 'postpone')) | 1514 new_command.extend(('--accept', 'postpone')) |
| 1553 return new_command | 1515 return new_command |
| OLD | NEW |