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

Side by Side Diff: recipe_engine/config_types.py

Issue 1925653002: recipe engine: require all path bases to be classes (Closed) Base URL: https://github.com/luci/recipes-py.git@master
Patch Set: rebase Created 4 years, 7 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
« no previous file with comments | « no previous file | recipe_modules/path/api.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
5 import abc 5 import abc
6 import os 6 import os
7 import re 7 import re
8 8
9 from collections import namedtuple 9 from collections import namedtuple
10 10
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 """Returns a string representation of the path base. 73 """Returns a string representation of the path base.
74 74
75 Args: 75 Args:
76 api (RecipeApi) - instance of path module's RecipeApi 76 api (RecipeApi) - instance of path module's RecipeApi
77 test_enabled (bool) - true iff this is only for recipe expectations 77 test_enabled (bool) - true iff this is only for recipe expectations
78 """ 78 """
79 raise NotImplementedError() 79 raise NotImplementedError()
80 80
81 81
82 class NamedBasePath(BasePath, namedtuple('NamedBasePath', 'name')): 82 class NamedBasePath(BasePath, namedtuple('NamedBasePath', 'name')):
83 # Restrict basenames to '[ALL_CAPS]'. This will help catch
84 # errors if someone attempts to provide an actual string path '/some/example'
85 # as the 'base'.
86 BASE_RE = re.compile(r'\[([A-Z][A-Z_]*)\]')
87
88 @staticmethod
89 def parse(base):
90 base_match = NamedBasePath.BASE_RE.match(base)
91 assert base_match, 'Base should be [ALL_CAPS], got %r' % base
92 return NamedBasePath(base_match.group(1).lower())
93
94 def resolve(self, api, test_enabled): 83 def resolve(self, api, test_enabled):
95 if self.name in api.c.dynamic_paths: 84 if self.name in api.c.dynamic_paths:
96 return api.c.dynamic_paths[self.name] 85 return api.c.dynamic_paths[self.name]
97 if self.name in api.c.base_paths: 86 if self.name in api.c.base_paths:
98 if test_enabled: 87 if test_enabled:
99 return repr(self) 88 return repr(self)
100 return api.join(*api.c.base_paths[self.name]) # pragma: no cover 89 return api.join(*api.c.base_paths[self.name]) # pragma: no cover
101 raise KeyError( 90 raise KeyError(
102 'Failed to resolve NamedBasePath: %s' % self.name) # pragma: no cover 91 'Failed to resolve NamedBasePath: %s' % self.name) # pragma: no cover
103 92
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 base (str) - The 'name' of a base path, to be filled in at recipe runtime 136 base (str) - The 'name' of a base path, to be filled in at recipe runtime
148 by the 'path' recipe module. 137 by the 'path' recipe module.
149 pieces (tuple(str)) - The components of the path relative to base. These 138 pieces (tuple(str)) - The components of the path relative to base. These
150 pieces must be non-relative (i.e. no '..' or '.', etc. as a piece). 139 pieces must be non-relative (i.e. no '..' or '.', etc. as a piece).
151 140
152 Kwargs: 141 Kwargs:
153 platform_ext (dict(str, str)) - A mapping from platform name (as defined 142 platform_ext (dict(str, str)) - A mapping from platform name (as defined
154 by the 'platform' module), to a suffix for the path. 143 by the 'platform' module), to a suffix for the path.
155 """ 144 """
156 super(Path, self).__init__() 145 super(Path, self).__init__()
146 assert isinstance(base, BasePath), base
157 assert all(isinstance(x, basestring) for x in pieces), pieces 147 assert all(isinstance(x, basestring) for x in pieces), pieces
158 assert not any(x in ('..', '.', '/', '\\') for x in pieces) 148 assert not any(x in ('..', '.', '/', '\\') for x in pieces)
149
150 self.base = base
159 self.pieces = pieces 151 self.pieces = pieces
160
161 if isinstance(base, BasePath):
162 self.base = base
163 elif isinstance(base, basestring):
164 self.base = NamedBasePath.parse(base)
165 else:
166 raise ValueError('%s is not a valid base path' % (base,))
167
168 self.platform_ext = kwargs.get('platform_ext', {}) 152 self.platform_ext = kwargs.get('platform_ext', {})
169 153
170 def __eq__(self, other): 154 def __eq__(self, other):
171 return (self.base == other.base and 155 return (self.base == other.base and
172 self.pieces == other.pieces and 156 self.pieces == other.pieces and
173 self.platform_ext == other.platform_ext) 157 self.platform_ext == other.platform_ext)
174 158
175 def __ne__(self, other): 159 def __ne__(self, other):
176 return not self.base == other 160 return not self.base == other
177 161
(...skipping 11 matching lines...) Expand all
189 if len(self.pieces) >= len(child.pieces): 173 if len(self.pieces) >= len(child.pieces):
190 return False 174 return False
191 return child.pieces[:len(self.pieces)] == self.pieces 175 return child.pieces[:len(self.pieces)] == self.pieces
192 176
193 def __repr__(self): 177 def __repr__(self):
194 s = "Path(%r" % self.base 178 s = "Path(%r" % self.base
195 if self.pieces: 179 if self.pieces:
196 s += ", %s" % ",".join(repr(x) for x in self.pieces) 180 s += ", %s" % ",".join(repr(x) for x in self.pieces)
197 181
198 return s + ")" 182 return s + ")"
OLDNEW
« no previous file with comments | « no previous file | recipe_modules/path/api.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698