Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Side by Side Diff: recipe_modules/path/api.py

Issue 2909983003: [loader] Make recipe engine support examples/ module subdir (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 re
8 import tempfile 9 import tempfile
9 10
10 from recipe_engine import recipe_api 11 from recipe_engine import recipe_api
11 from recipe_engine import config_types 12 from recipe_engine import config_types
12 13
13 14
14 class Error(Exception): 15 class Error(Exception):
15 """Error specific to path recipe module.""" 16 """Error specific to path recipe module."""
16 17
17 18
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 current platform according to the `platform` module. This allows us to 66 current platform according to the `platform` module. This allows us to
66 simulate path functions according to the platform being tested, rather than 67 simulate path functions according to the platform being tested, rather than
67 the platform which is currently running. 68 the platform which is currently running.
68 """ 69 """
69 70
70 def __init__(self, api, _mock_path_exists): 71 def __init__(self, api, _mock_path_exists):
71 self._api = api 72 self._api = api
72 self._mock_path_exists = path_set(self, _mock_path_exists) 73 self._mock_path_exists = path_set(self, _mock_path_exists)
73 self._pth = None 74 self._pth = None
74 75
75 def __getattr__(self, name): 76 def _init_pth(self):
76 if not self._pth: 77 if not self._pth:
77 if self._api.m.platform.is_win: 78 if self._api.m.platform.is_win:
78 import ntpath as pth 79 import ntpath as pth
79 elif self._api.m.platform.is_mac or self._api.m.platform.is_linux: 80 elif self._api.m.platform.is_mac or self._api.m.platform.is_linux:
80 import posixpath as pth 81 import posixpath as pth
81 self._pth = pth 82 self._pth = pth
83
84 def __getattr__(self, name):
85 self._init_pth()
82 return getattr(self._pth, name) 86 return getattr(self._pth, name)
83 87
84 def mock_add_paths(self, path): 88 def mock_add_paths(self, path):
85 """ 89 """
86 Adds a path and all of its parents to the set of existing paths. 90 Adds a path and all of its parents to the set of existing paths.
87 """ 91 """
88 self._mock_path_exists.add(path) 92 self._mock_path_exists.add(path)
89 93
90 def exists(self, path): # pylint: disable=E0202 94 def exists(self, path): # pylint: disable=E0202
91 """Return True if path refers to an existing path.""" 95 """Return True if path refers to an existing path."""
92 return self._mock_path_exists.contains(path) 96 return self._mock_path_exists.contains(path)
93 97
98 # This matches:
99 # [START_DIR]
100 # RECIPE[some_pkg::some_module:recipe_name]
101 #
102 # and friends at the beginning of a string.
103 ROOT_MATCHER = re.compile('^[A-Z_]*\[[^]]*\]')
104
105 def normpath(self, path):
106 """Normalizese the path.
107
108 This splits off a recipe base (i.e. RECIPE[...]) so that normpath is
109 only called on the user-supplied portion of the path.
110 """
111 self._init_pth()
112 real_normpath = self._pth.normpath
113 m = self.ROOT_MATCHER.match(path)
114 if m:
115 prefix = m.group(0)
116 rest = path[len(prefix):]
117 if rest == '':
118 # normpath turns '' into '.'
119 return prefix
120 return prefix + real_normpath(rest)
121 return real_normpath(path)
122
94 def abspath(self, path): 123 def abspath(self, path):
95 """Returns the absolute version of path.""" 124 """Returns the absolute version of path."""
96 return self.normpath(path) 125 return self.normpath(path)
97 126
98 def realpath(self, path): 127 def realpath(self, path):
99 """Returns the canonical version of the path.""" 128 """Returns the canonical version of the path."""
100 return self.normpath(path) 129 return self.normpath(path)
101 130
102 def expanduser(self, path): 131 def expanduser(self, path):
103 return path.replace('~', '[HOME]') 132 return path.replace('~', '[HOME]')
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 Example: 278 Example:
250 ``` 279 ```
251 # assume [START_DIR] == "/basis/dir/for/recipe" 280 # assume [START_DIR] == "/basis/dir/for/recipe"
252 api.path.abs_to_path("/basis/dir/for/recipe/some/other/dir") -> 281 api.path.abs_to_path("/basis/dir/for/recipe/some/other/dir") ->
253 Path("[START_DIR]/some/other/dir") 282 Path("[START_DIR]/some/other/dir")
254 ``` 283 ```
255 284
256 Raises an ValueError if the preconditions are not met, otherwise returns the 285 Raises an ValueError if the preconditions are not met, otherwise returns the
257 Path object. 286 Path object.
258 """ 287 """
259 if self.abspath(abs_string_path) != abs_string_path: 288 ap = self.abspath(abs_string_path)
260 raise ValueError("path is not absolute: %r" % abs_string_path) 289 if ap != abs_string_path:
290 raise ValueError("path is not absolute: %r v %r" % (abs_string_path, ap))
261 291
262 # try module/recipe/package resource paths first 292 # try module/recipe/package resource paths first
263 sPath, path = self._paths_client.find_longest_prefix( 293 sPath, path = self._paths_client.find_longest_prefix(
264 abs_string_path, self.sep) 294 abs_string_path, self.sep)
265 if path is None: 295 if path is None:
266 # try base paths now 296 # try base paths now
267 for path_name in itertools.chain(self.c.dynamic_paths, self.c.base_paths): 297 for path_name in itertools.chain(self.c.dynamic_paths, self.c.base_paths):
268 path = self[path_name] 298 path = self[path_name]
269 sPath = str(path) 299 sPath = str(path)
270 if abs_string_path.startswith(sPath): 300 if abs_string_path.startswith(sPath):
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 if name in self.OK_ATTRS: 332 if name in self.OK_ATTRS:
303 return getattr(self._path_mod, name) 333 return getattr(self._path_mod, name)
304 if name in self.FILTER_METHODS: 334 if name in self.FILTER_METHODS:
305 return string_filter(getattr(self._path_mod, name)) 335 return string_filter(getattr(self._path_mod, name))
306 raise AttributeError("'%s' object has no attribute '%s'" % 336 raise AttributeError("'%s' object has no attribute '%s'" %
307 (self._path_mod, name)) # pragma: no cover 337 (self._path_mod, name)) # pragma: no cover
308 338
309 def __dir__(self): # pragma: no cover 339 def __dir__(self): # pragma: no cover
310 # Used for helping out show_me_the_modules.py 340 # Used for helping out show_me_the_modules.py
311 return self.__dict__.keys() + list(self.OK_ATTRS + self.FILTER_METHODS) 341 return self.__dict__.keys() + list(self.OK_ATTRS + self.FILTER_METHODS)
OLDNEW
« no previous file with comments | « recipe_modules/json/examples/full.resources/cool_script.py ('k') | recipe_modules/path/example.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698