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

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

Issue 1151423002: Move recipe engine to third_party/recipe_engine. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Moved field_composer_test with its buddies Created 5 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 | Annotate | Revision Log
« no previous file with comments | « scripts/slave/recipe_universe.py ('k') | scripts/slave/recipes/android/appurify.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 # found in the LICENSE file.
4
5 import functools
6 import os
7
8 from cStringIO import StringIO
9
10
11 SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__))
12 BUILD_ROOT = os.path.dirname(os.path.dirname(SCRIPT_PATH))
13 ROOT_PATH = os.path.abspath(os.path.join(
14 SCRIPT_PATH, os.pardir, os.pardir, os.pardir))
15 BASE_DIRS = [
16 SCRIPT_PATH,
17 os.path.join(ROOT_PATH, 'build_internal', 'scripts', 'slave'),
18 os.path.join(ROOT_PATH, 'build_internal', 'scripts', 'slave-internal')
19 ]
20 MODULE_DIRS = lambda: [os.path.join(x, 'recipe_modules') for x in BASE_DIRS]
21 RECIPE_DIRS = lambda: [os.path.join(x, 'recipes') for x in BASE_DIRS]
22
23
24 class RecipeAbort(Exception):
25 pass
26
27
28 class ModuleInjectionError(AttributeError):
29 pass
30
31
32 class ModuleInjectionSite(object):
33 def __init__(self, owner_module=None):
34 self.owner_module = owner_module
35
36 def __getattr__(self, key):
37 if self.owner_module is None:
38 raise ModuleInjectionError(
39 "RecipeApi has no dependency %r. (Add it to DEPS?)" % (key,))
40 else:
41 raise ModuleInjectionError(
42 "Recipe Module %r has no dependency %r. (Add it to __init__.py:DEPS?)"
43 % (self.owner_module.name, key))
44
45
46 class Placeholder(object):
47 """Base class for json placeholders. Do not use directly."""
48 def __init__(self):
49 self.name_pieces = None
50
51 @property
52 def backing_file(self): # pragma: no cover
53 """Return path to a temp file that holds or receives the data.
54
55 Valid only after 'render' has been called.
56 """
57 raise NotImplementedError
58
59 def render(self, test): # pragma: no cover
60 """Return [cmd items]*"""
61 raise NotImplementedError
62
63 def result(self, presentation, test):
64 """Called after step completion.
65
66 Args:
67 presentation (StepPresentation) - for the current step.
68 test (PlaceholderTestData) - test data for this placeholder.
69
70 Returns value to add to step result.
71
72 May optionally modify presentation as a side-effect.
73 """
74 pass
75
76 @property
77 def name(self):
78 assert self.name_pieces
79 return "%s.%s" % self.name_pieces
80
81
82 def static_wraps(func):
83 wrapped_fn = func
84 if isinstance(func, staticmethod):
85 # __get__(obj) is the way to get the function contained in the staticmethod.
86 # python 2.7+ has a __func__ member, but previous to this the attribute
87 # doesn't exist. It doesn't matter what the obj is, as long as it's not
88 # None.
89 wrapped_fn = func.__get__(object)
90 return functools.wraps(wrapped_fn)
91
92
93 def static_call(obj, func, *args, **kwargs):
94 if isinstance(func, staticmethod):
95 return func.__get__(obj)(*args, **kwargs)
96 else:
97 return func(obj, *args, **kwargs)
98
99
100 def static_name(obj, func):
101 if isinstance(func, staticmethod):
102 return func.__get__(obj).__name__
103 else:
104 return func.__name__
105
106
107 def returns_placeholder(func):
108 @static_wraps(func)
109 def inner(self, *args, **kwargs):
110 ret = static_call(self, func, *args, **kwargs)
111 assert isinstance(ret, Placeholder)
112 ret.name_pieces = (self.name, static_name(self, func))
113 return ret
114 # prevent this placeholder-returning function from becoming a composite_step.
115 inner._non_step = True # pylint: disable=protected-access
116 return inner
117
118
119 def cached_unary(f):
120 """Decorator that caches/memoizes an unary function result.
121
122 If the function throws an exception, the cache table will not be updated.
123 """
124 cache = {}
125 empty = object()
126
127 @functools.wraps(f)
128 def cached_f(inp):
129 cache_entry = cache.get(inp, empty)
130 if cache_entry is empty:
131 cache_entry = f(inp)
132 cache[inp] = cache_entry
133 return cache_entry
134 return cached_f
135
136
137 def scan_directory(path, predicate):
138 """Recursively scans a directory and yields paths that match predicate."""
139 for root, _dirs, files in os.walk(path):
140 for file_name in (f for f in files if predicate(f)):
141 file_path = os.path.join(root, file_name)
142 yield file_path
143
144
145 class StringListIO(object):
146 def __init__(self):
147 self.lines = [StringIO()]
148
149 def write(self, s):
150 while s:
151 i = s.find('\n')
152 if i == -1:
153 self.lines[-1].write(s)
154 break
155 self.lines[-1].write(s[:i])
156 self.lines[-1] = self.lines[-1].getvalue()
157 self.lines.append(StringIO())
158 s = s[i+1:]
159
160 def close(self):
161 if not isinstance(self.lines[-1], basestring):
162 self.lines[-1] = self.lines[-1].getvalue()
OLDNEW
« no previous file with comments | « scripts/slave/recipe_universe.py ('k') | scripts/slave/recipes/android/appurify.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698