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

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

Issue 2934583003: [step] Remove config indirection. (Closed)
Patch Set: fix test 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 contextlib 5 import contextlib
6 import copy 6 import copy
7 import types
7 8
8 from recipe_engine import recipe_api 9 from recipe_engine import recipe_api
10 from recipe_engine.config_types import Path
11 from recipe_engine.util import Placeholder
9 12
10 13
11 # Inherit from RecipeApiPlain because the only thing which is a step is 14 # Inherit from RecipeApiPlain because the only thing which is a step is
12 # run_from_dict() 15 # run_from_dict()
13 class StepApi(recipe_api.RecipeApiPlain): 16 class StepApi(recipe_api.RecipeApiPlain):
14 17
15 step_client = recipe_api.RequireClient('step') 18 step_client = recipe_api.RequireClient('step')
16 19
17 def __init__(self, step_properties, **kwargs): 20 def __init__(self, step_properties, **kwargs):
18 super(StepApi, self).__init__(**kwargs) 21 super(StepApi, self).__init__(**kwargs)
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 infra_step: Whether or not this is an infrastructure step. Infrastructure 119 infra_step: Whether or not this is an infrastructure step. Infrastructure
117 steps will place the step in an EXCEPTION state and raise InfraFailure. 120 steps will place the step in an EXCEPTION state and raise InfraFailure.
118 wrapper: If supplied, a command to prepend to the executed step as a 121 wrapper: If supplied, a command to prepend to the executed step as a
119 command wrapper. 122 command wrapper.
120 timeout: If supplied, the recipe engine will kill the step after the 123 timeout: If supplied, the recipe engine will kill the step after the
121 specified number of seconds. 124 specified number of seconds.
122 allow_subannotations (bool): if True, lets the step emit its own 125 allow_subannotations (bool): if True, lets the step emit its own
123 annotations. NOTE: Enabling this can cause some buggy behavior. Please 126 annotations. NOTE: Enabling this can cause some buggy behavior. Please
124 strongly consider using step_result.presentation instead. If you have 127 strongly consider using step_result.presentation instead. If you have
125 questions, please contact infra-dev@chromium.org. 128 questions, please contact infra-dev@chromium.org.
126 trigger_specs: a list of trigger specifications 129 trigger_specs: a list of trigger specifications
iannucci 2017/06/12 19:37:57 do you know enough about this to add a bit more do
dnj 2017/06/13 18:28:38 no :(
127 stdout: Placeholder to put step stdout into. If used, stdout won't appear 130 stdout: Placeholder to put step stdout into. If used, stdout won't appear
128 in annotator's stdout (and |allow_subannotations| is ignored). 131 in annotator's stdout (and |allow_subannotations| is ignored).
129 stderr: Placeholder to put step stderr into. If used, stderr won't appear 132 stderr: Placeholder to put step stderr into. If used, stderr won't appear
130 in annotator's stderr. 133 in annotator's stderr.
131 stdin: Placeholder to read step stdin from. 134 stdin: Placeholder to read step stdin from.
132 step_test_data (func -> recipe_test_api.StepTestData): A factory which 135 step_test_data (func -> recipe_test_api.StepTestData): A factory which
133 returns a StepTestData object that will be used as the default test 136 returns a StepTestData object that will be used as the default test
134 data for this step. The recipe author can override/augment this object 137 data for this step. The recipe author can override/augment this object
135 in the GenTests function. 138 in the GenTests function.
136 139
137 Returns: 140 Returns:
138 Opaque step object produced and understood by recipe engine. 141 Opaque step object produced and understood by recipe engine.
139 """ 142 """
140 kwargs = {}
141 if allow_subannotations is not None:
142 kwargs['allow_subannotations'] = allow_subannotations
143 if trigger_specs:
144 kwargs['trigger_specs'] = trigger_specs
145 if stdout:
146 kwargs['stdout'] = stdout
147 if stderr:
148 kwargs['stderr'] = stderr
149 if stdin:
150 kwargs['stdin'] = stdin
151 if step_test_data:
152 kwargs['step_test_data'] = step_test_data
153 assert cmd is None or isinstance(cmd, list)
154 if not ok_ret:
155 ok_ret = {0}
156 if ok_ret in ('any', 'all'):
157 ok_ret = set(range(-256, 256))
158
159 if cmd is not None:
160 command = list(wrapper)
161 command += cmd
162 kwargs['cmd'] = command
163
164 kwargs['timeout'] = timeout
165 kwargs['ok_ret'] = ok_ret
166
167 # Calculate our full step name. If a step already has that name, add an 143 # Calculate our full step name. If a step already has that name, add an
168 # index to the end of it. 144 # index to the end of it.
169 # 145 #
170 # Note that another step could exist with that index already added to it 146 # Note that another step could exist with that index already added to it
171 # by the user. If this happens, we'll continue appending indexes until we 147 # by the user. If this happens, we'll continue appending indexes until we
172 # have a unique step name. 148 # have a unique step name.
173 with self.m.context(name_prefix=name): 149 with self.m.context(name_prefix=name):
174 base_name = self.m.context.name_prefix 150 base_name = self.m.context.name_prefix
175 name_suffix = '' 151 name_suffix = ''
176 152
177 while True: 153 while True:
178 full_name = base_name + name_suffix 154 full_name = base_name + name_suffix
179 if full_name not in self._seen_steps: 155 if full_name not in self._seen_steps:
180 break 156 break
181 157
182 step_count = self._step_names.setdefault(full_name, 1) + 1 158 step_count = self._step_names.setdefault(full_name, 1) + 1
183 self._step_names[full_name] = step_count 159 self._step_names[full_name] = step_count
184 name_suffix = ' (%d)' % step_count 160 name_suffix = ' (%d)' % step_count
185 self._seen_steps.add(full_name) 161 self._seen_steps.add(full_name)
186 162
163 assert isinstance(cmd, (types.NoneType, list))
164 if cmd is not None:
165 cmd = list(wrapper) + cmd
166 assert all(isinstance(x, (int, long, basestring, Path, Placeholder))
167 for x in cmd)
168
187 cwd = self.m.context.cwd 169 cwd = self.m.context.cwd
188 if cwd is not None and cwd != self.m.path['start_dir']: 170 if cwd and cwd == self.m.path['start_dir']:
189 kwargs['cwd'] = cwd 171 cwd = None
190 kwargs['env'] = self.m.context.env 172
173 env = self.m.context.env
191 if self._prefix_path: 174 if self._prefix_path:
192 ps = self.m.path.pathsep 175 ps = self.m.path.pathsep
193 prefix = ps.join(self._prefix_path) 176 prefix = ps.join(self._prefix_path)
194 suffix = kwargs['env'].get('PATH', '%(PATH)s') 177 suffix = env.get('PATH', '%(PATH)s')
195 kwargs['env']['PATH'] = '%s%s%s' % (prefix, ps, suffix) 178 env['PATH'] = '%s%s%s' % (prefix, ps, suffix)
196 kwargs['infra_step'] = self.m.context.infra_step or bool(infra_step)
197 kwargs['step_nest_level'] = self.m.context.nest_level
198 kwargs['name'] = full_name
199 kwargs['base_name'] = name
200 179
201 schema = self.make_config() 180 if ok_ret in ('any', 'all'):
202 schema.set_val(kwargs) 181 ok_ret = range(-256, 256)
203 return self.run_from_dict(schema.as_jsonish())
204 182
205 # TODO(martiniss) delete, and make generator_script use **kwargs on step() 183 return self.run_step(
184 name=full_name,
185 base_name=full_name or name,
186 cmd=cmd,
187 cwd=cwd,
188 env=env,
189 allow_subannotations=bool(allow_subannotations),
190 trigger_specs=[self._make_trigger_spec(trig)
191 for trig in (trigger_specs or ())],
192 timeout=timeout,
193 infra_step=self.m.context.infra_step or bool(infra_step),
194 stdout=stdout,
195 stderr=stderr,
196 stdin=stdin,
197 ok_ret=ok_ret,
198 step_test_data=step_test_data,
199 nest_level=self.m.context.nest_level,
200 )
201
206 @recipe_api.composite_step 202 @recipe_api.composite_step
207 def run_from_dict(self, dct): 203 def run_step(self, **kwargs):
208 return self.step_client.run_step(dct) 204 # TODO(dnj,iannucci): Remove this once "generator_script" is deleted. Make
205 # sure we preserve "composite_step".
206 return self.step_client.run_step(self.step_client.StepConfig(**kwargs))
iannucci 2017/06/12 19:37:57 delete this function
dnj 2017/06/13 18:28:38 Done.
207
208 def _make_trigger_spec(self, trig):
209 buildbot_changes = trig.get('buildbot_changes')
210 assert isinstance(buildbot_changes, (types.NoneType, list))
211
212 critical = trig.get('critical')
213 return self.step_client.TriggerSpec(
214 bucket=trig.get('bucket'),
215 builder_name=trig['builder_name'],
216 properties=trig.get('properties'),
217 buildbot_changes=buildbot_changes,
218 tags=trig.get('tags'),
219 critical=bool(critical) if critical is not None else (True),
220 )
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698