| OLD | NEW |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 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 import functools | 5 import functools |
| 5 import os | 6 import os |
| 6 | 7 |
| 7 | 8 |
| 8 SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__)) | 9 SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__)) |
| 9 BUILD_ROOT = os.path.dirname(os.path.dirname(SCRIPT_PATH)) | 10 BUILD_ROOT = os.path.dirname(os.path.dirname(SCRIPT_PATH)) |
| 10 ROOT_PATH = os.path.abspath(os.path.join( | 11 ROOT_PATH = os.path.abspath(os.path.join( |
| 11 SCRIPT_PATH, os.pardir, os.pardir, os.pardir)) | 12 SCRIPT_PATH, os.pardir, os.pardir, os.pardir)) |
| 12 BASE_DIRS = [ | 13 BASE_DIRS = [ |
| 13 SCRIPT_PATH, | 14 SCRIPT_PATH, |
| 14 os.path.join(ROOT_PATH, 'build_internal', 'scripts', 'slave'), | 15 os.path.join(ROOT_PATH, 'build_internal', 'scripts', 'slave'), |
| 15 os.path.join(ROOT_PATH, 'build_internal', 'scripts', 'slave-internal') | 16 os.path.join(ROOT_PATH, 'build_internal', 'scripts', 'slave-internal') |
| 16 ] | 17 ] |
| 17 MODULE_DIRS = lambda: [os.path.join(x, 'recipe_modules') for x in BASE_DIRS] | 18 MODULE_DIRS = lambda: [os.path.join(x, 'recipe_modules') for x in BASE_DIRS] |
| 18 RECIPE_DIRS = lambda: [os.path.join(x, 'recipes') for x in BASE_DIRS] | 19 RECIPE_DIRS = lambda: [os.path.join(x, 'recipes') for x in BASE_DIRS] |
| 19 | 20 |
| 21 |
| 20 class RecipeAbort(Exception): | 22 class RecipeAbort(Exception): |
| 21 pass | 23 pass |
| 22 | 24 |
| 23 | 25 |
| 24 class ModuleInjectionError(AttributeError): | 26 class ModuleInjectionError(AttributeError): |
| 25 pass | 27 pass |
| 26 | 28 |
| 27 | 29 |
| 28 class ModuleInjectionSite(object): | 30 class ModuleInjectionSite(object): |
| 29 def __init__(self, owner_module=None): | 31 def __init__(self, owner_module=None): |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 @static_wraps(func) | 106 @static_wraps(func) |
| 105 def inner(self, *args, **kwargs): | 107 def inner(self, *args, **kwargs): |
| 106 ret = static_call(self, func, *args, **kwargs) | 108 ret = static_call(self, func, *args, **kwargs) |
| 107 assert isinstance(ret, Placeholder) | 109 assert isinstance(ret, Placeholder) |
| 108 ret.name_pieces = (self.name, static_name(self, func)) | 110 ret.name_pieces = (self.name, static_name(self, func)) |
| 109 return ret | 111 return ret |
| 110 return inner | 112 return inner |
| 111 | 113 |
| 112 | 114 |
| 113 def wrap_followup(kwargs, pre=False): | 115 def wrap_followup(kwargs, pre=False): |
| 114 """ | 116 """Decorator for a new followup_fn. |
| 115 Decorator for a new followup_fn. | |
| 116 | 117 |
| 117 Will pop the existing fn out of kwargs (if any), and return a decorator for | 118 Will pop the existing fn out of kwargs (if any), and return a decorator for |
| 118 the new folloup_fn. | 119 the new folloup_fn. |
| 119 | 120 |
| 120 Args: | 121 Args: |
| 121 kwargs - dictionary possibly containing folloup_fn | 122 kwargs - dictionary possibly containing folloup_fn |
| 122 pre - If true, the old folloup_fn is called before the wrapped function. | 123 pre - If true, the old folloup_fn is called before the wrapped function. |
| 123 Otherwise, the old followup_fn is called after the wrapped function. | 124 Otherwise, the old followup_fn is called after the wrapped function. |
| 124 """ | 125 """ |
| 125 null_fn = lambda _: None | 126 null_fn = lambda _: None |
| 126 old_followup = kwargs.pop('followup_fn', null_fn) | 127 old_followup = kwargs.pop('followup_fn', null_fn) |
| 127 def decorator(f): | 128 def decorator(f): |
| 128 @functools.wraps(f) | 129 @functools.wraps(f) |
| 129 def _inner(step_result): | 130 def _inner(step_result): |
| 130 if pre: | 131 if pre: |
| 131 old_followup(step_result) | 132 old_followup(step_result) |
| 132 f(step_result) | 133 f(step_result) |
| 133 else: | 134 else: |
| 134 f(step_result) | 135 f(step_result) |
| 135 old_followup(step_result) | 136 old_followup(step_result) |
| 136 if old_followup is not null_fn: | 137 if old_followup is not null_fn: |
| 137 _inner.__name__ += '[%s]' % old_followup.__name__ | 138 _inner.__name__ += '[%s]' % old_followup.__name__ |
| 138 return _inner | 139 return _inner |
| 139 return decorator | 140 return decorator |
| 140 | 141 |
| 141 | 142 |
| 143 def cached_unary(f): |
| 144 """Decorator that caches/memoizes an unary function result. |
| 145 |
| 146 If the function throws an exception, the cache table will not be updated. |
| 147 """ |
| 148 cache = {} |
| 149 empty = object() |
| 150 |
| 151 @functools.wraps(f) |
| 152 def cached_f(inp): |
| 153 cache_entry = cache.get(inp, empty) |
| 154 if cache_entry is empty: |
| 155 cache_entry = f(inp) |
| 156 cache[inp] = cache_entry |
| 157 return cache_entry |
| 158 return cached_f |
| 159 |
| 160 |
| 161 def scan_directory(path, predicate): |
| 162 """Recursively scans a directory and yields paths that match predicate.""" |
| 163 for root, _dirs, files in os.walk(path): |
| 164 for file_name in (f for f in files if predicate(f)): |
| 165 file_path = os.path.join(root, file_name) |
| 166 yield file_path |
| OLD | NEW |