| OLD | NEW |
| 1 # Copyright 2013 The LUCI Authors. All rights reserved. | 1 # Copyright 2013 The LUCI Authors. All rights reserved. |
| 2 # Use of this source code is governed under the Apache License, Version 2.0 | 2 # Use of this source code is governed under the Apache License, Version 2.0 |
| 3 # that can be found in the LICENSE file. | 3 # that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import contextlib | 5 import contextlib |
| 6 import datetime | 6 import datetime |
| 7 import functools | 7 import functools |
| 8 import logging | 8 import logging |
| 9 import os | 9 import os |
| 10 import sys | 10 import sys |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 def inner(self, *args, **kwargs): | 121 def inner(self, *args, **kwargs): |
| 122 ret = static_call(self, func, *args, **kwargs) | 122 ret = static_call(self, func, *args, **kwargs) |
| 123 assert isinstance(ret, Placeholder) | 123 assert isinstance(ret, Placeholder) |
| 124 ret.namespaces = (self.name, static_name(self, func)) | 124 ret.namespaces = (self.name, static_name(self, func)) |
| 125 return ret | 125 return ret |
| 126 # prevent this placeholder-returning function from becoming a composite_step. | 126 # prevent this placeholder-returning function from becoming a composite_step. |
| 127 inner._non_step = True # pylint: disable=protected-access | 127 inner._non_step = True # pylint: disable=protected-access |
| 128 return inner | 128 return inner |
| 129 | 129 |
| 130 | 130 |
| 131 def scan_directory(path, predicate): | |
| 132 """Recursively scans a directory and yields paths that match predicate.""" | |
| 133 for root, _dirs, files in os.walk(path): | |
| 134 for file_name in (f for f in files if predicate(f)): | |
| 135 file_path = os.path.join(root, file_name) | |
| 136 yield file_path | |
| 137 | |
| 138 | |
| 139 BUG_LINK = ( | 131 BUG_LINK = ( |
| 140 'https://code.google.com/p/chromium/issues/entry?%s' % urllib.urlencode({ | 132 'https://code.google.com/p/chromium/issues/entry?%s' % urllib.urlencode({ |
| 141 'summary': 'Recipe engine bug: unexpected failure', | 133 'summary': 'Recipe engine bug: unexpected failure', |
| 142 'comment': 'Link to the failing build and paste the exception here', | 134 'comment': 'Link to the failing build and paste the exception here', |
| 143 'labels': 'Infra,Infra-Area-Recipes,Pri-1,Restrict-View-Google,' | 135 'labels': 'Infra,Infra-Area-Recipes,Pri-1,Restrict-View-Google,' |
| 144 'Infra-Troopers', | 136 'Infra-Troopers', |
| 145 'cc': 'martiniss@chromium.org,iannucci@chromium.org', | 137 'cc': 'martiniss@chromium.org,iannucci@chromium.org', |
| 146 })) | 138 })) |
| 147 | 139 |
| 148 | 140 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 it (iterable): An iterable to traverse. | 302 it (iterable): An iterable to traverse. |
| 311 exc_types (list): An optional list of specific exception types to defer. | 303 exc_types (list): An optional list of specific exception types to defer. |
| 312 If empty, Exception will be used. Any Exceptions not referenced by this | 304 If empty, Exception will be used. Any Exceptions not referenced by this |
| 313 list will skip deferring and be immediately raised. | 305 list will skip deferring and be immediately raised. |
| 314 """ | 306 """ |
| 315 mexc_builder = MultiException.Builder() | 307 mexc_builder = MultiException.Builder() |
| 316 for e in it: | 308 for e in it: |
| 317 with mexc_builder.catch(*exc_types): | 309 with mexc_builder.catch(*exc_types): |
| 318 fn(e) | 310 fn(e) |
| 319 mexc_builder.raise_if_any() | 311 mexc_builder.raise_if_any() |
| OLD | NEW |