| OLD | NEW |
| 1 # Copyright 2016 The LUCI Authors. All rights reserved. | 1 # Copyright 2016 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 from __future__ import absolute_import | 5 from __future__ import absolute_import |
| 6 import bisect | 6 import bisect |
| 7 import collections | 7 import collections |
| 8 import contextlib | 8 import contextlib |
| 9 import copy | 9 import copy |
| 10 import json | 10 import json |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 ) | 250 ) |
| 251 | 251 |
| 252 def _render_to_dict(self): | 252 def _render_to_dict(self): |
| 253 d = dict((k, v) for k, v in self._asdict().iteritems() if v) | 253 d = dict((k, v) for k, v in self._asdict().iteritems() if v) |
| 254 if d['critical']: | 254 if d['critical']: |
| 255 d.pop('critical') | 255 d.pop('critical') |
| 256 return d | 256 return d |
| 257 | 257 |
| 258 | 258 |
| 259 _StepConfig = collections.namedtuple('_StepConfig', | 259 _StepConfig = collections.namedtuple('_StepConfig', |
| 260 ('name', 'base_name', 'cmd', 'cwd', 'env', 'allow_subannotations', | 260 ('name', 'base_name', 'cmd', 'cwd', 'env_prefixes', 'env', |
| 261 'trigger_specs', 'timeout', 'infra_step', 'stdout', 'stderr', 'stdin', | 261 'allow_subannotations', 'trigger_specs', 'timeout', 'infra_step', 'stdout', |
| 262 'ok_ret', 'step_test_data', 'nest_level')) | 262 'stderr', 'stdin', 'ok_ret', 'step_test_data', 'nest_level')) |
| 263 | 263 |
| 264 class StepConfig(_StepConfig): | 264 class StepConfig(_StepConfig): |
| 265 """ | 265 """ |
| 266 StepConfig is the representation of a raw step as the recipe_engine sees it. | 266 StepConfig is the representation of a raw step as the recipe_engine sees it. |
| 267 You should use the standard 'step' recipe module, which will construct and | 267 You should use the standard 'step' recipe module, which will construct and |
| 268 pass this data to the engine for you, instead. The only reason why you would | 268 pass this data to the engine for you, instead. The only reason why you would |
| 269 need to worry about this object is if you're modifying the step module itself. | 269 need to worry about this object is if you're modifying the step module itself. |
| 270 | 270 |
| 271 The optional "env" parameter provides optional overrides for environment | 271 The optional "env" parameter provides optional overrides for environment |
| 272 variables. Each value is % formatted with the entire existing os.environ. A | 272 variables. Each value is % formatted with the entire existing os.environ. A |
| 273 value of `None` will remove that envvar from the environ. e.g. | 273 value of `None` will remove that envvar from the environ. e.g. |
| 274 | 274 |
| 275 { | 275 { |
| 276 "envvar": "%(envvar)s;%(envvar2)s;extra", | 276 "envvar": "%(envvar)s;%(envvar2)s;extra", |
| 277 "delete_this": None, | 277 "delete_this": None, |
| 278 "static_value": "something", | 278 "static_value": "something", |
| 279 } | 279 } |
| 280 |
| 281 The optional "env_prefix" parameter contains values that, if specified, will |
| 282 transform an environment variable into a "pathsep"-delimited sequence of |
| 283 items: |
| 284 - If an environment variable is also specified for this key, it will be |
| 285 appended as the last element: <prefix0>:...:<prefixN>:ENV |
| 286 - If no enviornment variable is specified, the current environment's value |
| 287 will be appended, unless it's empty: <prefix0>:...:<prefixN>[:ENV]? |
| 288 - If an enviornment variable with a value of None (delete) is specified, |
| 289 nothing will be appeneded: <prefix0>:...:<prefixN> |
| 280 """ | 290 """ |
| 281 | 291 |
| 282 _RENDER_WHITELIST=frozenset(( | 292 _RENDER_WHITELIST=frozenset(( |
| 283 'cmd', | 293 'cmd', |
| 284 )) | 294 )) |
| 285 | 295 |
| 286 _RENDER_BLACKLIST=frozenset(( | 296 _RENDER_BLACKLIST=frozenset(( |
| 287 'base_name', | 297 'base_name', |
| 288 'nest_level', | 298 'nest_level', |
| 289 'ok_ret', | 299 'ok_ret', |
| 290 'step_test_data', | 300 'step_test_data', |
| 291 )) | 301 )) |
| 292 | 302 |
| 293 @classmethod | 303 @classmethod |
| 294 def create(cls, name, base_name=None, cmd=None, cwd=None, env=None, | 304 def create(cls, name, base_name=None, cmd=None, cwd=None, env_prefixes=None, |
| 295 allow_subannotations=None, trigger_specs=None, timeout=None, | 305 env=None, allow_subannotations=None, trigger_specs=None, |
| 296 infra_step=None, stdout=None, stderr=None, stdin=None, | 306 timeout=None, infra_step=None, stdout=None, stderr=None, |
| 297 ok_ret=None, step_test_data=None, step_nest_level=None): | 307 stdin=None, ok_ret=None, step_test_data=None, |
| 308 step_nest_level=None): |
| 298 """ | 309 """ |
| 299 Initializes a new StepConfig step API dictionary. | 310 Initializes a new StepConfig step API dictionary. |
| 300 | 311 |
| 301 Args: | 312 Args: |
| 302 name (str): name of the step, will appear in buildbots waterfall | 313 name (str): name of the step, will appear in buildbots waterfall |
| 303 base_name (str): the base name of the step. If the step has a derived | 314 base_name (str): the base name of the step. If the step has a derived |
| 304 name (e.g., nested may be concatenated with its parent), this is the | 315 name (e.g., nested may be concatenated with its parent), this is the |
| 305 name component of just this step. If None, this will be set to "name". | 316 name component of just this step. If None, this will be set to "name". |
| 306 cmd: command to run. Acceptable types: str, Path, Placeholder, or None. | 317 cmd: command to run. Acceptable types: str, Path, Placeholder, or None. |
| 307 cwd (str or None): absolute path to working directory for the command | 318 cwd (str or None): absolute path to working directory for the command |
| 319 env_prefixes (dict): environment prefix variables, described above. |
| 308 env (dict): overrides for environment variables, described above. | 320 env (dict): overrides for environment variables, described above. |
| 309 allow_subannotations (bool): if True, lets the step emit its own | 321 allow_subannotations (bool): if True, lets the step emit its own |
| 310 annotations. NOTE: Enabling this can cause some buggy behavior. Please | 322 annotations. NOTE: Enabling this can cause some buggy behavior. Please |
| 311 strongly consider using step_result.presentation instead. If you have | 323 strongly consider using step_result.presentation instead. If you have |
| 312 questions, please contact infra-dev@chromium.org. | 324 questions, please contact infra-dev@chromium.org. |
| 313 trigger_specs: a list of trigger specifications, see also _trigger_builds. | 325 trigger_specs: a list of trigger specifications, see also _trigger_builds. |
| 314 timeout: if not None, a datetime.timedelta for the step timeout. | 326 timeout: if not None, a datetime.timedelta for the step timeout. |
| 315 infra_step: if True, this is an infrastructure step. Failures will raise | 327 infra_step: if True, this is an infrastructure step. Failures will raise |
| 316 InfraFailure instead of StepFailure. | 328 InfraFailure instead of StepFailure. |
| 317 stdout: Placeholder to put step stdout into. If used, stdout won't appear | 329 stdout: Placeholder to put step stdout into. If used, stdout won't appear |
| 318 in annotator's stdout (and |allow_subannotations| is ignored). | 330 in annotator's stdout (and |allow_subannotations| is ignored). |
| 319 stderr: Placeholder to put step stderr into. If used, stderr won't appear | 331 stderr: Placeholder to put step stderr into. If used, stderr won't appear |
| 320 in annotator's stderr. | 332 in annotator's stderr. |
| 321 stdin: Placeholder to read step stdin from. | 333 stdin: Placeholder to read step stdin from. |
| 322 ok_ret (iter): set of return codes allowed. If the step process returns | 334 ok_ret (iter): set of return codes allowed. If the step process returns |
| 323 something not on this list, it will raise a StepFailure (or | 335 something not on this list, it will raise a StepFailure (or |
| 324 InfraFailure if infra_step is True). If omitted, {0} will be used. | 336 InfraFailure if infra_step is True). If omitted, {0} will be used. |
| 325 step_test_data (func -> recipe_test_api.StepTestData): A factory which | 337 step_test_data (func -> recipe_test_api.StepTestData): A factory which |
| 326 returns a StepTestData object that will be used as the default test | 338 returns a StepTestData object that will be used as the default test |
| 327 data for this step. The recipe author can override/augment this object | 339 data for this step. The recipe author can override/augment this object |
| 328 in the GenTests function. | 340 in the GenTests function. |
| 329 step_nest_level (int): the step's nesting level. | 341 step_nest_level (int): the step's nesting level. |
| 330 """ | 342 """ |
| 331 return cls( | 343 return cls( |
| 332 name=name, | 344 name=name, |
| 333 base_name=(base_name or name), | 345 base_name=(base_name or name), |
| 334 cmd=cmd, | 346 cmd=cmd, |
| 335 cwd=cwd, | 347 cwd=cwd, |
| 336 env=env, | 348 env_prefixes={k: tuple(v) for k, v in (env_prefixes or {}).iteritems()}, |
| 349 env=env or {}, |
| 337 allow_subannotations=bool(allow_subannotations), | 350 allow_subannotations=bool(allow_subannotations), |
| 338 trigger_specs=[TriggerSpec._create(**trig) | 351 trigger_specs=[TriggerSpec._create(**trig) |
| 339 for trig in (trigger_specs or ())], | 352 for trig in (trigger_specs or ())], |
| 340 timeout=timeout, | 353 timeout=timeout, |
| 341 infra_step=bool(infra_step), | 354 infra_step=bool(infra_step), |
| 342 stdout=stdout, | 355 stdout=stdout, |
| 343 stderr=stderr, | 356 stderr=stderr, |
| 344 stdin=stdin, | 357 stdin=stdin, |
| 345 ok_ret=frozenset(ok_ret or (0,)), | 358 ok_ret=frozenset(ok_ret or (0,)), |
| 346 step_test_data=step_test_data, | 359 step_test_data=step_test_data, |
| 347 nest_level=int(step_nest_level or 0), | 360 nest_level=int(step_nest_level or 0), |
| 348 ) | 361 ) |
| 349 | 362 |
| 350 def render_to_dict(self): | 363 def render_to_dict(self): |
| 351 self = self._replace( | 364 self = self._replace( |
| 365 env_prefixes={k: list(v) for k, v in self.env_prefixes.iteritems()}, |
| 352 trigger_specs=[trig._render_to_dict() | 366 trigger_specs=[trig._render_to_dict() |
| 353 for trig in (self.trigger_specs or ())], | 367 for trig in (self.trigger_specs or ())], |
| 354 ) | 368 ) |
| 355 return dict((k, v) for k, v in self._asdict().iteritems() | 369 return dict((k, v) for k, v in self._asdict().iteritems() |
| 356 if (v or k in self._RENDER_WHITELIST) | 370 if (v or k in self._RENDER_WHITELIST) |
| 357 and k not in self._RENDER_BLACKLIST) | 371 and k not in self._RENDER_BLACKLIST) |
| 358 | 372 |
| 359 | 373 |
| 360 class StepFailure(Exception): | 374 class StepFailure(Exception): |
| 361 """ | 375 """ |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 def bind(self, name, property_type, full_decl_name): | 1089 def bind(self, name, property_type, full_decl_name): |
| 1076 """ | 1090 """ |
| 1077 Gets the BoundProperty version of this Property. Requires a name. | 1091 Gets the BoundProperty version of this Property. Requires a name. |
| 1078 """ | 1092 """ |
| 1079 return BoundProperty( | 1093 return BoundProperty( |
| 1080 self._default, self.help, self.kind, name, property_type, full_decl_name, | 1094 self._default, self.help, self.kind, name, property_type, full_decl_name, |
| 1081 self.param_name) | 1095 self.param_name) |
| 1082 | 1096 |
| 1083 class UndefinedPropertyException(TypeError): | 1097 class UndefinedPropertyException(TypeError): |
| 1084 pass | 1098 pass |
| OLD | NEW |