| 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 functools | 5 import functools |
| 6 import itertools | 6 import itertools |
| 7 import os | 7 import os |
| 8 import tempfile | 8 import tempfile |
| 9 | 9 |
| 10 from recipe_engine import recipe_api | 10 from recipe_engine import recipe_api |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 | 154 |
| 155 def __init__(self, **kwargs): | 155 def __init__(self, **kwargs): |
| 156 super(PathApi, self).__init__(**kwargs) | 156 super(PathApi, self).__init__(**kwargs) |
| 157 config_types.Path.set_tostring_fn( | 157 config_types.Path.set_tostring_fn( |
| 158 PathToString(self, self._test_data)) | 158 PathToString(self, self._test_data)) |
| 159 config_types.NamedBasePath.set_path_api(self) | 159 config_types.NamedBasePath.set_path_api(self) |
| 160 | 160 |
| 161 # Used in mkdtemp when generating and checking expectations. | 161 # Used in mkdtemp when generating and checking expectations. |
| 162 self._test_counter = 0 | 162 self._test_counter = 0 |
| 163 | 163 |
| 164 def _read_module_property(self, property_name, default=None): | |
| 165 """Reads a path property module from "$recipe_engine/path". If absent, | |
| 166 returns the default. | |
| 167 """ | |
| 168 props = self.m.properties.get('$recipe_engine/path', {}) | |
| 169 return props.get(property_name, default) | |
| 170 | |
| 171 def _read_path(self, property_name, default): # pragma: no cover | 164 def _read_path(self, property_name, default): # pragma: no cover |
| 172 """Reads a path from a property. If absent, returns the default. | 165 """Reads a path from a property. If absent, returns the default. |
| 173 | 166 |
| 174 Validates that the path is absolute. | 167 Validates that the path is absolute. |
| 175 """ | 168 """ |
| 176 value = self._read_module_property(property_name) | 169 props = self.m.properties.get('$recipe_engine/path', {}) |
| 170 value = props.get(property_name) |
| 177 if not value: | 171 if not value: |
| 178 assert os.path.isabs(default), default | 172 assert os.path.isabs(default), default |
| 179 return default | 173 return default |
| 180 if not os.path.isabs(value): | 174 if not os.path.isabs(value): |
| 181 raise Error( | 175 raise Error( |
| 182 'Path "%s" specified by module property %s is not absolute' % ( | 176 'Path "%s" specified by module property %s is not absolute' % ( |
| 183 value, property_name)) | 177 value, property_name)) |
| 184 return value | 178 return value |
| 185 | 179 |
| 186 def _ensure_dir(self, path): # pragma: no cover | 180 def _ensure_dir(self, path): # pragma: no cover |
| (...skipping 15 matching lines...) Expand all Loading... |
| 202 cache_dir = self._read_path('cache_dir', os.path.join(os.getcwd(), 'cache'
)) | 196 cache_dir = self._read_path('cache_dir', os.path.join(os.getcwd(), 'cache'
)) |
| 203 self._ensure_dir(cache_dir) | 197 self._ensure_dir(cache_dir) |
| 204 self._cache_dir = _split_path(cache_dir) | 198 self._cache_dir = _split_path(cache_dir) |
| 205 else: | 199 else: |
| 206 self._path_mod = fake_path(self, self._test_data.get('exists', [])) | 200 self._path_mod = fake_path(self, self._test_data.get('exists', [])) |
| 207 self._startup_cwd = ['/', 'b', 'FakeTestingCWD'] | 201 self._startup_cwd = ['/', 'b', 'FakeTestingCWD'] |
| 208 # Appended to placeholder '[TMP]' to get fake path in test. | 202 # Appended to placeholder '[TMP]' to get fake path in test. |
| 209 self._temp_dir = ['/'] | 203 self._temp_dir = ['/'] |
| 210 self._cache_dir = ['/', 'b', 'c'] | 204 self._cache_dir = ['/', 'b', 'c'] |
| 211 | 205 |
| 212 self._volatile_paths = self._read_module_property('volatile', []) | |
| 213 | |
| 214 self.set_config('BASE') | 206 self.set_config('BASE') |
| 215 | 207 |
| 216 def mock_add_paths(self, path): | 208 def mock_add_paths(self, path): |
| 217 """For testing purposes, assert that |path| exists.""" | 209 """For testing purposes, assert that |path| exists.""" |
| 218 if self._test_data.enabled: | 210 if self._test_data.enabled: |
| 219 self._path_mod.mock_add_paths(path) | 211 self._path_mod.mock_add_paths(path) |
| 220 | 212 |
| 221 def assert_absolute(self, path): | 213 def assert_absolute(self, path): |
| 222 assert self.abspath(path) == str(path), '%s is not absolute' % path | 214 assert self.abspath(path) == str(path), '%s is not absolute' % path |
| 223 | 215 |
| 224 def is_volatile(self, base): | |
| 225 """Returns (bool): True if the named path is declared as volatile. | |
| 226 | |
| 227 A path is volatile if it is scoped to the recipe engine execution. Note that | |
| 228 some paths may be volatile, but not explicitly declared as such. | |
| 229 """ | |
| 230 return base in self.c.volatile_paths or base in self._volatile_paths | |
| 231 | |
| 232 def mkdtemp(self, prefix): | 216 def mkdtemp(self, prefix): |
| 233 """Makes a new temp directory, returns path to it.""" | 217 """Makes a new temp directory, returns path to it.""" |
| 234 if not self._test_data.enabled: # pragma: no cover | 218 if not self._test_data.enabled: # pragma: no cover |
| 235 # New path as str. | 219 # New path as str. |
| 236 new_path = tempfile.mkdtemp(prefix=prefix, dir=str(self['tmp_base'])) | 220 new_path = tempfile.mkdtemp(prefix=prefix, dir=str(self['tmp_base'])) |
| 237 # Ensure it's under self._temp_dir, convert to Path. | 221 # Ensure it's under self._temp_dir, convert to Path. |
| 238 new_path = _split_path(new_path) | 222 new_path = _split_path(new_path) |
| 239 assert new_path[:len(self._temp_dir)] == self._temp_dir | 223 assert new_path[:len(self._temp_dir)] == self._temp_dir |
| 240 temp_dir = self['tmp_base'].join(*new_path[len(self._temp_dir):]) | 224 temp_dir = self['tmp_base'].join(*new_path[len(self._temp_dir):]) |
| 241 else: | 225 else: |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 if name in self.OK_ATTRS: | 299 if name in self.OK_ATTRS: |
| 316 return getattr(self._path_mod, name) | 300 return getattr(self._path_mod, name) |
| 317 if name in self.FILTER_METHODS: | 301 if name in self.FILTER_METHODS: |
| 318 return string_filter(getattr(self._path_mod, name)) | 302 return string_filter(getattr(self._path_mod, name)) |
| 319 raise AttributeError("'%s' object has no attribute '%s'" % | 303 raise AttributeError("'%s' object has no attribute '%s'" % |
| 320 (self._path_mod, name)) # pragma: no cover | 304 (self._path_mod, name)) # pragma: no cover |
| 321 | 305 |
| 322 def __dir__(self): # pragma: no cover | 306 def __dir__(self): # pragma: no cover |
| 323 # Used for helping out show_me_the_modules.py | 307 # Used for helping out show_me_the_modules.py |
| 324 return self.__dict__.keys() + list(self.OK_ATTRS + self.FILTER_METHODS) | 308 return self.__dict__.keys() + list(self.OK_ATTRS + self.FILTER_METHODS) |
| OLD | NEW |