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

Side by Side Diff: scripts/slave/recipe_config_types.py

Issue 24737002: Add Paths as first-class types in configs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Address comments Created 7 years, 2 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 import re
2
3 def ResetTostringFns():
4 RecipeConfigType._TOSTRING_MAP.clear() # pylint: disable=W0212
5
6
7 def json_fixup(obj):
8 if isinstance(obj, RecipeConfigType):
9 return str(obj)
10 raise TypeError("%r is not JSON serializable" % obj)
11
12
13 class RecipeConfigType(object):
14 """Base class for custom Recipe config types, intended to be subclassed.
15
16 RecipeConfigTypes are meant to be PURE data. There should be no dependency on
17 any external systems (i.e. no importing sys, os, etc.).
18
19 The subclasses should override default_tostring_fn. This method should
20 produce a string representation of the object. This string representation
21 should contain all of the data members of the subclass. This representation
22 will be used during the execution of the recipe_config_tests.
23
24 External entities (usually recipe modules), can override the default
25 tostring_fn method by calling <RecipeConfigType
26 subclass>.set_tostring_fn(<new method>). This new method will recieve an
27 instance of the RecipeConfigType subclass as its single argument, and is
28 expected to return a string. There is no restriction on the data that the
29 override tostring_fn may use (for example, the Path class in this module has
30 its tostring_fn overridden by the 'path' recipe_module. This new tostring_fn
31 uses data from the current recipe run, like the host os, to return platform
32 specific strings using the data in the Path object.)
agable 2013/09/27 17:48:17 nit: your punctuation in/around your parentheses i
iannucci 2013/09/27 19:23:37 Done.
33
34 """
35 _TOSTRING_MAP = {}
36
37 @property
38 def tostring_fn(self):
39 cls = self.__class__
40 return self._TOSTRING_MAP.get(cls.__name__, cls.default_tostring_fn)
41
42 @classmethod
43 def set_tostring_fn(cls, new_tostring_fn):
44 assert cls.__name__ not in cls._TOSTRING_MAP, (
45 'tostring_fn already installed for %s' % cls)
46 cls._TOSTRING_MAP[cls.__name__] = new_tostring_fn
47
48 def default_tostring_fn(self):
49 raise NotImplementedError
50
51 def __str__(self):
52 return self.tostring_fn(self)
53
54
55 class Path(RecipeConfigType):
56 """Represents a path which is relative to a semantically-named base.
57
58 Because there's a lot of platform (separator style) and runtime-specific
59 context (working directory) which goes into assembling a final OS-specific
60 absolute path, we only store three attributes in this Path object:
61 * base (str) - The 'name' of a base path, to be filled in at recipe runtime
62 by the 'path' recipe module.
63 * pieces (tuple(str)) - The components of the path relative to base. These
64 pieces must be non-relative (i.e. no '..' or '.' as a piece).
65 * platform_ext (dict(str, str)) - A mapping from platform name (as defined
66 by the 'platform' module), to a suffix for the path.
67 """
68 # Restrict basenames to simple alpha pythonic tokens. This will help catch
69 # errors if someone attempts to provide an actual string path '/some/example'
70 # as the 'base'.
71 BASE_RE = re.compile("[a-z][a-z_]*")
72
73 def __init__(self, base, pieces=(), platform_ext=None):
agable 2013/09/27 17:48:17 I think I would prefer that BASE_RE assert that ba
iannucci 2013/09/27 19:23:37 Done.
74 super(Path, self).__init__()
75 assert not any(x in ('..', '.') for x in pieces)
agable 2013/09/27 17:48:17 Also assert that '/' isn't one of the pieces. IIRC
iannucci 2013/09/27 19:23:37 Done.
76 assert self.BASE_RE.match(base)
77
78 self.base = base
79 self.pieces = pieces
80 self.platform_ext = platform_ext or {}
81
82 def __call__(self, *pieces, **kwargs):
83 platform_ext = kwargs.get('platform_ext', self.platform_ext)
84 return Path(self.base, filter(bool, self.pieces + pieces), platform_ext)
85
86 def default_tostring_fn(self):
87 suffix = ''
88 if self.platform_ext:
89 suffix = ', platform_ext=%r' % (self.platform_ext,)
90 return 'Path([%s], %r%s)' % (self.base.upper(), self.pieces, suffix)
agable 2013/09/27 17:48:17 Would still prefer to have this print self.pieces
iannucci 2013/09/27 19:23:37 Done.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698