| 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 imp | 6 import imp |
| 7 import inspect | 7 import inspect |
| 8 import os | 8 import os |
| 9 import sys | 9 import sys |
| 10 | 10 |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 fullname = '%s.%s.%s' % ( | 338 fullname = '%s.%s.%s' % ( |
| 339 RECIPE_MODULE_PREFIX, universe_view.package.name, modname) | 339 RECIPE_MODULE_PREFIX, universe_view.package.name, modname) |
| 340 mod = _find_and_load_module(fullname, modname, path) | 340 mod = _find_and_load_module(fullname, modname, path) |
| 341 | 341 |
| 342 # This actually loads the dependencies. | 342 # This actually loads the dependencies. |
| 343 mod.LOADED_DEPS = universe_view.deps_from_spec(getattr(mod, 'DEPS', [])) | 343 mod.LOADED_DEPS = universe_view.deps_from_spec(getattr(mod, 'DEPS', [])) |
| 344 | 344 |
| 345 # Prevent any modules that mess with sys.path from leaking. | 345 # Prevent any modules that mess with sys.path from leaking. |
| 346 with env.temp_sys_path(): | 346 with env.temp_sys_path(): |
| 347 sys.modules['%s.DEPS' % fullname] = mod.LOADED_DEPS | 347 sys.modules['%s.DEPS' % fullname] = mod.LOADED_DEPS |
| 348 _recursive_import( | 348 _load_recipe_module_files(path, mod, fullname) |
| 349 path, '%s.%s' % (RECIPE_MODULE_PREFIX, universe_view.package.name)) | |
| 350 _patchup_module(modname, mod, universe_view) | 349 _patchup_module(modname, mod, universe_view) |
| 351 | 350 |
| 352 return mod | 351 return mod |
| 353 | 352 |
| 354 | 353 |
| 355 def _recursive_import(path, prefix): | 354 def _load_recipe_module_files(path, mod, prefix): |
| 356 modname = os.path.splitext(os.path.basename(path))[0] | 355 for subitem in os.listdir(path): |
| 357 fullname = '%s.%s' % (prefix, modname) | 356 if subitem in ('api.py', 'test_api.py') or subitem.endswith('config.py'): |
| 358 mod = _find_and_load_module(fullname, modname, path) | 357 subpath = os.path.join(path, subitem) |
| 359 if not os.path.isdir(path): | 358 subname = os.path.splitext(subitem)[0] |
| 360 return mod | 359 fullname = '%s.%s' % (prefix, subname) |
| 360 submod = _find_and_load_module(fullname, subname, subpath) |
| 361 | 361 |
| 362 for subitem in os.listdir(path): | 362 if not hasattr(mod, subname): |
| 363 subpath = os.path.join(path, subitem) | 363 setattr(mod, subname, submod) |
| 364 subname = os.path.splitext(subitem)[0] | 364 else: |
| 365 if os.path.isdir(subpath): | 365 prev = getattr(mod, subname) |
| 366 if not os.path.exists(os.path.join(subpath, '__init__.py')): | 366 assert submod is prev, ( |
| 367 continue | 367 'Conflicting modules: %s and %s' % (prev, mod)) |
| 368 elif not subpath.endswith('.py') or subitem.startswith('__init__.py'): | |
| 369 continue | |
| 370 | |
| 371 submod = _recursive_import(subpath, fullname) | |
| 372 | |
| 373 if not hasattr(mod, subname): | |
| 374 setattr(mod, subname, submod) | |
| 375 else: | |
| 376 prev = getattr(mod, subname) | |
| 377 assert submod is prev, ( | |
| 378 'Conflicting modules: %s and %s' % (prev, mod)) | |
| 379 | |
| 380 return mod | |
| 381 | 368 |
| 382 | 369 |
| 383 def _patchup_module(name, submod, universe_view): | 370 def _patchup_module(name, submod, universe_view): |
| 384 """Finds framework related classes and functions in a |submod| and adds | 371 """Finds framework related classes and functions in a |submod| and adds |
| 385 them to |submod| as top level constants with well known names such as | 372 them to |submod| as top level constants with well known names such as |
| 386 API, CONFIG_CTX, TEST_API, and PROPERTIES. | 373 API, CONFIG_CTX, TEST_API, and PROPERTIES. |
| 387 | 374 |
| 388 |submod| is a recipe module (akin to python package) with submodules such as | 375 |submod| is a recipe module (akin to python package) with submodules such as |
| 389 'api', 'config', 'test_api'. This function scans through dicts of that | 376 'api', 'config', 'test_api'. This function scans through dicts of that |
| 390 submodules to find subclasses of RecipeApi, RecipeTestApi, etc. | 377 submodules to find subclasses of RecipeApi, RecipeTestApi, etc. |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 632 for k,v in toplevel_deps.iteritems(): | 619 for k,v in toplevel_deps.iteritems(): |
| 633 setattr(api, k, mapper.instantiate(v)) | 620 setattr(api, k, mapper.instantiate(v)) |
| 634 return api | 621 return api |
| 635 | 622 |
| 636 | 623 |
| 637 def _resolve_requirement(req, engine): | 624 def _resolve_requirement(req, engine): |
| 638 if req._typ == 'client': | 625 if req._typ == 'client': |
| 639 return engine._get_client(req._name) | 626 return engine._get_client(req._name) |
| 640 else: | 627 else: |
| 641 raise ValueError('Unknown requirement type [%s]' % (req._typ,)) | 628 raise ValueError('Unknown requirement type [%s]' % (req._typ,)) |
| OLD | NEW |