def main(): common_methods = set(k for k, v in member_iter(recipe_api.RecipeApi)) p(0, 'Common Methods -- %s' % os.path.splitext(recipe_api.__file__)[0]) for method in sorted(common_methods): pmethod(1, method, getattr(recipe_api.RecipeApi, method)) RECIPE_MODULES = recipe_loader.load_recipe_modules( recipe_util.MODULE_DIRS()) inst = recipe_loader.create_recipe_api( [mod_name for mod_name, mod in member_iter(RECIPE_MODULES)], annotated_run.SequentialRecipeEngine(None, {}, None)) for mod_name, mod in member_iter(RECIPE_MODULES): p(0) p(0, "(%s) -- %s" % (mod_name, mod.__path__[0])) if mod.DEPS: p(1, 'DEPS:', list(mod.DEPS)) subinst = getattr(inst, mod_name) bases = set(subinst.__class__.__bases__) base_fns = set() for base in bases: for name, _ in inspect.getmembers(base): base_fns.add(name) for cool_base in bases - set((recipe_api.RecipeApi, )): p(1, 'behaves like %s' % map_to_cool_name(cool_base)) if mod.API.__doc__: for line in trim_doc(mod.API.__doc__): p(2, '"', line) for fn_name, obj in member_iter(subinst): if fn_name in base_fns: continue pmethod(1, fn_name, obj)
def main(): common_methods = set(k for k, v in member_iter(recipe_api.RecipeApi)) p(0, 'Common Methods -- %s' % os.path.splitext(recipe_api.__file__)[0]) for method in sorted(common_methods): pmethod(1, method, getattr(recipe_api.RecipeApi, method)) RECIPE_MODULES = recipe_loader.load_recipe_modules(recipe_util.MODULE_DIRS()) inst = recipe_loader.create_recipe_api( [ mod_name for mod_name, mod in member_iter(RECIPE_MODULES) ], annotated_run.SequentialRecipeEngine(None, {}, None)) for mod_name, mod in member_iter(RECIPE_MODULES): p(0) p(0, "(%s) -- %s" % (mod_name, mod.__path__[0])) if mod.DEPS: p(1, 'DEPS:', list(mod.DEPS)) subinst = getattr(inst, mod_name) bases = set(subinst.__class__.__bases__) base_fns = set() for base in bases: for name, _ in inspect.getmembers(base): base_fns.add(name) for cool_base in bases - set((recipe_api.RecipeApi,)): p(1, 'behaves like %s' % map_to_cool_name(cool_base)) if mod.API.__doc__: for line in trim_doc(mod.API.__doc__): p(2, '"', line) for fn_name, obj in member_iter(subinst): if fn_name in base_fns: continue pmethod(1, fn_name, obj)
def run_steps(stream, build_properties, factory_properties, test_data=recipe_test_api.DisabledTestData()): """Returns a tuple of (status_code, steps_ran). Only one of these values will be set at a time. This is mainly to support the testing interface used by unittests/recipes_test.py. """ stream.honor_zero_return_code() # TODO(iannucci): Stop this when blamelist becomes sane data. if ('blamelist_real' in build_properties and 'blamelist' in build_properties): build_properties['blamelist'] = build_properties['blamelist_real'] del build_properties['blamelist_real'] properties = factory_properties.copy() properties.update(build_properties) # TODO(iannucci): A much better way to do this would be to dynamically # detect if the mirrors are actually available during the execution of the # recipe. if ('use_mirror' not in properties and ('TESTING_MASTERNAME' in os.environ or 'TESTING_SLAVENAME' in os.environ)): properties['use_mirror'] = False # It's an integration point with a new recipe engine that can run steps # in parallel (that is not implemented yet). Use new engine only if explicitly # asked by setting 'engine' property to 'ParallelRecipeEngine'. engine = RecipeEngine.create(stream, properties, test_data) # Create all API modules and an instance of top level GenSteps generator. # It doesn't launch any recipe code yet (generator needs to be iterated upon # to start executing code). with stream.step('setup_build') as s: assert 'recipe' in factory_properties recipe = factory_properties['recipe'] try: recipe_module = recipe_loader.load_recipe(recipe) stream.emit('Running recipe with %s' % (properties, )) api = recipe_loader.create_recipe_api(recipe_module.DEPS, engine, test_data) steps = recipe_module.GenSteps(api) assert inspect.isgenerator(steps) s.step_text('<br/>running recipe: "%s"' % recipe) except recipe_loader.NoSuchRecipe as e: s.step_text('<br/>recipe not found: %s' % e) s.step_failure() return RecipeExecutionResult(2, None) try: # Run the steps emitted by a recipe via the engine, emitting annotations # into |stream| along the way. return engine.run(steps) except BaseException: return engine.unhandled_exception()
def run_steps(stream, build_properties, factory_properties, test_data=recipe_test_api.DisabledTestData()): """Returns a tuple of (status_code, steps_ran). Only one of these values will be set at a time. This is mainly to support the testing interface used by unittests/recipes_test.py. """ stream.honor_zero_return_code() # TODO(iannucci): Stop this when blamelist becomes sane data. if ('blamelist_real' in build_properties and 'blamelist' in build_properties): build_properties['blamelist'] = build_properties['blamelist_real'] del build_properties['blamelist_real'] properties = factory_properties.copy() properties.update(build_properties) # TODO(iannucci): A much better way to do this would be to dynamically # detect if the mirrors are actually available during the execution of the # recipe. if ('use_mirror' not in properties and ( 'TESTING_MASTERNAME' in os.environ or 'TESTING_SLAVENAME' in os.environ)): properties['use_mirror'] = False # It's an integration point with a new recipe engine that can run steps # in parallel (that is not implemented yet). Use new engine only if explicitly # asked by setting 'engine' property to 'ParallelRecipeEngine'. engine = RecipeEngine.create(stream, properties, test_data) # Create all API modules and an instance of top level GenSteps generator. # It doesn't launch any recipe code yet (generator needs to be iterated upon # to start executing code). with stream.step('setup_build') as s: assert 'recipe' in factory_properties recipe = factory_properties['recipe'] try: recipe_module = recipe_loader.load_recipe(recipe) stream.emit('Running recipe with %s' % (properties,)) api = recipe_loader.create_recipe_api(recipe_module.DEPS, engine, test_data) steps = recipe_module.GenSteps(api) assert inspect.isgenerator(steps) s.step_text('<br/>running recipe: "%s"' % recipe) except recipe_loader.NoSuchRecipe as e: s.step_text('<br/>recipe not found: %s' % e) s.step_failure() return RecipeExecutionResult(2, None) try: # Run the steps emitted by a recipe via the engine, emitting annotations # into |stream| along the way. return engine.run(steps) except BaseException: return engine.unhandled_exception()
def run_steps(stream, build_properties, factory_properties, test_data=recipe_test_api.DisabledTestData()): """Returns a tuple of (status_code, steps_ran). Only one of these values will be set at a time. This is mainly to support the testing interface used by unittests/recipes_test.py. """ stream.honor_zero_return_code() # TODO(iannucci): Stop this when blamelist becomes sane data. if ('blamelist_real' in build_properties and 'blamelist' in build_properties): build_properties['blamelist'] = build_properties['blamelist_real'] del build_properties['blamelist_real'] properties = factory_properties.copy() properties.update(build_properties) # TODO(iannucci): A much better way to do this would be to dynamically # detect if the mirrors are actually available during the execution of the # recipe. if ('use_mirror' not in properties and ('TESTING_MASTERNAME' in os.environ or 'TESTING_SLAVENAME' in os.environ)): properties['use_mirror'] = False # It's an integration point with a new recipe engine that can run steps # in parallel (that is not implemented yet). Use new engine only if explicitly # asked by setting 'engine' property to 'ParallelRecipeEngine'. engine = RecipeEngine.create(stream, properties, test_data) # Create all API modules and an instance of top level GenSteps generator. # It doesn't launch any recipe code yet (generator needs to be iterated upon # to start executing code). api = None with stream.step('setup_build') as s: assert 'recipe' in factory_properties recipe = factory_properties['recipe'] properties_to_print = properties.copy() if 'use_mirror' in properties: del properties_to_print['use_mirror'] run_recipe_help_lines = [ 'To repro this locally, run the following line from a build checkout:', '', './scripts/tools/run_recipe.py %s --properties-file - <<EOF' % recipe, repr(properties_to_print), 'EOF', '', 'To run on Windows, you can put the JSON in a file and redirect the', 'contents of the file into run_recipe.py, with the < operator.', ] for line in run_recipe_help_lines: s.step_log_line('run_recipe', line) s.step_log_end('run_recipe') try: recipe_module = recipe_loader.load_recipe(recipe) stream.emit('Running recipe with %s' % (properties, )) api = recipe_loader.create_recipe_api(recipe_module.DEPS, engine, test_data) steps = recipe_module.GenSteps s.step_text('<br/>running recipe: "%s"' % recipe) except recipe_loader.NoSuchRecipe as e: s.step_text('<br/>recipe not found: %s' % e) s.step_failure() return RecipeExecutionResult(2, None) # Run the steps emitted by a recipe via the engine, emitting annotations # into |stream| along the way. return engine.run(steps, api)