Chromium Code Reviews| 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 """Generic utils.""" | 5 """Generic utils.""" |
| 6 | 6 |
| 7 import codecs | 7 import codecs |
| 8 import errno | 8 import errno |
| 9 import logging | 9 import logging |
| 10 import os | 10 import os |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 os.makedirs(tree) | 185 os.makedirs(tree) |
| 186 except OSError, e: | 186 except OSError, e: |
| 187 # 17 POSIX, 183 Windows | 187 # 17 POSIX, 183 Windows |
| 188 if e.errno not in (17, 183): | 188 if e.errno not in (17, 183): |
| 189 raise | 189 raise |
| 190 if count > 40: | 190 if count > 40: |
| 191 # Give up. | 191 # Give up. |
| 192 raise | 192 raise |
| 193 | 193 |
| 194 | 194 |
| 195 def CheckCallAndFilterAndHeader(args, always=False, **kwargs): | 195 def CheckCallAndFilterAndHeader(args, always=False, header=None, **kwargs): |
| 196 """Adds 'header' support to CheckCallAndFilter. | 196 """Adds 'header' support to CheckCallAndFilter. |
| 197 | 197 |
| 198 If |always| is True, a message indicating what is being done | 198 If |always| is True, a message indicating what is being done |
| 199 is printed to stdout all the time even if not output is generated. Otherwise | 199 is printed to stdout all the time even if not output is generated. Otherwise |
| 200 the message header is printed only if the call generated any ouput. | 200 the message header is printed only if the call generated any ouput. |
| 201 """ | 201 """ |
| 202 stdout = kwargs.get('stdout', None) or sys.stdout | 202 stdout = kwargs.setdefault('stdout', sys.stdout) |
| 203 if header is None: | |
| 204 header = "\n________ running '%s' in '%s'\n" % ( | |
| 205 ' '.join(args), kwargs.get('cwd', '.')) | |
| 206 | |
| 203 if always: | 207 if always: |
| 204 stdout.write('\n________ running \'%s\' in \'%s\'\n' | 208 stdout.write(header) |
| 205 % (' '.join(args), kwargs.get('cwd', '.'))) | |
| 206 else: | 209 else: |
| 207 filter_fn = kwargs.get('filter_fn', None) | 210 filter_fn = kwargs.get('filter_fn') |
| 208 def filter_msg(line): | 211 def filter_msg(line): |
| 209 if line is None: | 212 if line is None: |
| 210 stdout.write('\n________ running \'%s\' in \'%s\'\n' | 213 stdout.write(header) |
| 211 % (' '.join(args), kwargs.get('cwd', '.'))) | |
| 212 elif filter_fn: | 214 elif filter_fn: |
| 213 filter_fn(line) | 215 filter_fn(line) |
| 214 kwargs['filter_fn'] = filter_msg | 216 kwargs['filter_fn'] = filter_msg |
| 215 kwargs['call_filter_on_first_line'] = True | 217 kwargs['call_filter_on_first_line'] = True |
| 216 # Obviously. | 218 # Obviously. |
| 217 kwargs['print_stdout'] = True | 219 kwargs.setdefault('print_stdout', True) |
| 218 return CheckCallAndFilter(args, **kwargs) | 220 return CheckCallAndFilter(args, **kwargs) |
| 219 | 221 |
| 220 | 222 |
| 221 class Wrapper(object): | 223 class Wrapper(object): |
| 222 """Wraps an object, acting as a transparent proxy for all properties by | 224 """Wraps an object, acting as a transparent proxy for all properties by |
| 223 default. | 225 default. |
| 224 """ | 226 """ |
| 225 def __init__(self, wrapped): | 227 def __init__(self, wrapped): |
| 226 self._wrapped = wrapped | 228 self._wrapped = wrapped |
| 227 | 229 |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 443 return None | 445 return None |
| 444 # If the root does not have a trailing \ or /, we add it so the returned | 446 # If the root does not have a trailing \ or /, we add it so the returned |
| 445 # path starts immediately after the seperator regardless of whether it is | 447 # path starts immediately after the seperator regardless of whether it is |
| 446 # provided. | 448 # provided. |
| 447 root = os.path.join(root, '') | 449 root = os.path.join(root, '') |
| 448 return subpath[len(root):] | 450 return subpath[len(root):] |
| 449 | 451 |
| 450 | 452 |
| 451 def FindFileUpwards(filename, path=None): | 453 def FindFileUpwards(filename, path=None): |
| 452 """Search upwards from the a directory (default: current) to find a file. | 454 """Search upwards from the a directory (default: current) to find a file. |
| 453 | 455 |
| 454 Returns nearest upper-level directory with the passed in file. | 456 Returns nearest upper-level directory with the passed in file. |
| 455 """ | 457 """ |
| 456 if not path: | 458 if not path: |
| 457 path = os.getcwd() | 459 path = os.getcwd() |
| 458 path = os.path.realpath(path) | 460 path = os.path.realpath(path) |
| 459 while True: | 461 while True: |
| 460 file_path = os.path.join(path, filename) | 462 file_path = os.path.join(path, filename) |
| 461 if os.path.exists(file_path): | 463 if os.path.exists(file_path): |
| 462 return path | 464 return path |
| 463 (new_path, _) = os.path.split(path) | 465 (new_path, _) = os.path.split(path) |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 self.queued = [] | 578 self.queued = [] |
| 577 self._flush_terminated_threads() | 579 self._flush_terminated_threads() |
| 578 if (not self.queued and not self.running or | 580 if (not self.queued and not self.running or |
| 579 self.jobs == len(self.running)): | 581 self.jobs == len(self.running)): |
| 580 logging.debug('No more worker threads or can\'t queue anything.') | 582 logging.debug('No more worker threads or can\'t queue anything.') |
| 581 break | 583 break |
| 582 | 584 |
| 583 # Check for new tasks to start. | 585 # Check for new tasks to start. |
| 584 for i in xrange(len(self.queued)): | 586 for i in xrange(len(self.queued)): |
| 585 # Verify its requirements. | 587 # Verify its requirements. |
| 586 for r in self.queued[i].requirements: | 588 if (not (set(self.queued[i].requirements) - set(self.ran)) or |
| 587 if not r in self.ran: | 589 kwargs.get('ignore_requirements')): |
|
M-A Ruel
2012/11/08 19:44:13
I prefer this to be in the state itself, e.g. in t
Isaac (away)
2012/11/09 03:58:52
Seems reasonable. Fixed.
| |
| 588 # Requirement not met. | |
| 589 break | |
| 590 else: | |
| 591 # Start one work item: all its requirements are satisfied. | 590 # Start one work item: all its requirements are satisfied. |
| 592 self._run_one_task(self.queued.pop(i), args, kwargs) | 591 self._run_one_task(self.queued.pop(i), args, kwargs) |
| 593 break | 592 break |
| 594 else: | 593 else: |
| 595 # Couldn't find an item that could run. Break out the outher loop. | 594 # Couldn't find an item that could run. Break out the outher loop. |
| 596 break | 595 break |
| 597 | 596 |
| 598 if not self.queued and not self.running: | 597 if not self.queued and not self.running: |
| 599 # We're done. | 598 # We're done. |
| 600 break | 599 break |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 776 | 775 |
| 777 Python on OSX 10.6 raises a NotImplementedError exception. | 776 Python on OSX 10.6 raises a NotImplementedError exception. |
| 778 """ | 777 """ |
| 779 try: | 778 try: |
| 780 import multiprocessing | 779 import multiprocessing |
| 781 return multiprocessing.cpu_count() | 780 return multiprocessing.cpu_count() |
| 782 except: # pylint: disable=W0702 | 781 except: # pylint: disable=W0702 |
| 783 # Mac OS 10.6 only | 782 # Mac OS 10.6 only |
| 784 # pylint: disable=E1101 | 783 # pylint: disable=E1101 |
| 785 return int(os.sysconf('SC_NPROCESSORS_ONLN')) | 784 return int(os.sysconf('SC_NPROCESSORS_ONLN')) |
| OLD | NEW |