Skip to content

Commit

Permalink
feat: pass original working directory as env variable to pdm scripts (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
o-moe authored Nov 13, 2024
1 parent 96c59f8 commit 7c879cf
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 1 deletion.
4 changes: 4 additions & 0 deletions docs/usage/scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@ start.working_dir = "subdir"

Relative paths are resolved against the project root.

+++ 2.20.2

To identify the original calling working directory, each script gets the environment variable `PDM_RUN_CWD` injected.

### `site_packages`

To make sure the running environment is properly isolated from the outer Python interpreter,
Expand Down
1 change: 1 addition & 0 deletions news/3179.feat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Pass original working directory as env variable to pdm scripts
4 changes: 3 additions & 1 deletion src/pdm/cli/commands/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,11 @@ def forward_signal(signum: int, frame: FrameType | None) -> None:
signum = signal.SIGTERM
process.send_signal(signum)

process_env = os.environ.copy()
process_env.update({"PDM_RUN_CWD": str(Path.cwd())})
handle_term = signal.signal(signal.SIGTERM, forward_signal)
handle_int = signal.signal(signal.SIGINT, forward_signal)
process = subprocess.Popen(process_cmd, cwd=cwd, shell=shell, bufsize=0, close_fds=False)
process = subprocess.Popen(process_cmd, cwd=cwd, shell=shell, bufsize=0, close_fds=False, env=process_env)
retcode = process.wait()
signal.signal(signal.SIGTERM, handle_term)
signal.signal(signal.SIGINT, handle_int)
Expand Down
33 changes: 33 additions & 0 deletions tests/cli/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -995,3 +995,36 @@ def test_run_script_with_inline_metadata(project, pdm, local_finder, local_finde
with cd(project.root):
result = pdm(["run", "test_script.py"], obj=project)
assert result.exit_code == 0


def test_run_script_pass_run_cwd(project, pdm, capfd):
project.pyproject.settings["scripts"] = {
"test_script": [
"python",
"-c",
"import os;print(os.getenv('PDM_RUN_CWD'))",
]
}
project.pyproject.write()
capfd.readouterr()
result = pdm(["run", "test_script"], obj=project)
assert result.exit_code == 0
out, _ = capfd.readouterr()
assert Path(out.strip()) == Path.cwd()


def test_run_script_pass_run_cwd_to_original_working_dir_when_working_dir_of_script_is_changed(project, pdm, capfd):
project.root.joinpath("subdir").mkdir()
project.root.joinpath("subdir", "test_script.py").write_text(
textwrap.dedent("""\
import os
print(os.getenv('PDM_RUN_CWD', ''))
""")
)
project.pyproject.settings["scripts"] = {
"test_script": {"working_dir": "subdir", "cmd": "python test_script.py"},
}
project.pyproject.write()
capfd.readouterr()
pdm(["run", "test_script"], obj=project, strict=True)
assert capfd.readouterr()[0].strip() == str(Path.cwd())

0 comments on commit 7c879cf

Please sign in to comment.