pdm-default-scripts 0.1.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pdm-default-scripts
|
|
3
|
+
Version: 0.1.5
|
|
4
|
+
Summary: PDM plugin that adds default scripts after `pdm init`
|
|
5
|
+
Keywords: pdm,plugin,default scripts
|
|
6
|
+
Author-Email: tepek2 <dev@tepek2.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
|
+
Requires-Dist: pdm>=2.26.7
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
# pdm-default-scripts
|
|
15
|
+
|
|
16
|
+
`pdm-default-scripts` is a PDM plugin that adds your predefined scripts to new projects right after `pdm init`.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Install the plugin into your PDM environment:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pdm self add pdm-default-scripts
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Configure default scripts
|
|
27
|
+
|
|
28
|
+
Create a `default-scripts.toml` file in your user PDM config directory.
|
|
29
|
+
|
|
30
|
+
- Linux: `~/.config/pdm/default-scripts.toml`
|
|
31
|
+
- macOS: `~/Library/Application Support/pdm/default-scripts.toml`
|
|
32
|
+
- Windows: `%APPDATA%\\pdm\\default-scripts.toml`
|
|
33
|
+
|
|
34
|
+
### Example
|
|
35
|
+
|
|
36
|
+
```toml
|
|
37
|
+
[scripts]
|
|
38
|
+
test = "pytest"
|
|
39
|
+
lint = "ruff check ."
|
|
40
|
+
format = "ruff format ."
|
|
41
|
+
|
|
42
|
+
[scripts.cov]
|
|
43
|
+
cmd = "pytest --cov"
|
|
44
|
+
env = { PYTHONPATH = "src" }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
|
|
49
|
+
1. Configure `default-scripts.toml` once.
|
|
50
|
+
2. Run `pdm init` in any new project.
|
|
51
|
+
3. The plugin adds missing entries into `[tool.pdm.scripts]` in `pyproject.toml`.
|
|
52
|
+
|
|
53
|
+
Existing scripts are not overwritten.
|
|
54
|
+
|
|
55
|
+
## How it behaves
|
|
56
|
+
|
|
57
|
+
- Runs on the `post_init` PDM signal.
|
|
58
|
+
- Reads `[scripts]` from your `default-scripts.toml`.
|
|
59
|
+
- Writes scripts into `[tool.pdm.scripts]` only when a script name is not already present.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# pdm-default-scripts
|
|
4
|
+
|
|
5
|
+
`pdm-default-scripts` is a PDM plugin that adds your predefined scripts to new projects right after `pdm init`.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Install the plugin into your PDM environment:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pdm self add pdm-default-scripts
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Configure default scripts
|
|
16
|
+
|
|
17
|
+
Create a `default-scripts.toml` file in your user PDM config directory.
|
|
18
|
+
|
|
19
|
+
- Linux: `~/.config/pdm/default-scripts.toml`
|
|
20
|
+
- macOS: `~/Library/Application Support/pdm/default-scripts.toml`
|
|
21
|
+
- Windows: `%APPDATA%\\pdm\\default-scripts.toml`
|
|
22
|
+
|
|
23
|
+
### Example
|
|
24
|
+
|
|
25
|
+
```toml
|
|
26
|
+
[scripts]
|
|
27
|
+
test = "pytest"
|
|
28
|
+
lint = "ruff check ."
|
|
29
|
+
format = "ruff format ."
|
|
30
|
+
|
|
31
|
+
[scripts.cov]
|
|
32
|
+
cmd = "pytest --cov"
|
|
33
|
+
env = { PYTHONPATH = "src" }
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
1. Configure `default-scripts.toml` once.
|
|
39
|
+
2. Run `pdm init` in any new project.
|
|
40
|
+
3. The plugin adds missing entries into `[tool.pdm.scripts]` in `pyproject.toml`.
|
|
41
|
+
|
|
42
|
+
Existing scripts are not overwritten.
|
|
43
|
+
|
|
44
|
+
## How it behaves
|
|
45
|
+
|
|
46
|
+
- Runs on the `post_init` PDM signal.
|
|
47
|
+
- Reads `[scripts]` from your `default-scripts.toml`.
|
|
48
|
+
- Writes scripts into `[tool.pdm.scripts]` only when a script name is not already present.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from collections.abc import MutableMapping
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import platformdirs
|
|
5
|
+
import tomlkit
|
|
6
|
+
from pdm.core import Core
|
|
7
|
+
from pdm.project import Project
|
|
8
|
+
from pdm.signals import post_init
|
|
9
|
+
from tomlkit import TOMLDocument
|
|
10
|
+
from tomlkit.items import Table
|
|
11
|
+
|
|
12
|
+
DEFAULT_SCRIPTS_FILE = "default-scripts.toml"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _get_scripts_for_creation() -> Table | None:
|
|
16
|
+
default_scripts = platformdirs.user_config_path("pdm") / DEFAULT_SCRIPTS_FILE
|
|
17
|
+
|
|
18
|
+
if not default_scripts.exists():
|
|
19
|
+
return None
|
|
20
|
+
|
|
21
|
+
with default_scripts.open("r", encoding="utf-8") as fp:
|
|
22
|
+
scripts = tomlkit.load(fp).get("scripts")
|
|
23
|
+
|
|
24
|
+
if scripts is None:
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
assert isinstance(scripts, Table), "[scripts] must be a TOML table"
|
|
28
|
+
|
|
29
|
+
return scripts
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _add_script_with_dotted_keys(scripts_table: Table, name: str, command: Any):
|
|
33
|
+
if isinstance(command, MutableMapping):
|
|
34
|
+
for key, value in command.items():
|
|
35
|
+
dotted_key = tomlkit.key([name, str(key)])
|
|
36
|
+
scripts_table.append(dotted_key, value)
|
|
37
|
+
return
|
|
38
|
+
scripts_table[name] = command
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _get_or_create_table(node: TOMLDocument | Table, key: str) -> Table:
|
|
42
|
+
|
|
43
|
+
if node.get(key) is None:
|
|
44
|
+
node[key] = tomlkit.table()
|
|
45
|
+
|
|
46
|
+
table = node[key]
|
|
47
|
+
assert isinstance(table, Table), f"[{key}] must be TOML table"
|
|
48
|
+
|
|
49
|
+
return table
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def on_post_init(project: Project, **args):
|
|
53
|
+
scripts_to_add = _get_scripts_for_creation()
|
|
54
|
+
|
|
55
|
+
if scripts_to_add is None:
|
|
56
|
+
return
|
|
57
|
+
|
|
58
|
+
tool_table = _get_or_create_table(project.pyproject.open_for_write(), "tool")
|
|
59
|
+
pdm_table = _get_or_create_table(tool_table, "pdm")
|
|
60
|
+
scripts_table = _get_or_create_table(pdm_table, "scripts")
|
|
61
|
+
|
|
62
|
+
for name, command in scripts_to_add.items():
|
|
63
|
+
if name not in scripts_table:
|
|
64
|
+
_add_script_with_dotted_keys(scripts_table, str(name), command)
|
|
65
|
+
project.core.ui.info(f"Added default script: {name}")
|
|
66
|
+
|
|
67
|
+
project.pyproject.write(show_message=False)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def plugin(core: Core) -> None:
|
|
71
|
+
post_init.connect(on_post_init)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pdm-default-scripts"
|
|
3
|
+
version = "0.1.5"
|
|
4
|
+
description = "PDM plugin that adds default scripts after `pdm init`"
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "tepek2", email = "dev@tepek2.com" },
|
|
7
|
+
]
|
|
8
|
+
requires-python = ">=3.9"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
keywords = [
|
|
11
|
+
"pdm",
|
|
12
|
+
"plugin",
|
|
13
|
+
"default scripts",
|
|
14
|
+
]
|
|
15
|
+
dependencies = [
|
|
16
|
+
"pdm>=2.26.7",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.license]
|
|
20
|
+
text = "MIT"
|
|
21
|
+
|
|
22
|
+
[project.entry-points.pdm]
|
|
23
|
+
default-scripts = "default_scripts:plugin"
|
|
24
|
+
|
|
25
|
+
[build-system]
|
|
26
|
+
requires = [
|
|
27
|
+
"pdm-backend",
|
|
28
|
+
]
|
|
29
|
+
build-backend = "pdm.backend"
|
|
30
|
+
|
|
31
|
+
[dependency-groups]
|
|
32
|
+
dev = [
|
|
33
|
+
"pytest>=9.0.2",
|
|
34
|
+
"pytest-mock>=3.15.1",
|
|
35
|
+
"pyright>=1.1.408",
|
|
36
|
+
"pytest-cov>=7.1.0",
|
|
37
|
+
"ruff>=0.15.8",
|
|
38
|
+
]
|
|
39
|
+
release = [
|
|
40
|
+
"commitizen>=4.13.9",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[tool.ruff]
|
|
44
|
+
line-length = 100
|
|
45
|
+
|
|
46
|
+
[tool.ruff.lint]
|
|
47
|
+
select = [
|
|
48
|
+
"E4",
|
|
49
|
+
"E7",
|
|
50
|
+
"E9",
|
|
51
|
+
"F",
|
|
52
|
+
"I",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[tool.commitizen]
|
|
56
|
+
name = "cz_conventional_commits"
|
|
57
|
+
changelog_incremental = false
|
|
58
|
+
tag_format = "v$version"
|
|
59
|
+
version_scheme = "semver2"
|
|
60
|
+
version_provider = "pep621"
|
|
61
|
+
|
|
62
|
+
[tool.pdm]
|
|
63
|
+
distribution = true
|
|
64
|
+
|
|
65
|
+
[tool.pdm.scripts]
|
|
66
|
+
lint = "ruff check"
|
|
67
|
+
test = "pytest"
|
|
68
|
+
type-check = "pyright ."
|
|
69
|
+
coverage = "pytest --cov-fail-under=75"
|
|
70
|
+
release-create = "cz bump --allow-no-commit --version-files-only --changelog --changelog-to-stdout --yes {args}"
|
|
71
|
+
|
|
72
|
+
[tool.pdm.scripts.static-analys]
|
|
73
|
+
composite = [
|
|
74
|
+
"lint",
|
|
75
|
+
"type-check",
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
[tool.pdm.scripts.tests]
|
|
79
|
+
composite = [
|
|
80
|
+
"static-analys",
|
|
81
|
+
"test",
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
[tool.pdm.scripts.release-commit]
|
|
85
|
+
shell = "git add pyproject.toml CHANGELOG.md && git commit -m \"release: v$(cz version --project)\" && git tag \"v$(cz version --project)\" && git push && git push --tags\n "
|
|
86
|
+
|
|
87
|
+
[tool.pdm.scripts.release]
|
|
88
|
+
composite = [
|
|
89
|
+
"release-create {args}",
|
|
90
|
+
"release-commit",
|
|
91
|
+
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import tomlkit
|
|
2
|
+
import tomlkit.items
|
|
3
|
+
from pdm import signals
|
|
4
|
+
from pdm.project.core import Project
|
|
5
|
+
from pdm.pytest import RunResult
|
|
6
|
+
from pytest import MonkeyPatch
|
|
7
|
+
|
|
8
|
+
from default_scripts import on_post_init
|
|
9
|
+
|
|
10
|
+
pytest_plugins = "pdm.pytest"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_post_init_signal(
|
|
14
|
+
project_no_init: Project,
|
|
15
|
+
pdm,
|
|
16
|
+
monkeypatch: MonkeyPatch,
|
|
17
|
+
):
|
|
18
|
+
def _table_data(str_data: str) -> tomlkit.items.Table:
|
|
19
|
+
scripts = tomlkit.parse(str_data).get("scripts")
|
|
20
|
+
assert isinstance(scripts, tomlkit.items.Table)
|
|
21
|
+
return scripts
|
|
22
|
+
|
|
23
|
+
mock_config_file_str = """
|
|
24
|
+
[scripts]
|
|
25
|
+
_.env = { PYTHONPATH = "${PDM_PROJECT_ROOT}" }
|
|
26
|
+
format = "ruff format ."
|
|
27
|
+
cov = { cmd = "pytest --cov", env = { PYTHONPATH = "src" } }
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
[scripts.cov2]
|
|
31
|
+
cmd = "pytest --cov"
|
|
32
|
+
env = { PYTHONPATH = "src" }
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
expected_data = {
|
|
36
|
+
"_": {"env": {"PYTHONPATH": "${PDM_PROJECT_ROOT}"}},
|
|
37
|
+
"format": "ruff format .",
|
|
38
|
+
"cov": {"cmd": "pytest --cov", "env": {"PYTHONPATH": "src"}},
|
|
39
|
+
"cov2": {"cmd": "pytest --cov", "env": {"PYTHONPATH": "src"}},
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
monkeypatch.setattr(
|
|
43
|
+
"default_scripts._get_scripts_for_creation",
|
|
44
|
+
lambda: _table_data(mock_config_file_str),
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
with signals.post_init.connected_to(on_post_init):
|
|
48
|
+
result: RunResult = pdm(["init", "-n"], obj=project_no_init)
|
|
49
|
+
print(project_no_init.scripts)
|
|
50
|
+
assert result.exit_code == 0
|
|
51
|
+
assert project_no_init.scripts == expected_data
|