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 |