Chromium Code Reviews| 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 import collections | 5 import collections |
| 6 import contextlib | 6 import contextlib |
| 7 import imp | 7 import imp |
| 8 import inspect | 8 import inspect |
| 9 import os | 9 import os |
| 10 import sys | 10 import sys |
| (...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 # Replace class-level Requirements placeholders in the recipe API with | 576 # Replace class-level Requirements placeholders in the recipe API with |
| 577 # their instance-level real values. | 577 # their instance-level real values. |
| 578 map(lambda (k, v): setattr(mod_api, k, _resolve_requirement(v, engine)), | 578 map(lambda (k, v): setattr(mod_api, k, _resolve_requirement(v, engine)), |
| 579 ((k, v) for k, v in type(mod_api).__dict__.iteritems() | 579 ((k, v) for k, v in type(mod_api).__dict__.iteritems() |
| 580 if isinstance(v, _UnresolvedRequirement))) | 580 if isinstance(v, _UnresolvedRequirement))) |
| 581 | 581 |
| 582 mod_api.initialize() | 582 mod_api.initialize() |
| 583 return mod_api | 583 return mod_api |
| 584 | 584 |
| 585 mapper = DependencyMapper(instantiator) | 585 mapper = DependencyMapper(instantiator) |
| 586 # Provide a fake module to the ScriptApi so that recipes can use: | 586 # Provide a fake module to the ScriptApi so that recipes can use: |
|
martiniss
2017/02/02 21:12:18
should this comment be moved? It doesn't seem to a
iannucci
2017/02/02 22:29:13
no, it still applies; this whole section is in ord
| |
| 587 # * .name | 587 # * .name |
| 588 # * .resource | 588 # * .resource |
| 589 # * .package_repo_resource | 589 # * .package_repo_resource |
| 590 # This is obviously a hack, however it homogenizes the api and removes the | 590 # This is obviously a hack, however it homogenizes the api and removes the |
| 591 # need for some ugly workarounds in user code. A better way to do this would | 591 # need for some ugly workarounds in user code. A better way to do this would |
| 592 # be to migrate all recipes to be members of modules. | 592 # be to migrate all recipes to be members of modules. |
| 593 name = os.path.join( | 593 is_module = recipe_script_path.startswith(toplevel_package.module_dirs[0]) |
| 594 toplevel_package.name, | 594 rel_to = toplevel_package.recipe_dirs[0] |
|
martiniss
2017/02/02 21:12:18
I don't like all the [0] we have everywhere with m
iannucci
2017/02/02 22:29:13
agree. I'll take a stab at cleaning this up in a s
| |
| 595 os.path.relpath( | 595 if is_module: |
| 596 os.path.splitext(recipe_script_path)[0], | 596 rel_to = toplevel_package.module_dirs[0] |
| 597 toplevel_package.recipe_dirs[0])) | 597 rel_path = os.path.relpath(os.path.splitext(recipe_script_path)[0], rel_to) |
| 598 if is_module: | |
| 599 mod_name, recipe = rel_path.split(os.path.sep, 1) | |
| 600 rel_path = "%s:%s" % (mod_name, recipe) | |
| 601 name = "%s::%s" % (toplevel_package.name, rel_path) | |
| 598 fakeModule = collections.namedtuple( | 602 fakeModule = collections.namedtuple( |
| 599 "fakeModule", "PACKAGE_REPO_ROOT NAME RESOURCE_DIRECTORY")( | 603 "fakeModule", "PACKAGE_REPO_ROOT NAME RESOURCE_DIRECTORY")( |
| 600 Path(PackageRepoBasePath(toplevel_package)), | 604 Path(PackageRepoBasePath(toplevel_package)), |
| 601 name, | 605 name, |
| 602 Path(RecipeScriptBasePath( | 606 Path(RecipeScriptBasePath( |
| 603 name, os.path.splitext(recipe_script_path)[0]+".resources"))) | 607 name, os.path.splitext(recipe_script_path)[0]+".resources"))) |
| 604 api = RecipeScriptApi(module=fakeModule, engine=engine, | 608 api = RecipeScriptApi(module=fakeModule, engine=engine, |
| 605 test_data=test_data.get_module_test_data(None)) | 609 test_data=test_data.get_module_test_data(None)) |
| 606 for k, v in toplevel_deps.iteritems(): | 610 for k, v in toplevel_deps.iteritems(): |
| 607 setattr(api, k, mapper.instantiate(v)) | 611 setattr(api, k, mapper.instantiate(v)) |
| 612 | |
| 613 # Always instantiate the path module at least once so that string functions on | |
| 614 # Path objects work. This extra load doesn't actually attach the loaded path | |
| 615 # module to the api return, so if recipes want to use the path module, they | |
| 616 # still need to import it. If the recipe already loaded the path module | |
| 617 # (somewhere, could be transitively), then this extra load is a no-op. | |
| 618 # TODO(iannucci): The way paths work need to be reimplemented sanely :/ | |
| 619 path_spec = engine._universe_view.deps_from_spec(['recipe_engine/path']) | |
| 620 mapper.instantiate(path_spec['path']) | |
| 621 | |
| 608 return api | 622 return api |
| 609 | 623 |
| 610 | 624 |
| 611 def create_test_api(toplevel_deps, universe): | 625 def create_test_api(toplevel_deps, universe): |
| 612 def instantiator(mod, deps): | 626 def instantiator(mod, deps): |
| 613 modapi = (getattr(mod, 'TEST_API', None) or RecipeTestApi)(module=mod) | 627 modapi = (getattr(mod, 'TEST_API', None) or RecipeTestApi)(module=mod) |
| 614 for k,v in deps.iteritems(): | 628 for k,v in deps.iteritems(): |
| 615 setattr(modapi.m, k, v) | 629 setattr(modapi.m, k, v) |
| 616 return modapi | 630 return modapi |
| 617 | 631 |
| 618 mapper = DependencyMapper(instantiator) | 632 mapper = DependencyMapper(instantiator) |
| 619 api = RecipeTestApi(module=None) | 633 api = RecipeTestApi(module=None) |
| 620 for k,v in toplevel_deps.iteritems(): | 634 for k,v in toplevel_deps.iteritems(): |
| 621 setattr(api, k, mapper.instantiate(v)) | 635 setattr(api, k, mapper.instantiate(v)) |
| 622 return api | 636 return api |
| 623 | 637 |
| 624 | 638 |
| 625 def _resolve_requirement(req, engine): | 639 def _resolve_requirement(req, engine): |
| 626 if req._typ == 'client': | 640 if req._typ == 'client': |
| 627 return engine._get_client(req._name) | 641 return engine._get_client(req._name) |
| 628 else: | 642 else: |
| 629 raise ValueError('Unknown requirement type [%s]' % (req._typ,)) | 643 raise ValueError('Unknown requirement type [%s]' % (req._typ,)) |
| OLD | NEW |