diff --git a/pynt/_pynt.py b/pynt/_pynt.py index d816841..8374fcb 100644 --- a/pynt/_pynt.py +++ b/pynt/_pynt.py @@ -40,12 +40,7 @@ def build(args): sys.exit(0) #load build file as a module - if not path.isfile(args.file): - print("Build file '%s' does not exist. Please specify a build file\n" % args.file) - parser.print_help() - sys.exit(1) - - module = imp.load_source(path.splitext(path.basename(args.file))[0], args.file) + module = _load_buildscript(args.file) # Run task and all its dependencies. if args.list_tasks: @@ -80,6 +75,23 @@ def print_tasks(module, file): task.doc) print(task_list + "\n\n"+_CREDIT_LINE) +def _load_buildscript(file_path): + if not path.isfile(file_path): + print("Build file '%s' does not exist. Please specify a build file\n" % file_path) + parser.print_help() + sys.exit(1) + + script_dir, script_base = path.split(file_path) + + # Append directory of build script to path, to allow importing modules relatively to the script + sys.path.append(path.abspath(script_dir)) + + module_name, suffix = path.splitext(script_base) + description = (suffix, 'r', imp.PY_SOURCE) + + with open(file_path, 'r') as script_file: + return imp.load_module(module_name, script_file, file_path, description) + def _get_default_task(module): matching_tasks = [task for name,task in inspect.getmembers(module,Task.is_task) if name == "__DEFAULT__"] diff --git a/pynt/tests/build_scripts/build_with_local_import.py b/pynt/tests/build_scripts/build_with_local_import.py new file mode 100644 index 0000000..6bfa09d --- /dev/null +++ b/pynt/tests/build_scripts/build_with_local_import.py @@ -0,0 +1,9 @@ +#!/usr/bin/python + +from pynt import task + +from test_module import do_stuff + +@task() +def work(): + do_stuff() \ No newline at end of file diff --git a/pynt/tests/build_scripts/test_module.py b/pynt/tests/build_scripts/test_module.py new file mode 100644 index 0000000..16a3bd8 --- /dev/null +++ b/pynt/tests/build_scripts/test_module.py @@ -0,0 +1,3 @@ + +def do_stuff(): + pass \ No newline at end of file diff --git a/pynt/tests/test_pynt.py b/pynt/tests/test_pynt.py index 195851b..f67cefd 100644 --- a/pynt/tests/test_pynt.py +++ b/pynt/tests/test_pynt.py @@ -17,8 +17,14 @@ def fpath(mod): def simulate_dynamic_module_load(mod): file_path = fpath(mod) - dynamically_loaded_mod = imp.load_source(path.splitext(path.basename(file_path))[0], file_path) - return dynamically_loaded_mod + + #sys.path.append(path.abspath(script_dir)) + + module_name, suffix = path.splitext(path.basename(file_path)) + description = (suffix, 'r', imp.PY_SOURCE) + + with open(file_path, 'r') as scriptfile: + return imp.load_module(module_name, scriptfile, file_path, description) def reset_build_file(mod): mod.tasks_run = [] @@ -296,3 +302,12 @@ def test_invalid_names_for_kwargs(self): build(self._mod, ['copy[bar123=2]']) assert "got an unexpected keyword argument 'bar123'" in str(exc.value) + +class TesttaskLocalImports: + def setup_method(self,method): + from .build_scripts import build_with_local_import + self._mod = build_with_local_import + self._mod.tasks_run = [] + + def test_load_build_with_local_import_does_not_fail(self): + mod = build(self._mod, ["work"])