From d6b77adc031eafa8cc1cb55180071c539bcd886f Mon Sep 17 00:00:00 2001 From: Zanie Date: Mon, 15 Jan 2024 13:09:48 -0600 Subject: [PATCH] Add support for `backend-path` --- scripts/hookd/example.in | 1 + scripts/hookd/hookd.py | 43 +++- scripts/hookd/tests/test_hookd.py | 228 ++++++++++++++---- scripts/hookd/tests/tree/__init__.py | 3 + .../tests/tree/in_tree_backend/in_tree.py | 23 ++ 5 files changed, 247 insertions(+), 51 deletions(-) create mode 100644 scripts/hookd/tests/tree/__init__.py create mode 100644 scripts/hookd/tests/tree/in_tree_backend/in_tree.py diff --git a/scripts/hookd/example.in b/scripts/hookd/example.in index d6f64da5b..85d89dbe1 100644 --- a/scripts/hookd/example.in +++ b/scripts/hookd/example.in @@ -1,5 +1,6 @@ run ok_backend + build_wheel foo diff --git a/scripts/hookd/hookd.py b/scripts/hookd/hookd.py index ab87ee31a..3ec07a3a1 100755 --- a/scripts/hookd/hookd.py +++ b/scripts/hookd/hookd.py @@ -76,6 +76,9 @@ def run_once(stdin: TextIO, stdout: TextIO): send_expect(stdout, "build_backend") build_backend_name = parse_build_backend(stdin) + send_expect(stdout, "backend_path") + backend_path = parse_backend_path(stdin) + send_expect(stdout, "hook_name") hook_name = parse_hook_name(stdin) if hook_name not in HookArguments: @@ -105,13 +108,14 @@ def run_once(stdin: TextIO, stdout: TextIO): # TODO(zanieb): Where do we get the path of the source tree? with ExitStack() as hook_ctx: + hook_ctx.enter_context(update_sys_path(backend_path)) hook_stdout = hook_ctx.enter_context(redirect_sys_stream("stdout")) hook_stderr = hook_ctx.enter_context(redirect_sys_stream("stderr")) send_redirect(stdout, "stdout", str(hook_stdout)) send_redirect(stdout, "stderr", str(hook_stderr)) try: - build_backend = import_build_backend(build_backend_name) + build_backend = import_build_backend(build_backend_name, backend_path) except Exception as exc: if not isinstance(exc, HookdError): # Wrap unhandled errors in a generic one @@ -136,7 +140,7 @@ def run_once(stdin: TextIO, stdout: TextIO): @cache() -def import_build_backend(backend_name: str) -> object: +def import_build_backend(backend_name: str, backend_path: tuple[str]) -> object: """ See: https://peps.python.org/pep-0517/#source-trees """ @@ -190,6 +194,24 @@ def import_build_backend(backend_name: str) -> object: return backend +@contextmanager +def update_sys_path(extensions: tuple[Path]): + """ + Temporarily update `sys.path`. + + WARNING: This function is not safe to concurrent usage. + """ + if not extensions: + yield + return + + previous_path = sys.path.copy() + + sys.path = list(extensions) + sys.path + yield + sys.path = previous_path + + @contextmanager def redirect_sys_stream(name: StreamName): """ @@ -294,7 +316,6 @@ def parse_hook_name(buffer: TextIO) -> Hook: def parse_path(buffer: TextIO) -> Path: path = os.path.abspath(buffer.readline().rstrip("\n")) - # TODO(zanieb): Consider validating the path here return path @@ -327,7 +348,6 @@ def parse_config_settings(buffer: TextIO) -> dict | None: def parse_build_backend(buffer: TextIO) -> str: - # TODO: Add support for `build-path` name = buffer.readline().rstrip("\n") if not name: @@ -337,6 +357,21 @@ def parse_build_backend(buffer: TextIO) -> str: return name +def parse_backend_path(buffer: TextIO) -> tuple[Path]: + """ + Directories in backend-path are interpreted as relative to the project root, and MUST refer to a location within the source tree (after relative paths and symbolic links have been resolved). + The backend code MUST be loaded from one of the directories specified in backend-path (i.e., it is not permitted to specify backend-path and not have in-tree backend code). + """ + paths = [] + + while True: + path = parse_optional_path(buffer) + if not path: + return tuple(paths) + + paths.append(path) + + ###################### ####### OUTPUT ####### ###################### diff --git a/scripts/hookd/tests/test_hookd.py b/scripts/hookd/tests/test_hookd.py index 36e6fd9bc..f32bf8720 100644 --- a/scripts/hookd/tests/test_hookd.py +++ b/scripts/hookd/tests/test_hookd.py @@ -11,12 +11,14 @@ from pathlib import Path import pytest PROJECT_DIR = Path(__file__).parent.parent +TREE_DIR = PROJECT_DIR / "tests" / "tree" # Snapshot filters TIME = (r"(\d+.)?\d+(ms|s)", "[TIME]") SHUTDOWN = ( textwrap.dedent( """ + DEBUG changed working directory to [TREE] READY EXPECT action SHUTDOWN @@ -26,12 +28,17 @@ SHUTDOWN = ( ) STDOUT = ("STDOUT .*", "STDOUT [PATH]") STDERR = ("STDERR .*", "STDERR [PATH]") + +TREE = (re.escape(str(TREE_DIR)), "[TREE]") CWD = (re.escape(os.getcwd()), "[CWD]") TRACEBACK = ("TRACEBACK .*", "TRACEBACK [TRACEBACK]") -DEFAULT_FILTERS = [TIME, STDOUT, STDERR, TRACEBACK, CWD] +DEFAULT_FILTERS = [TIME, STDOUT, STDERR, TRACEBACK, TREE, CWD] -def new(extra_backend_paths: list[str] | None = None) -> subprocess.Popen: +def new( + extra_backend_paths: list[str] | None = None, + tree_path: Path | None = TREE_DIR, +) -> subprocess.Popen: extra_backend_paths = extra_backend_paths or [] env = os.environ.copy() @@ -41,7 +48,8 @@ def new(extra_backend_paths: list[str] | None = None) -> subprocess.Popen: ) return subprocess.Popen( - [sys.executable, str(PROJECT_DIR / "hookd.py")], + [sys.executable, str(PROJECT_DIR / "hookd.py")] + + ([str(tree_path)] if tree_path is not None else []), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -84,19 +92,32 @@ def test_sigterm(): def test_run_invalid_backend(): daemon = new() - send(daemon, ["run", "backend_does_not_exist", "build_wheel", "", "", ""]) + send( + daemon, + [ + "run", + "backend_does_not_exist", + "", + "build_wheel", + "", + "", + "", + ], + ) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG backend_does_not_exist build_wheel wheel_directory=[CWD] config_settings=None metadata_directory=None + DEBUG backend_does_not_exist build_wheel wheel_directory=[TREE] config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -114,14 +135,16 @@ def test_run_invalid_backend(): def test_run_invalid_hook(): daemon = new() - send(daemon, ["run", "ok_backend", "hook_does_not_exist"]) + send(daemon, ["run", "ok_backend", "", "hook_does_not_exist"]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name ERROR InvalidHookName The name 'hook_does_not_exist' is not valid hook. Expected one of: 'build_wheel', 'build_sdist', 'prepare_metadata_for_build_wheel', 'get_requires_for_build_wheel', 'get_requires_for_build_sdist' TRACEBACK [TRACEBACK] @@ -140,19 +163,21 @@ def test_run_build_wheel_ok(): Uses a mock backend to test the `build_wheel` hook. """ daemon = new() - send(daemon, ["run", "ok_backend", "build_wheel", "foo", "", ""]) + send(daemon, ["run", "ok_backend", "", "build_wheel", "foo", "", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG ok_backend build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG ok_backend build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -173,18 +198,20 @@ def test_run_build_sdist_ok(): Uses a mock backend to test the `build_sdist` hook. """ daemon = new() - send(daemon, ["run", "ok_backend", "build_sdist", "foo", ""]) + send(daemon, ["run", "ok_backend", "", "build_sdist", "foo", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT sdist_directory EXPECT config_settings - DEBUG ok_backend build_sdist sdist_directory=[CWD]/foo config_settings=None + DEBUG ok_backend build_sdist sdist_directory=[TREE]/foo config_settings=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -205,14 +232,16 @@ def test_run_get_requires_for_build_wheel_ok(): Uses a mock backend to test the `get_requires_for_build_wheel` hook. """ daemon = new() - send(daemon, ["run", "ok_backend", "get_requires_for_build_wheel", ""]) + send(daemon, ["run", "ok_backend", "", "get_requires_for_build_wheel", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT config_settings DEBUG ok_backend get_requires_for_build_wheel config_settings=None @@ -236,18 +265,22 @@ def test_run_prepare_metadata_for_build_wheel_ok(): Uses a mock backend to test the `prepare_metadata_for_build_wheel` hook. """ daemon = new() - send(daemon, ["run", "ok_backend", "prepare_metadata_for_build_wheel", "foo", ""]) + send( + daemon, ["run", "ok_backend", "", "prepare_metadata_for_build_wheel", "foo", ""] + ) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT metadata_directory EXPECT config_settings - DEBUG ok_backend prepare_metadata_for_build_wheel metadata_directory=[CWD]/foo config_settings=None + DEBUG ok_backend prepare_metadata_for_build_wheel metadata_directory=[TREE]/foo config_settings=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -269,15 +302,18 @@ def test_run_invalid_config_settings(): """ daemon = new() send( - daemon, ["run", "ok_backend", "get_requires_for_build_wheel", "not_valid_json"] + daemon, + ["run", "ok_backend", "", "get_requires_for_build_wheel", "not_valid_json"], ) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT config_settings ERROR MalformedHookArgument Malformed content for argument 'config_settings': 'not_valid_json' @@ -298,19 +334,23 @@ def test_run_build_wheel_multiple_times(): """ daemon = new() for _ in range(5): - send(daemon, ["run", "ok_backend", "build_wheel", "foo", "", ""]) + send(daemon, ["run", "ok_backend", "", "build_wheel", "foo", "", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] + """.rstrip() + + """ READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG ok_backend build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG ok_backend build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -333,19 +373,21 @@ def test_run_build_wheel_error(): Uses a mock backend that throws an error to test error reporting. """ daemon = new() - send(daemon, ["run", "err_backend", "build_wheel", "foo", "", ""]) + send(daemon, ["run", "err_backend", "", "build_wheel", "foo", "", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG err_backend build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG err_backend build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -366,20 +408,22 @@ def test_run_error_not_fatal(): Uses a mock backend that throws an error to ensure errors are not fatal and another hook can be run. """ daemon = new() - send(daemon, ["run", "err_backend", "build_wheel", "foo", "", ""]) - send(daemon, ["run", "err_backend", "build_wheel", "foo", "", ""]) + send(daemon, ["run", "err_backend", "", "build_wheel", "foo", "", ""]) + send(daemon, ["run", "err_backend", "", "build_wheel", "foo", "", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG err_backend build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG err_backend build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -388,11 +432,12 @@ def test_run_error_not_fatal(): READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG err_backend build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG err_backend build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -422,20 +467,22 @@ def test_run_base_exception_error_not_fatal(tmp_path: Path): ) daemon = new(extra_backend_paths=[tmp_path]) - send(daemon, ["run", "base_exc_backend", "build_wheel", "foo", "", ""]) - send(daemon, ["run", "base_exc_backend", "build_wheel", "foo", "", ""]) + send(daemon, ["run", "base_exc_backend", "", "build_wheel", "foo", "", ""]) + send(daemon, ["run", "base_exc_backend", "", "build_wheel", "foo", "", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG base_exc_backend build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG base_exc_backend build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -444,11 +491,12 @@ def test_run_base_exception_error_not_fatal(tmp_path: Path): READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG base_exc_backend build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG base_exc_backend build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -470,19 +518,21 @@ def test_run_error_in_backend_module(tmp_path: Path): """ (tmp_path / "import_err_backend.py").write_text("raise RuntimeError('oh no')") daemon = new(extra_backend_paths=[tmp_path]) - send(daemon, ["run", "import_err_backend", "build_wheel", "foo", "", ""]) + send(daemon, ["run", "import_err_backend", "", "build_wheel", "foo", "", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG import_err_backend build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG import_err_backend build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -504,19 +554,21 @@ def test_run_unsupported_hook_empty(tmp_path: Path): """ (tmp_path / "empty_backend.py").write_text("") daemon = new(extra_backend_paths=[tmp_path]) - send(daemon, ["run", "empty_backend", "build_wheel", "foo", "", ""]) + send(daemon, ["run", "empty_backend", "", "build_wheel", "foo", "", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG empty_backend build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG empty_backend build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -549,18 +601,20 @@ def test_run_unsupported_hook_partial(tmp_path: Path): ) daemon = new(extra_backend_paths=[tmp_path]) - send(daemon, ["run", "partial_backend", "build_sdist", "foo", "", ""]) + send(daemon, ["run", "partial_backend", "", "build_sdist", "foo", "", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT sdist_directory EXPECT config_settings - DEBUG partial_backend build_sdist sdist_directory=[CWD]/foo config_settings=None + DEBUG partial_backend build_sdist sdist_directory=[TREE]/foo config_settings=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -586,19 +640,24 @@ def test_run_cls_backend(separator): Tests a backend namespaced to a class. """ daemon = new() - send(daemon, ["run", f"cls_backend{separator}Class", "build_wheel", "foo", "", ""]) + send( + daemon, + ["run", f"cls_backend{separator}Class", "", "build_wheel", "foo", "", ""], + ) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, f""" + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG cls_backend{separator}Class build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG cls_backend{separator}Class build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -620,19 +679,71 @@ def test_run_obj_backend(separator): Tests a backend namespaced to an object. """ daemon = new() - send(daemon, ["run", f"obj_backend{separator}obj", "build_wheel", "foo", "", ""]) + send( + daemon, ["run", f"obj_backend{separator}obj", "", "build_wheel", "foo", "", ""] + ) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, f""" + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG obj_backend{separator}obj build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG obj_backend{separator}obj build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None + DEBUG parsed hook inputs in [TIME] + STDOUT [PATH] + STDERR [PATH] + OK build_wheel_fake_path + DEBUG ran hook in [TIME] + READY + EXPECT action + SHUTDOWN + """, + filters=DEFAULT_FILTERS, + ) + assert stderr == "" + assert daemon.returncode == 0 + + +def test_run_in_tree_backend(): + """ + Tests a backend in the source tree + """ + daemon = new() + send( + daemon, + [ + "run", + "in_tree", + "directory_does_not_exist", + "in_tree_backend", + "", + "build_wheel", + "foo", + "", + "", + ], + ) + stdout, stderr = daemon.communicate(input="shutdown\n") + assert_snapshot( + stdout, + """ + DEBUG changed working directory to [TREE] + READY + EXPECT action + EXPECT build_backend + EXPECT backend_path + EXPECT hook_name + EXPECT wheel_directory + EXPECT config_settings + EXPECT metadata_directory + DEBUG in_tree build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -653,19 +764,23 @@ def test_run_submodule_backend(): Tests a backend namespaced to an submodule. """ daemon = new() - send(daemon, ["run", "submodule_backend.submodule", "build_wheel", "foo", "", ""]) + send( + daemon, ["run", "submodule_backend.submodule", "", "build_wheel", "foo", "", ""] + ) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG submodule_backend.submodule build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG submodule_backend.submodule build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -686,19 +801,32 @@ def test_run_submodule_backend_invalid_import(): Tests a backend namespaced to an submodule but imported as an attribute """ daemon = new() - send(daemon, ["run", "submodule_backend:submodule", "build_wheel", "", "", ""]) + send( + daemon, + [ + "run", + "submodule_backend:submodule", + "", + "build_wheel", + "", + "", + "", + ], + ) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG submodule_backend:submodule build_wheel wheel_directory=[CWD] config_settings=None metadata_directory=None + DEBUG submodule_backend:submodule build_wheel wheel_directory=[TREE] config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -719,19 +847,21 @@ def test_run_stdout_capture(): Tests capture of stdout from a backend. """ daemon = new() - send(daemon, ["run", "stdout_backend", "build_wheel", "foo", "", ""]) + send(daemon, ["run", "stdout_backend", "", "build_wheel", "foo", "", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG stdout_backend build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG stdout_backend build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -772,19 +902,21 @@ def test_run_stderr_capture(): Tests capture of stderr from a backend. """ daemon = new() - send(daemon, ["run", "stderr_backend", "build_wheel", "foo", "", ""]) + send(daemon, ["run", "stderr_backend", "", "build_wheel", "foo", "", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, """ + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG stderr_backend build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG stderr_backend build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] @@ -828,7 +960,7 @@ def test_run_stdout_capture_multiple_hook_runs(): for i in range(COUNT): send( daemon, - ["run", "stdout_backend", "build_wheel", "foo", f'{{"run": {i}}}', ""], + ["run", "stdout_backend", "", "build_wheel", "foo", f'{{"run": {i}}}', ""], ) stdout, stderr = daemon.communicate(input="shutdown\n") print(stdout) @@ -873,19 +1005,21 @@ def test_run_real_backend_build_wheel_error(backend: str): pytest.skip(f"build backend {backend!r} is not installed") daemon = new() - send(daemon, ["run", backend, "build_wheel", "foo", "", ""]) + send(daemon, ["run", backend, "", "build_wheel", "foo", "", ""]) stdout, stderr = daemon.communicate(input="shutdown\n") assert_snapshot( stdout, f""" + DEBUG changed working directory to [TREE] READY EXPECT action EXPECT build_backend + EXPECT backend_path EXPECT hook_name EXPECT wheel_directory EXPECT config_settings EXPECT metadata_directory - DEBUG {backend} build_wheel wheel_directory=[CWD]/foo config_settings=None metadata_directory=None + DEBUG {backend} build_wheel wheel_directory=[TREE]/foo config_settings=None metadata_directory=None DEBUG parsed hook inputs in [TIME] STDOUT [PATH] STDERR [PATH] diff --git a/scripts/hookd/tests/tree/__init__.py b/scripts/hookd/tests/tree/__init__.py new file mode 100644 index 000000000..08ce7cb02 --- /dev/null +++ b/scripts/hookd/tests/tree/__init__.py @@ -0,0 +1,3 @@ +""" +A test Python project +""" diff --git a/scripts/hookd/tests/tree/in_tree_backend/in_tree.py b/scripts/hookd/tests/tree/in_tree_backend/in_tree.py new file mode 100644 index 000000000..31e6e4711 --- /dev/null +++ b/scripts/hookd/tests/tree/in_tree_backend/in_tree.py @@ -0,0 +1,23 @@ +""" +A build backend in a sub-directory in-tree +""" + + +def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): + return "build_wheel_fake_path" + + +def build_sdist(sdist_directory, config_settings=None): + return "build_sdist_fake_path" + + +def get_requires_for_build_wheel(config_settings=None): + return ["fake", "build", "wheel", "requires"] + + +def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None): + return "prepare_metadata_fake_dist_info_path" + + +def get_requires_for_build_sdist(config_settings=None): + return ["fake", "build", "sdist", "requires"]