OLD | NEW |
---|---|
1 # Copyright (c) 2013-2015 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2016 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 """Entry point for fully-annotated builds. | 5 """Entry point for fully-annotated builds. |
6 | 6 |
7 This script is part of the effort to move all builds to annotator-based | 7 This script is part of the effort to move all builds to annotator-based |
8 systems. Any builder configured to use the AnnotatorFactory.BaseFactory() | 8 systems. Any builder configured to use the AnnotatorFactory.BaseFactory() |
9 found in scripts/master/factory/annotator_factory.py executes a single | 9 found in scripts/master/factory/annotator_factory.py executes a single |
10 AddAnnotatedScript step. That step (found in annotator_commands.py) calls | 10 AddAnnotatedScript step. That step (found in annotator_commands.py) calls |
11 this script with the build- and factory-properties passed on the command | 11 this script with the build- and factory-properties passed on the command |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 the current history of what steps have run, what they returned, and any | 57 the current history of what steps have run, what they returned, and any |
58 json data they emitted. Additionally, the OrderedDict has the following | 58 json data they emitted. Additionally, the OrderedDict has the following |
59 convenience functions defined: | 59 convenience functions defined: |
60 * last_step - Returns the last step that ran or None | 60 * last_step - Returns the last step that ran or None |
61 * nth_step(n) - Returns the N'th step that ran or None | 61 * nth_step(n) - Returns the N'th step that ran or None |
62 | 62 |
63 'failed' is a boolean representing if the build is in a 'failed' state. | 63 'failed' is a boolean representing if the build is in a 'failed' state. |
64 """ | 64 """ |
65 | 65 |
66 import collections | 66 import collections |
67 import json | |
67 import os | 68 import os |
68 import sys | 69 import sys |
69 import traceback | 70 import traceback |
70 | 71 |
71 from . import loader | 72 from . import loader |
72 from . import recipe_api | 73 from . import recipe_api |
73 from . import recipe_test_api | 74 from . import recipe_test_api |
74 from . import types | 75 from . import types |
75 from . import util | 76 from . import util |
76 | 77 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
172 'USER', | 173 'USER', |
173 'USERNAME', | 174 'USERNAME', |
174 ]) | 175 ]) |
175 | 176 |
176 | 177 |
177 # Return value of run_steps and RecipeEngine.run. Just a container for the | 178 # Return value of run_steps and RecipeEngine.run. Just a container for the |
178 # literal return value of the recipe. | 179 # literal return value of the recipe. |
179 RecipeResult = collections.namedtuple('RecipeResult', 'result') | 180 RecipeResult = collections.namedtuple('RecipeResult', 'result') |
180 | 181 |
181 | 182 |
182 def run_steps(properties, stream_engine, step_runner, universe): | 183 def run_steps(properties, stream_engine, step_runner, universe_view): |
183 """Runs a recipe (given by the 'recipe' property). | 184 """Runs a recipe (given by the 'recipe' property). |
184 | 185 |
185 Args: | 186 Args: |
186 properties: a dictionary of properties to pass to the recipe. The | 187 properties: a dictionary of properties to pass to the recipe. The |
187 'recipe' property defines which recipe to actually run. | 188 'recipe' property defines which recipe to actually run. |
188 stream_engine: the StreamEngine to use to create individual step streams. | 189 stream_engine: the StreamEngine to use to create individual step streams. |
189 step_runner: The StepRunner to use to 'actually run' the steps. | 190 step_runner: The StepRunner to use to 'actually run' the steps. |
190 universe: The RecipeUniverse to use to load the recipes & modules. | 191 universe_view: The RecipeUniverse to use to load the recipes & modules. |
191 | 192 |
192 Returns: RecipeResult | 193 Returns: RecipeResult |
193 """ | 194 """ |
194 # NOTE(iannucci): 'root' was a terribly bad idea and has been replaced by | 195 # NOTE(iannucci): 'root' was a terribly bad idea and has been replaced by |
195 # 'patch_project'. 'root' had Rietveld knowing about the implementation of | 196 # 'patch_project'. 'root' had Rietveld knowing about the implementation of |
196 # the builders. 'patch_project' lets the builder (recipe) decide its own | 197 # the builders. 'patch_project' lets the builder (recipe) decide its own |
197 # destiny. | 198 # destiny. |
198 properties.pop('root', None) | 199 properties.pop('root', None) |
199 | 200 |
200 # TODO(iannucci): A much better way to do this would be to dynamically | 201 # TODO(iannucci): A much better way to do this would be to dynamically |
201 # detect if the mirrors are actually available during the execution of the | 202 # detect if the mirrors are actually available during the execution of the |
202 # recipe. | 203 # recipe. |
203 if ('use_mirror' not in properties and ( | 204 if ('use_mirror' not in properties and ( |
204 'TESTING_MASTERNAME' in os.environ or | 205 'TESTING_MASTERNAME' in os.environ or |
205 'TESTING_SLAVENAME' in os.environ)): | 206 'TESTING_SLAVENAME' in os.environ)): |
206 properties['use_mirror'] = False | 207 properties['use_mirror'] = False |
207 | 208 |
208 engine = RecipeEngine(step_runner, properties, universe) | 209 engine = RecipeEngine(step_runner, properties, universe_view) |
209 | 210 |
210 # Create all API modules and top level RunSteps function. It doesn't launch | 211 # Create all API modules and top level RunSteps function. It doesn't launch |
211 # any recipe code yet; RunSteps needs to be called. | 212 # any recipe code yet; RunSteps needs to be called. |
212 api = None | 213 api = None |
213 with stream_engine.new_step_stream('setup_build') as s: | 214 with stream_engine.new_step_stream('setup_build') as s: |
214 assert 'recipe' in properties | 215 assert 'recipe' in properties |
215 recipe = properties['recipe'] | 216 recipe = properties['recipe'] |
216 | 217 |
217 properties_to_print = properties.copy() | 218 properties_to_print = properties.copy() |
218 if 'use_mirror' in properties: | 219 if 'use_mirror' in properties: |
219 del properties_to_print['use_mirror'] | 220 del properties_to_print['use_mirror'] |
220 | 221 |
222 root_package = universe_view.universe.package_deps.root_package | |
221 run_recipe_help_lines = [ | 223 run_recipe_help_lines = [ |
222 'To repro this locally, run the following line from a build checkout:', | 224 'To repro this locally, run the following line from a %s checkout:' % ( |
225 root_package.name), | |
223 '', | 226 '', |
224 './scripts/tools/run_recipe.py %s --properties-file - <<EOF' % recipe, | 227 '%s run %s --properties-file - <<EOF' % (os.path.join( |
225 repr(properties_to_print), | 228 '.', root_package.relative_recipes_dir, 'recipes.py'), recipe), |
iannucci
2016/04/14 01:18:28
I think there's a discrepancy between run_recipe a
| |
229 '%s' % json.dumps(properties_to_print), | |
226 'EOF', | 230 'EOF', |
227 '', | 231 '', |
228 'To run on Windows, you can put the JSON in a file and redirect the', | 232 'To run on Windows, you can put the JSON in a file and redirect the', |
229 'contents of the file into run_recipe.py, with the < operator.', | 233 'contents of the file into run_recipe.py, with the < operator.', |
230 ] | 234 ] |
231 | 235 |
232 with s.new_log_stream('run_recipe') as l: | 236 with s.new_log_stream('run_recipe') as l: |
233 for line in run_recipe_help_lines: | 237 for line in run_recipe_help_lines: |
234 l.write_line(line) | 238 l.write_line(line) |
235 | 239 |
236 _isolate_environment() | 240 _isolate_environment() |
237 | 241 |
238 # Find and load the recipe to run. | 242 # Find and load the recipe to run. |
239 try: | 243 try: |
240 recipe_script = universe.load_recipe(recipe) | 244 recipe_script = universe_view.load_recipe(recipe) |
241 s.write_line('Running recipe with %s' % (properties,)) | 245 s.write_line('Running recipe with %s' % (properties,)) |
242 | 246 |
243 api = loader.create_recipe_api(recipe_script.LOADED_DEPS, | 247 api = loader.create_recipe_api(recipe_script.LOADED_DEPS, |
244 engine, | 248 engine, |
245 recipe_test_api.DisabledTestData()) | 249 recipe_test_api.DisabledTestData()) |
246 | 250 |
247 s.add_step_text('<br/>running recipe: "%s"' % recipe) | 251 s.add_step_text('<br/>running recipe: "%s"' % recipe) |
248 except (loader.LoaderError, ImportError, AssertionError) as e: | 252 except (loader.LoaderError, ImportError, AssertionError) as e: |
249 s.add_step_text('<br/>%s' % '<br/>'.join(str(e).splitlines())) | 253 s.add_step_text('<br/>%s' % '<br/>'.join(str(e).splitlines())) |
250 s.set_step_status('EXCEPTION') | 254 s.set_step_status('EXCEPTION') |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
465 results.append( | 469 results.append( |
466 loader._invoke_with_properties( | 470 loader._invoke_with_properties( |
467 run_recipe, properties, recipe_script.PROPERTIES, | 471 run_recipe, properties, recipe_script.PROPERTIES, |
468 properties.keys())) | 472 properties.keys())) |
469 except TypeError as e: | 473 except TypeError as e: |
470 raise TypeError( | 474 raise TypeError( |
471 "Got %r while trying to call recipe %s with properties %r" % ( | 475 "Got %r while trying to call recipe %s with properties %r" % ( |
472 e, recipe, properties)) | 476 e, recipe, properties)) |
473 | 477 |
474 return results | 478 return results |
OLD | NEW |