From 6274e6decc08f778de5bf96a199cc61271eb1bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oto=20=C5=A0=C5=A5=C3=A1va?= Date: Mon, 7 Aug 2023 11:37:38 +0200 Subject: [PATCH] Add POE_PWD for original working directory and allow use of env vars for cwd --- poethepoet/context.py | 11 ++-- poethepoet/env/manager.py | 4 ++ tests/conftest.py | 1 + tests/fixtures/cwd_project/pyproject.toml | 8 +++ tests/fixtures/cwd_project/subdir/bar/baz.txt | 0 .../fixtures/monorepo_project/pyproject.toml | 2 + .../subproject_3/pyproject.toml | 7 +++ tests/test_cmd_tasks.py | 59 +++++++++++++++++++ tests/test_includes.py | 21 ++++++- 9 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 tests/fixtures/cwd_project/subdir/bar/baz.txt create mode 100644 tests/fixtures/monorepo_project/subproject_3/pyproject.toml diff --git a/poethepoet/context.py b/poethepoet/context.py index 1bbbc0da0..123cf0a8e 100644 --- a/poethepoet/context.py +++ b/poethepoet/context.py @@ -1,4 +1,3 @@ -import os import re from pathlib import Path from typing import TYPE_CHECKING, Any, Dict, Mapping, Optional, Tuple @@ -106,15 +105,17 @@ def get_executor( ) -> "PoeExecutor": from .executor import PoeExecutor - cwd_option = task_options.get("cwd", ".") - if cwd_option == '$exec_cwd': - cwd_option = os.getcwd() + cwd_option = self.env.fill_template(task_options.get("cwd", ".")) + working_dir = Path(cwd_option) + + if not working_dir.is_absolute(): + working_dir = self.project_dir / working_dir return PoeExecutor.get( invocation=invocation, context=self, env=env, - working_dir=self.project_dir / cwd_option, + working_dir=working_dir, dry=self.dry, executor_config=task_options.get("executor"), capture_stdout=task_options.get("capture_stdout", False), diff --git a/poethepoet/env/manager.py b/poethepoet/env/manager.py index e84500260..aba2435fe 100644 --- a/poethepoet/env/manager.py +++ b/poethepoet/env/manager.py @@ -1,3 +1,4 @@ +import os from pathlib import Path from typing import TYPE_CHECKING, Any, Dict, Mapping, Optional, Union @@ -51,6 +52,9 @@ def __init__( self._vars["POE_ROOT"] = str(self._config.project_dir) + if "POE_PWD" not in self._vars: + self._vars["POE_PWD"] = os.getcwd() + def get(self, key: str, default: Optional[str] = None) -> Optional[str]: return self._vars.get(key, default) diff --git a/tests/conftest.py b/tests/conftest.py index 1d28706b2..e9d804b74 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -141,6 +141,7 @@ def run_poe_subproc( subproc_env = dict(os.environ) subproc_env.pop("VIRTUAL_ENV", None) + subproc_env.pop("POE_PWD", None) # do not inherit this from the test if env: subproc_env.update(env) diff --git a/tests/fixtures/cwd_project/pyproject.toml b/tests/fixtures/cwd_project/pyproject.toml index 1e592025b..0404de017 100644 --- a/tests/fixtures/cwd_project/pyproject.toml +++ b/tests/fixtures/cwd_project/pyproject.toml @@ -1,3 +1,11 @@ [tool.poe.tasks.cwd] cmd = "poe_test_pwd" cwd = "./subdir/foo" + +[tool.poe.tasks.cwd_env] +cmd = "poe_test_pwd" +cwd = "./subdir/${BAR_ENV}" + +[tool.poe.tasks.cwd_poe_pwd] +cmd = "poe_test_pwd" +cwd = "${POE_PWD}" diff --git a/tests/fixtures/cwd_project/subdir/bar/baz.txt b/tests/fixtures/cwd_project/subdir/bar/baz.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/monorepo_project/pyproject.toml b/tests/fixtures/monorepo_project/pyproject.toml index 70cbd5875..9e2be8304 100644 --- a/tests/fixtures/monorepo_project/pyproject.toml +++ b/tests/fixtures/monorepo_project/pyproject.toml @@ -4,6 +4,8 @@ path = "subproject_1/pyproject.toml" [[tool.poe.include]] path = "subproject_2/pyproject.toml" cwd = "subproject_2" +[[tool.poe.include]] +path = "subproject_3/pyproject.toml" [tool.poe.tasks.get_cwd_0] diff --git a/tests/fixtures/monorepo_project/subproject_3/pyproject.toml b/tests/fixtures/monorepo_project/subproject_3/pyproject.toml new file mode 100644 index 000000000..f33eb7fe9 --- /dev/null +++ b/tests/fixtures/monorepo_project/subproject_3/pyproject.toml @@ -0,0 +1,7 @@ + + + +[tool.poe.tasks.get_cwd_3] +interpreter = "python" +shell = "import os; print(os.getcwd())" +cwd = "${POE_PWD}" diff --git a/tests/test_cmd_tasks.py b/tests/test_cmd_tasks.py index adfb0d907..4d3ad1bbc 100644 --- a/tests/test_cmd_tasks.py +++ b/tests/test_cmd_tasks.py @@ -1,3 +1,6 @@ +import os + + def test_call_echo_task(run_poe_subproc, projects, esc_prefix): result = run_poe_subproc("echo", "foo", "!", project="cmds") assert ( @@ -63,3 +66,59 @@ def test_cmd_task_with_cwd_option(run_poe_subproc, poe_project_path): == f'{poe_project_path.joinpath("tests", "fixtures", "cwd_project", "subdir", "foo")}\n' ) assert result.stderr == "" + + +def test_cmd_task_with_cwd_option_env(run_poe_subproc, poe_project_path): + result = run_poe_subproc("cwd_env", project="cwd", env={"BAR_ENV": "bar"}) + assert result.capture == "Poe => poe_test_pwd\n" + assert ( + result.stdout + == f'{poe_project_path.joinpath("tests", "fixtures", "cwd_project", "subdir", "bar")}\n' + ) + assert result.stderr == "" + + +def test_cmd_task_with_cwd_option_pwd(run_poe_subproc, poe_project_path): + prev_cwd = os.getcwd() + try: + os.chdir( + poe_project_path.joinpath( + "tests", "fixtures", "cwd_project", "subdir", "foo" + ) + ) + result = run_poe_subproc("cwd_poe_pwd", project="cwd") + assert result.capture == "Poe => poe_test_pwd\n" + assert ( + result.stdout + == f'{poe_project_path.joinpath("tests", "fixtures", "cwd_project", "subdir", "foo")}\n' + ) + assert result.stderr == "" + finally: + os.chdir(prev_cwd) + + +def test_cmd_task_with_cwd_option_pwd_override(run_poe_subproc, poe_project_path): + prev_cwd = os.getcwd() + try: + os.chdir( + poe_project_path.joinpath( + "tests", "fixtures", "cwd_project", "subdir", "foo" + ) + ) + result = run_poe_subproc( + "cwd_poe_pwd", + project="cwd", + env={ + "POE_PWD": poe_project_path.joinpath( + "tests", "fixtures", "cwd_project", "subdir", "bar" + ) + }, + ) + assert result.capture == "Poe => poe_test_pwd\n" + assert ( + result.stdout + == f'{poe_project_path.joinpath("tests", "fixtures", "cwd_project", "subdir", "bar")}\n' + ) + assert result.stderr == "" + finally: + os.chdir(prev_cwd) diff --git a/tests/test_includes.py b/tests/test_includes.py index 4f390381d..0c4ecbb38 100644 --- a/tests/test_includes.py +++ b/tests/test_includes.py @@ -1,3 +1,6 @@ +import os + + def test_docs_for_include_toml_file(run_poe_subproc): result = run_poe_subproc(project="includes") assert ( @@ -88,7 +91,8 @@ def test_monorepo_contains_only_expected_tasks(run_poe_subproc, projects): "CONFIGURED TASKS\n" " get_cwd_0 \n" " get_cwd_1 \n" - " get_cwd_2 \n\n\n" + " get_cwd_2 \n" + " get_cwd_3 \n\n\n" ) assert result.stdout == "" assert result.stderr == "" @@ -148,3 +152,18 @@ def test_monorepo_runs_each_task_with_expected_cwd( "poethepoet/tests/fixtures/monorepo_project/subproject_2\n" ) assert result.stderr == "" + + prev_cwd = os.getcwd() + try: + os.chdir(projects["example"]) + result = run_poe_subproc("get_cwd_3", project="monorepo") + assert result.capture == "Poe => import os; print(os.getcwd())\n" + if is_windows: + assert result.stdout.endswith( + "poethepoet\\tests\\fixtures\\example_project\n" + ) + else: + assert result.stdout.endswith("poethepoet/tests/fixtures/example_project\n") + assert result.stderr == "" + finally: + os.chdir(prev_cwd)