Skip to content

Commit e258a1a

Browse files
authored
Merge pull request #27 from noirbizarre/feature/reuse-scripts
Feature: reuse PDM scripts
2 parents a4a4a86 + 3af55a7 commit e258a1a

File tree

11 files changed

+494
-348
lines changed

11 files changed

+494
-348
lines changed

.github/workflows/ci.yml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ jobs:
1010
runs-on: ubuntu-latest
1111
strategy:
1212
matrix:
13-
python-version: [3.8, 3.9, "3.10"]
14-
tox-version: ["<4", ">=4.0.0b0"]
13+
python-version: [3.7, 3.8, 3.9, "3.10"]
14+
tox-version: [3, 4]
1515

1616
steps:
1717
- uses: actions/checkout@v3
@@ -21,12 +21,13 @@ jobs:
2121
python-version: ${{ matrix.python-version }}
2222
- name: Install dependencies
2323
run: |
24-
python -m pip install "tox${{ matrix.tox-version }}" .
24+
python -m pip install "tox>=${{ matrix.tox-version }}.0.0b0,<${{ matrix.tox-version }}.999" .
2525
- name: Test with tox
2626
run: |
27+
tox --version
2728
pyversion="${{ matrix.python-version }}"
28-
if which tox4 > /dev/null
29-
then
30-
mv pdm.tox4.lock pdm.lock
29+
toxversion="${{ matrix.tox-version }}"
30+
if [[ $toxversion == "4" ]]; then
31+
mv pdm.tox4.lock pdm.lock;
3132
fi
32-
tox -e py${pyversion/./}
33+
tox -e py${pyversion/./}-tox${toxversion}

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ commands =
4646
pytest test/
4747
```
4848

49+
Here is another one installing the `test` dependencies and executing the `test` PDM script
50+
51+
```ini
52+
[tox]
53+
envlist = py3{8,9,10}
54+
isolated_build = True ; This is required for a pyproject.toml based project.
55+
56+
[testenv]
57+
groups = test
58+
commands = test
59+
```
60+
4961
A real-world example can be found at this repository's [tox.ini](https://github.com/pdm-project/tox-pdm/blob/main/tox.ini) and
5062
[GitHub Action workflow](https://github.com/pdm-project/tox-pdm/blob/main/.github/workflows/ci.yml).
5163

@@ -54,3 +66,4 @@ A real-world example can be found at this repository's [tox.ini](https://github.
5466
1. `pdm` executable must be exposed in `PATH`, if it is not the case, give the absolute path to tox by `tox --pdm <path_to_pdm>`.
5567
2. Make sure you have generated `pdm.lock` before running the test, it will greatly accelerate the testing.
5668
3. If you don't set `skip_install = true`, the current package will be built and installed into the testing environment together with the `dependencies` from `pyproject.toml`.
69+
4. Reuse your PDM scripts to avoid duplication

pdm.lock

Lines changed: 188 additions & 157 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pdm.tox4.lock

Lines changed: 154 additions & 123 deletions
Large diffs are not rendered by default.

pyproject.toml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pdm = "tox_pdm.plugin"
2929
[project.optional-dependencies]
3030
test = [
3131
"pytest>=6.2",
32-
"coverage>=5.5",
32+
"coverage[toml]>=5.5,<6.4",
3333
]
3434
lint = [
3535
"flake8>=3.8",
@@ -43,6 +43,22 @@ build-backend = "pdm.pep517.api"
4343
[tool.pdm]
4444
version = {use_scm = true}
4545

46+
[tool.pdm.scripts]
47+
test = "pytest -v tests/"
48+
49+
[tool.pdm.scripts.lint]
50+
shell = """
51+
flake8 tox_pdm
52+
isort --check tox_pdm tests
53+
black --check tox_pdm tests
54+
"""
55+
56+
[tool.pdm.scripts.format]
57+
shell = """
58+
isort tox_pdm tests
59+
black tox_pdm tests
60+
"""
61+
4662
[tool.pytest.ini_options]
4763
filterwarnings = ["ignore::DeprecationWarning"]
4864

tests/fixture-project/pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ build-backend = "pdm.pep517.api"
2626

2727
[tool]
2828
[tool.pdm]
29+
[tool.pdm.scripts]
30+
lint = "flake8 demo.py"
31+
lint-shell = {shell = "flake8 demo.py"}

tests/test_integration.py

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,35 @@ def setup_project(tmpdir, tox_config):
3131
)
3232

3333

34-
def test_install_conditional_deps(tmpdir):
34+
def execute_config(tmpdir, config: str):
35+
__tracebackhide__ = True
3536
if IS_TOX_4:
36-
from tox.run import main
37+
from tox.run import run as main
3738
else:
3839
from tox.session import main
3940

40-
test_config = textwrap.dedent(
41+
setup_project(tmpdir, textwrap.dedent(config))
42+
43+
code = -1
44+
with tmpdir.as_cwd():
45+
try:
46+
main([])
47+
except SystemExit as e:
48+
print("e", e)
49+
code = e.code
50+
if code != 0:
51+
pytest.fail(f"non-zero exit code: {code}")
52+
53+
if TOX_VERSION[0] == "4":
54+
package = tmpdir.join(".tox/.pkg/dist/demo-0.1.0.tar.gz")
55+
else:
56+
package = tmpdir.join(".tox/dist/demo-0.1.0.tar.gz")
57+
assert package.exists()
58+
59+
60+
def test_install_conditional_deps(tmpdir):
61+
execute_config(
62+
tmpdir,
4163
"""
4264
[tox]
4365
envlist = django{2,3}
@@ -53,18 +75,37 @@ def test_install_conditional_deps(tmpdir):
5375
commands =
5476
django-admin --version
5577
flake8 --version
78+
""",
79+
)
80+
81+
82+
def test_use_pdm_scripts(tmpdir):
83+
execute_config(
84+
tmpdir,
5685
"""
86+
[tox]
87+
envlist = py3
88+
passenv = LD_PRELOAD
89+
isolated_build = True
90+
91+
[testenv]
92+
groups = lint
93+
commands = lint
94+
""",
5795
)
58-
setup_project(tmpdir, test_config)
59-
with tmpdir.as_cwd():
60-
try:
61-
main([])
62-
except SystemExit as e:
63-
if e.code != 0:
64-
raise RuntimeError(f"non-zero exit code: {e.code}")
6596

66-
if TOX_VERSION[0] == "4":
67-
package = tmpdir.join(".tox/.pkg/dist/demo-0.1.0.tar.gz")
68-
else:
69-
package = tmpdir.join(".tox/dist/demo-0.1.0.tar.gz")
70-
assert package.exists()
97+
98+
def test_use_pdm_shell_scripts(tmpdir):
99+
execute_config(
100+
tmpdir,
101+
"""
102+
[tox]
103+
envlist = py3
104+
passenv = LD_PRELOAD
105+
isolated_build = True
106+
107+
[testenv]
108+
groups = lint
109+
commands = lint-shell
110+
""",
111+
)

tox.ini

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@ ignore =
55
max-line-length = 88
66

77
[tox]
8-
envlist = py{38,39,310}, lint
8+
envlist = py3{7,8,9,10}-tox{3,4}, lint
99
passenv = LD_PRELOAD
1010
isolated_build = True
1111

1212
[testenv]
1313
groups = test
14-
commands = pytest tests/
14+
commands_pre =
15+
tox4: pip install tox>=4.0.0b2
16+
commands =
17+
tox --version
18+
test {posargs}
1519

1620
[testenv:lint]
1721
groups = lint
1822
skip_install = true
19-
commands =
20-
flake8 tox_pdm
21-
black --check tox_pdm
23+
commands = lint

tox_pdm/plugin3.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
"""Plugin specification for Tox 3"""
2+
import os
23
from typing import Any
34

45
from tox import action, config, hookimpl
56
from tox.venv import VirtualEnv
67

7-
from tox_pdm.utils import setup_env
8+
from .utils import pdm_scripts
9+
10+
11+
def setup_env() -> None:
12+
os.environ.update({"PDM_IGNORE_SAVED_PYTHON": "1", "PDM_USE_VENV": "1"})
13+
old_passenv = os.getenv("TOX_TESTENV_PASSENV")
14+
new_env = ["PDM_*"]
15+
if old_passenv:
16+
new_env.append(old_passenv)
17+
os.environ["TOX_TESTENV_PASSENV"] = " ".join(new_env)
818

919

1020
@hookimpl
@@ -16,6 +26,17 @@ def tox_addoption(parser: config.Parser) -> Any:
1626
parser.add_argument("--pdm", default="pdm", help="The executable path of PDM")
1727

1828

29+
@hookimpl
30+
def tox_configure(config: config.Config):
31+
scripts = pdm_scripts(config.toxinidir)
32+
if scripts:
33+
for cfg in config.envconfigs.values():
34+
cfg.allowlist_externals.append("pdm")
35+
for lineno, cmd in enumerate(cfg.commands):
36+
if cmd[0] in scripts:
37+
cfg.commands[lineno] = ["pdm", "run", *cmd]
38+
39+
1940
@hookimpl
2041
def tox_testenv_install_deps(venv: VirtualEnv, action: action.Action) -> Any:
2142
groups = venv.envconfig.groups or []

tox_pdm/plugin4.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@
22
from __future__ import annotations
33

44
import typing as t
5+
from pathlib import Path
56

67
from tox.config.set_env import SetEnv
78
from tox.execute.request import StdinSource
89
from tox.plugin import impl
910
from tox.tox_env.python.virtual_env.runner import VirtualEnvRunner
1011

12+
from .utils import pdm_scripts
13+
1114
if t.TYPE_CHECKING:
1215
from argparse import ArgumentParser
1316

17+
from tox.execute.api import Execute, Outcome
1418
from tox.tox_env.register import ToxEnvRegister
1519

1620

@@ -58,3 +62,18 @@ def register_config(self) -> None:
5862
@staticmethod
5963
def id() -> str:
6064
return "pdm"
65+
66+
def execute(
67+
self,
68+
cmd: t.Sequence[Path | str],
69+
stdin: StdinSource,
70+
show: bool | None = None,
71+
cwd: Path | None = None,
72+
run_id: str = "",
73+
executor: Execute | None = None,
74+
) -> Outcome:
75+
scripts = pdm_scripts(self.core["tox_root"])
76+
if scripts:
77+
if cmd[0] in scripts:
78+
cmd = ["pdm", "run", *cmd]
79+
return super().execute(cmd, stdin, show, cwd, run_id, executor)

0 commit comments

Comments
 (0)