common-python-tasks 0.8.0__tar.gz → 0.9.0__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.
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/PKG-INFO +33 -25
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/README.md +32 -24
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/pyproject.toml +1 -1
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/scripts/add_common_python_tasks.py +8 -41
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/fastapi/compose-base.yml.j2 +1 -2
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/fastapi/compose-db.yml.j2 +1 -2
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/fastapi/compose-debug.yml.j2 +1 -1
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/generic/.dockerignore +1 -1
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/generic/Dockerfile.j2 +1 -34
- common_python_tasks-0.9.0/src/common_python_tasks/data/generic/ruff.toml +2 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/docker.py +1 -21
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/docker_compose.py +4 -7
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/github.py +20 -1
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/project.py +124 -295
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/tasks.py +7 -14
- common_python_tasks-0.8.0/src/common_python_tasks/data/generic/ruff.toml +0 -2
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/.gitignore +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/.poetry/plugins/poetry_dynamic_versioning-1.10.0.dist-info/licenses/LICENSE +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/.poetry/plugins/poetry_plugin_export-1.10.0.dist-info/licenses/LICENSE +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/LICENSE +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/scripts/__init__.py +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/scripts/readme_tasks_table.py +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/scripts/release_script.py +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/scripts/update_readme_tasks_table.py +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/scripts/utils.py +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/__init__.py +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/__main__.py +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/dockerfile_extensions/.gitkeep +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/fastapi/alembic.ini.j2 +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/fastapi/compose-db-debug.yml.j2 +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/generic/.coveragerc +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/generic/Dockerfile.deps.j2 +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/generic/cliff.toml +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/data/generic/pytest.ini +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/env.py +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/git.py +0 -0
- {common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: common-python-tasks
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: Opinionated Poe the Poet tasks for Python package development.
|
|
5
5
|
Project-URL: Homepage, http://github.com/ci-sourcerer/common-python-tasks
|
|
6
6
|
Project-URL: Source, http://github.com/ci-sourcerer/common-python-tasks.git
|
|
@@ -43,9 +43,7 @@ It supplies sensible defaults for formatting, linting, testing, packaging, relea
|
|
|
43
43
|
Add `common-python-tasks` as a development dependency from your project root.
|
|
44
44
|
|
|
45
45
|
```shell
|
|
46
|
-
uv add --dev common-python-tasks==0.
|
|
47
|
-
# or, for Poetry projects
|
|
48
|
-
poetry add --group dev common-python-tasks==0.8.0
|
|
46
|
+
uv add --dev common-python-tasks==0.9.0
|
|
49
47
|
```
|
|
50
48
|
|
|
51
49
|
Configure Poe the Poet to expose the default `common` task set.
|
|
@@ -70,7 +68,7 @@ The helper script performs the same development-dependency installation and Poe
|
|
|
70
68
|
```shell
|
|
71
69
|
curl --fail --silent --show-error --location \
|
|
72
70
|
--output /tmp/add_common_python_tasks.py \
|
|
73
|
-
https://raw.githubusercontent.com/ci-sourcerer/common-python-tasks/v0.
|
|
71
|
+
https://raw.githubusercontent.com/ci-sourcerer/common-python-tasks/v0.9.0/scripts/add_common_python_tasks.py
|
|
74
72
|
```
|
|
75
73
|
|
|
76
74
|
Review the downloaded script before executing it.
|
|
@@ -82,10 +80,10 @@ less /tmp/add_common_python_tasks.py
|
|
|
82
80
|
Run the reviewed script with the same pinned package version.
|
|
83
81
|
|
|
84
82
|
```shell
|
|
85
|
-
COMMON_PYTHON_TASKS_VERSION=0.
|
|
83
|
+
COMMON_PYTHON_TASKS_VERSION=0.9.0 python3 /tmp/add_common_python_tasks.py
|
|
86
84
|
```
|
|
87
85
|
|
|
88
|
-
To install another release, replace both occurrences of `0.
|
|
86
|
+
To install another release, replace both occurrences of `0.9.0` with that release's version.
|
|
89
87
|
|
|
90
88
|
## Available tasks
|
|
91
89
|
|
|
@@ -108,7 +106,7 @@ The generated tables below list public tasks only. Tags identify which tasks are
|
|
|
108
106
|
| --- | --- | --- |
|
|
109
107
|
| `publish-package` | Publish the package to the PyPI server. | common, packaging |
|
|
110
108
|
| `publish-github-release` | Publish or update a GitHub Release for the current repository. | common, packaging, release |
|
|
111
|
-
| `update-dependencies` | Update project dependencies with
|
|
109
|
+
| `update-dependencies` | Update project dependencies with uv. | common, packaging |
|
|
112
110
|
| `build-package` | Build the package (wheel and sdist). | build, common, packaging |
|
|
113
111
|
| `bump-version` | Bump the project version. | common, packaging |
|
|
114
112
|
| `changelog` | Print the changelog for the current version based on git history and git-cliff. | common, packaging, release |
|
|
@@ -143,7 +141,7 @@ The generated tables below list public tasks only. Tags identify which tasks are
|
|
|
143
141
|
|
|
144
142
|
Every project needs a `pyproject.toml` file at its root and Poe the Poet available in its development environment.
|
|
145
143
|
|
|
146
|
-
Tasks that install, build, publish, or update dependencies
|
|
144
|
+
Tasks that install, build, publish, or update dependencies require uv. Package and release tasks need a resolvable project version from `project.version` or Git tags. Dynamic versioning is supported but is not a baseline requirement.
|
|
147
145
|
|
|
148
146
|
### Task selection
|
|
149
147
|
|
|
@@ -163,18 +161,27 @@ include_script = "common_python_tasks:tasks(include_tags=['common', 'containers'
|
|
|
163
161
|
|
|
164
162
|
The `containers` tag also includes container-based development-stack tasks. Use the tags in the task tables to tailor a smaller task set.
|
|
165
163
|
|
|
166
|
-
### Package
|
|
164
|
+
### Package management
|
|
167
165
|
|
|
168
|
-
Packaging-related tasks, including `build-package`, `publish-package`, release version resolution, and container build metadata,
|
|
166
|
+
Packaging-related tasks, including `build-package`, `publish-package`, dependency updates, release version resolution, and container build metadata, use uv exclusively. The `uv` executable must be available on `PATH`.
|
|
169
167
|
|
|
170
|
-
|
|
168
|
+
### Publish target selection
|
|
171
169
|
|
|
172
|
-
|
|
173
|
-
2. `COMMON_PYTHON_TASKS_BUILD_TOOL`
|
|
174
|
-
3. `PACKAGE_MANAGER`
|
|
175
|
-
4. Auto-discovery (`auto`) based on installed tools and project metadata
|
|
170
|
+
The `publish-package` task resolves publish targets with this precedence.
|
|
176
171
|
|
|
177
|
-
|
|
172
|
+
1. Explicit task arguments (`repository` or `repository_url`)
|
|
173
|
+
2. Environment-variable fallback
|
|
174
|
+
3. uv project configuration fallback from `[[tool.uv.index]]`
|
|
175
|
+
4. The `uv publish` default
|
|
176
|
+
|
|
177
|
+
uv prefers named publish indexes.
|
|
178
|
+
|
|
179
|
+
- `COMMON_PYTHON_TASKS_PUBLISH_REPOSITORY`
|
|
180
|
+
- `UV_PUBLISH_INDEX`
|
|
181
|
+
- `COMMON_PYTHON_TASKS_PUBLISH_URL`
|
|
182
|
+
- `UV_PUBLISH_URL`
|
|
183
|
+
|
|
184
|
+
When using uv project configuration fallback, `[[tool.uv.index]]` must include both `name` and `publish-url` for publish selection. If multiple publishable indexes exist, set exactly one `default = true` or pass an explicit repository.
|
|
178
185
|
|
|
179
186
|
### Configuration precedence
|
|
180
187
|
|
|
@@ -196,7 +203,7 @@ After installing the package, a minimal project configuration looks like this.
|
|
|
196
203
|
```toml
|
|
197
204
|
[project]
|
|
198
205
|
name = "simple-cli-tool"
|
|
199
|
-
version = "0.
|
|
206
|
+
version = "0.9.0"
|
|
200
207
|
|
|
201
208
|
[tool.poe]
|
|
202
209
|
include_script = "common_python_tasks:tasks()"
|
|
@@ -232,9 +239,10 @@ addopts = "-ra"
|
|
|
232
239
|
#### Project and package settings
|
|
233
240
|
|
|
234
241
|
- `PACKAGE_NAME`: Overrides the package name inferred from `pyproject.toml`
|
|
235
|
-
- `
|
|
236
|
-
- `
|
|
237
|
-
- `
|
|
242
|
+
- `COMMON_PYTHON_TASKS_PUBLISH_REPOSITORY`: Preferred publish repository/index name for `publish-package`
|
|
243
|
+
- `COMMON_PYTHON_TASKS_PUBLISH_URL`: Preferred uv publish upload URL for `publish-package` when no repository/index is selected
|
|
244
|
+
- `UV_PUBLISH_INDEX`: uv publish-index fallback for `publish-package`
|
|
245
|
+
- `UV_PUBLISH_URL`: uv publish upload-url fallback for `publish-package`
|
|
238
246
|
|
|
239
247
|
#### Container image settings
|
|
240
248
|
|
|
@@ -386,7 +394,7 @@ GITHUB_RELEASE_ASSETS="dist/*.whl:dist/*.tar.gz" poe publish-github-release
|
|
|
386
394
|
|
|
387
395
|
### Container build fails with "unable to find package"
|
|
388
396
|
|
|
389
|
-
Check that `pyproject.toml` has a correct package name and the package-discovery settings required by its build backend. For
|
|
397
|
+
Check that `pyproject.toml` has a correct package name and the package-discovery settings required by its build backend. For a `src` layout built with Hatch, configure `[tool.hatch.build.targets.wheel] packages = ["src/your_package"]`.
|
|
390
398
|
|
|
391
399
|
### Stack fails to start or services cannot connect
|
|
392
400
|
|
|
@@ -411,9 +419,9 @@ Ensure the project-root `.env` file is writable and inspect its permissions with
|
|
|
411
419
|
|
|
412
420
|
See the [standard Dockerfile template](src/common_python_tasks/data/generic/Dockerfile.j2) for the implementation.
|
|
413
421
|
|
|
414
|
-
- Multi-stage build: The build stage installs
|
|
415
|
-
- Cache mounts: Pip and
|
|
416
|
-
- Explicit build metadata: `PYTHON_VERSION`, `
|
|
422
|
+
- Multi-stage build: The build stage installs uv and builds a wheel. The runtime stage installs only the wheel to keep the final image slim and reproducible.
|
|
423
|
+
- Cache mounts: Pip and uv cache mounts speed up iterative builds without bloating the final image.
|
|
424
|
+
- Explicit build metadata: `PYTHON_VERSION`, `UV_VERSION`, `PACKAGE_VERSION`, `PACKAGE_NAME`, `AUTHORS`, and `GIT_COMMIT` make image metadata predictable and auditable.
|
|
417
425
|
- Project-level build settings: `CONTAINER_APT_PACKAGES`, `CONTAINER_CUSTOM_ENTRYPOINT`, and `CONTAINER_DEPS_IMAGE` configure generated image behavior without being encoded as generic Docker arguments.
|
|
418
426
|
- Optional debug stage: The image exports and installs the `debug` dependency group only when present and does not include it in the default final image.
|
|
419
427
|
- Stable package path: Symlinks give entrypoints and consumers consistent `/pkg` and `/_$PACKAGE_NAME` paths regardless of wheel layout.
|
|
@@ -11,9 +11,7 @@ It supplies sensible defaults for formatting, linting, testing, packaging, relea
|
|
|
11
11
|
Add `common-python-tasks` as a development dependency from your project root.
|
|
12
12
|
|
|
13
13
|
```shell
|
|
14
|
-
uv add --dev common-python-tasks==0.
|
|
15
|
-
# or, for Poetry projects
|
|
16
|
-
poetry add --group dev common-python-tasks==0.8.0
|
|
14
|
+
uv add --dev common-python-tasks==0.9.0
|
|
17
15
|
```
|
|
18
16
|
|
|
19
17
|
Configure Poe the Poet to expose the default `common` task set.
|
|
@@ -38,7 +36,7 @@ The helper script performs the same development-dependency installation and Poe
|
|
|
38
36
|
```shell
|
|
39
37
|
curl --fail --silent --show-error --location \
|
|
40
38
|
--output /tmp/add_common_python_tasks.py \
|
|
41
|
-
https://raw.githubusercontent.com/ci-sourcerer/common-python-tasks/v0.
|
|
39
|
+
https://raw.githubusercontent.com/ci-sourcerer/common-python-tasks/v0.9.0/scripts/add_common_python_tasks.py
|
|
42
40
|
```
|
|
43
41
|
|
|
44
42
|
Review the downloaded script before executing it.
|
|
@@ -50,10 +48,10 @@ less /tmp/add_common_python_tasks.py
|
|
|
50
48
|
Run the reviewed script with the same pinned package version.
|
|
51
49
|
|
|
52
50
|
```shell
|
|
53
|
-
COMMON_PYTHON_TASKS_VERSION=0.
|
|
51
|
+
COMMON_PYTHON_TASKS_VERSION=0.9.0 python3 /tmp/add_common_python_tasks.py
|
|
54
52
|
```
|
|
55
53
|
|
|
56
|
-
To install another release, replace both occurrences of `0.
|
|
54
|
+
To install another release, replace both occurrences of `0.9.0` with that release's version.
|
|
57
55
|
|
|
58
56
|
## Available tasks
|
|
59
57
|
|
|
@@ -76,7 +74,7 @@ The generated tables below list public tasks only. Tags identify which tasks are
|
|
|
76
74
|
| --- | --- | --- |
|
|
77
75
|
| `publish-package` | Publish the package to the PyPI server. | common, packaging |
|
|
78
76
|
| `publish-github-release` | Publish or update a GitHub Release for the current repository. | common, packaging, release |
|
|
79
|
-
| `update-dependencies` | Update project dependencies with
|
|
77
|
+
| `update-dependencies` | Update project dependencies with uv. | common, packaging |
|
|
80
78
|
| `build-package` | Build the package (wheel and sdist). | build, common, packaging |
|
|
81
79
|
| `bump-version` | Bump the project version. | common, packaging |
|
|
82
80
|
| `changelog` | Print the changelog for the current version based on git history and git-cliff. | common, packaging, release |
|
|
@@ -111,7 +109,7 @@ The generated tables below list public tasks only. Tags identify which tasks are
|
|
|
111
109
|
|
|
112
110
|
Every project needs a `pyproject.toml` file at its root and Poe the Poet available in its development environment.
|
|
113
111
|
|
|
114
|
-
Tasks that install, build, publish, or update dependencies
|
|
112
|
+
Tasks that install, build, publish, or update dependencies require uv. Package and release tasks need a resolvable project version from `project.version` or Git tags. Dynamic versioning is supported but is not a baseline requirement.
|
|
115
113
|
|
|
116
114
|
### Task selection
|
|
117
115
|
|
|
@@ -131,18 +129,27 @@ include_script = "common_python_tasks:tasks(include_tags=['common', 'containers'
|
|
|
131
129
|
|
|
132
130
|
The `containers` tag also includes container-based development-stack tasks. Use the tags in the task tables to tailor a smaller task set.
|
|
133
131
|
|
|
134
|
-
### Package
|
|
132
|
+
### Package management
|
|
135
133
|
|
|
136
|
-
Packaging-related tasks, including `build-package`, `publish-package`, release version resolution, and container build metadata,
|
|
134
|
+
Packaging-related tasks, including `build-package`, `publish-package`, dependency updates, release version resolution, and container build metadata, use uv exclusively. The `uv` executable must be available on `PATH`.
|
|
137
135
|
|
|
138
|
-
|
|
136
|
+
### Publish target selection
|
|
139
137
|
|
|
140
|
-
|
|
141
|
-
2. `COMMON_PYTHON_TASKS_BUILD_TOOL`
|
|
142
|
-
3. `PACKAGE_MANAGER`
|
|
143
|
-
4. Auto-discovery (`auto`) based on installed tools and project metadata
|
|
138
|
+
The `publish-package` task resolves publish targets with this precedence.
|
|
144
139
|
|
|
145
|
-
|
|
140
|
+
1. Explicit task arguments (`repository` or `repository_url`)
|
|
141
|
+
2. Environment-variable fallback
|
|
142
|
+
3. uv project configuration fallback from `[[tool.uv.index]]`
|
|
143
|
+
4. The `uv publish` default
|
|
144
|
+
|
|
145
|
+
uv prefers named publish indexes.
|
|
146
|
+
|
|
147
|
+
- `COMMON_PYTHON_TASKS_PUBLISH_REPOSITORY`
|
|
148
|
+
- `UV_PUBLISH_INDEX`
|
|
149
|
+
- `COMMON_PYTHON_TASKS_PUBLISH_URL`
|
|
150
|
+
- `UV_PUBLISH_URL`
|
|
151
|
+
|
|
152
|
+
When using uv project configuration fallback, `[[tool.uv.index]]` must include both `name` and `publish-url` for publish selection. If multiple publishable indexes exist, set exactly one `default = true` or pass an explicit repository.
|
|
146
153
|
|
|
147
154
|
### Configuration precedence
|
|
148
155
|
|
|
@@ -164,7 +171,7 @@ After installing the package, a minimal project configuration looks like this.
|
|
|
164
171
|
```toml
|
|
165
172
|
[project]
|
|
166
173
|
name = "simple-cli-tool"
|
|
167
|
-
version = "0.
|
|
174
|
+
version = "0.9.0"
|
|
168
175
|
|
|
169
176
|
[tool.poe]
|
|
170
177
|
include_script = "common_python_tasks:tasks()"
|
|
@@ -200,9 +207,10 @@ addopts = "-ra"
|
|
|
200
207
|
#### Project and package settings
|
|
201
208
|
|
|
202
209
|
- `PACKAGE_NAME`: Overrides the package name inferred from `pyproject.toml`
|
|
203
|
-
- `
|
|
204
|
-
- `
|
|
205
|
-
- `
|
|
210
|
+
- `COMMON_PYTHON_TASKS_PUBLISH_REPOSITORY`: Preferred publish repository/index name for `publish-package`
|
|
211
|
+
- `COMMON_PYTHON_TASKS_PUBLISH_URL`: Preferred uv publish upload URL for `publish-package` when no repository/index is selected
|
|
212
|
+
- `UV_PUBLISH_INDEX`: uv publish-index fallback for `publish-package`
|
|
213
|
+
- `UV_PUBLISH_URL`: uv publish upload-url fallback for `publish-package`
|
|
206
214
|
|
|
207
215
|
#### Container image settings
|
|
208
216
|
|
|
@@ -354,7 +362,7 @@ GITHUB_RELEASE_ASSETS="dist/*.whl:dist/*.tar.gz" poe publish-github-release
|
|
|
354
362
|
|
|
355
363
|
### Container build fails with "unable to find package"
|
|
356
364
|
|
|
357
|
-
Check that `pyproject.toml` has a correct package name and the package-discovery settings required by its build backend. For
|
|
365
|
+
Check that `pyproject.toml` has a correct package name and the package-discovery settings required by its build backend. For a `src` layout built with Hatch, configure `[tool.hatch.build.targets.wheel] packages = ["src/your_package"]`.
|
|
358
366
|
|
|
359
367
|
### Stack fails to start or services cannot connect
|
|
360
368
|
|
|
@@ -379,9 +387,9 @@ Ensure the project-root `.env` file is writable and inspect its permissions with
|
|
|
379
387
|
|
|
380
388
|
See the [standard Dockerfile template](src/common_python_tasks/data/generic/Dockerfile.j2) for the implementation.
|
|
381
389
|
|
|
382
|
-
- Multi-stage build: The build stage installs
|
|
383
|
-
- Cache mounts: Pip and
|
|
384
|
-
- Explicit build metadata: `PYTHON_VERSION`, `
|
|
390
|
+
- Multi-stage build: The build stage installs uv and builds a wheel. The runtime stage installs only the wheel to keep the final image slim and reproducible.
|
|
391
|
+
- Cache mounts: Pip and uv cache mounts speed up iterative builds without bloating the final image.
|
|
392
|
+
- Explicit build metadata: `PYTHON_VERSION`, `UV_VERSION`, `PACKAGE_VERSION`, `PACKAGE_NAME`, `AUTHORS`, and `GIT_COMMIT` make image metadata predictable and auditable.
|
|
385
393
|
- Project-level build settings: `CONTAINER_APT_PACKAGES`, `CONTAINER_CUSTOM_ENTRYPOINT`, and `CONTAINER_DEPS_IMAGE` configure generated image behavior without being encoded as generic Docker arguments.
|
|
386
394
|
- Optional debug stage: The image exports and installs the `debug` dependency group only when present and does not include it in the default final image.
|
|
387
395
|
- Stable package path: Symlinks give entrypoints and consumers consistent `/pkg` and `/_$PACKAGE_NAME` paths regardless of wheel layout.
|
|
@@ -10,11 +10,6 @@ import tomllib
|
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
|
|
12
12
|
PACKAGE_NAME = "common-python-tasks"
|
|
13
|
-
PACKAGE_MANAGER_ENV_VARS = (
|
|
14
|
-
"COMMON_PYTHON_TASKS_PACKAGE_MANAGER",
|
|
15
|
-
"COMMON_PYTHON_TASKS_BUILD_TOOL",
|
|
16
|
-
"PACKAGE_MANAGER",
|
|
17
|
-
)
|
|
18
13
|
PYPROJECT_PATH = Path("pyproject.toml")
|
|
19
14
|
TOOL_POE_PATTERN = re.compile(r"^\s*\[tool\.poe\]\s*(?:#.*)?$")
|
|
20
15
|
TABLE_PATTERN = re.compile(r"^\s*\[")
|
|
@@ -26,47 +21,18 @@ def _require_command(command: str) -> None:
|
|
|
26
21
|
sys.exit(f"Required command not found: {command}")
|
|
27
22
|
|
|
28
23
|
|
|
29
|
-
def _get_requested_package_manager() -> str:
|
|
30
|
-
for env_var in PACKAGE_MANAGER_ENV_VARS:
|
|
31
|
-
if os.getenv(env_var, "").strip():
|
|
32
|
-
return os.environ[env_var].strip().lower()
|
|
33
|
-
return "auto"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def _select_package_manager() -> str:
|
|
37
|
-
requested_manager = _get_requested_package_manager()
|
|
38
|
-
if requested_manager in {"poetry", "uv"}:
|
|
39
|
-
_require_command(requested_manager)
|
|
40
|
-
return requested_manager
|
|
41
|
-
if requested_manager != "auto":
|
|
42
|
-
sys.exit(f"Unsupported package manager: {requested_manager}")
|
|
43
|
-
|
|
44
|
-
for lock_file, package_manager in (
|
|
45
|
-
(Path("uv.lock"), "uv"),
|
|
46
|
-
(Path("poetry.lock"), "poetry"),
|
|
47
|
-
):
|
|
48
|
-
if lock_file.is_file() and shutil.which(package_manager) is not None:
|
|
49
|
-
return package_manager
|
|
50
|
-
|
|
51
|
-
for package_manager in ("uv", "poetry"):
|
|
52
|
-
if shutil.which(package_manager) is not None:
|
|
53
|
-
return package_manager
|
|
54
|
-
|
|
55
|
-
sys.exit("Neither uv nor Poetry is installed.")
|
|
56
|
-
|
|
57
|
-
|
|
58
24
|
def _get_package_requirement() -> str:
|
|
59
25
|
if os.getenv("COMMON_PYTHON_TASKS_VERSION", "").strip():
|
|
60
26
|
return f"{PACKAGE_NAME}=={os.environ['COMMON_PYTHON_TASKS_VERSION'].strip()}"
|
|
61
27
|
return PACKAGE_NAME
|
|
62
28
|
|
|
63
29
|
|
|
64
|
-
def _install_package(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
30
|
+
def _install_package() -> None:
|
|
31
|
+
subprocess.run(
|
|
32
|
+
["uv", "add", "--dev", _get_package_requirement()],
|
|
33
|
+
check=True,
|
|
34
|
+
shell=False,
|
|
35
|
+
)
|
|
70
36
|
|
|
71
37
|
|
|
72
38
|
def _get_include_script() -> str:
|
|
@@ -132,7 +98,8 @@ def _print_available_tasks() -> None:
|
|
|
132
98
|
|
|
133
99
|
def main() -> None:
|
|
134
100
|
"""Install common tasks and configure Poe in the current project."""
|
|
135
|
-
|
|
101
|
+
_require_command("uv")
|
|
102
|
+
_install_package()
|
|
136
103
|
_configure_poe()
|
|
137
104
|
print("\n\033[1;32mCommon Python tasks added to project.\033[0m")
|
|
138
105
|
print("\n\033[1mAvailable tasks:\033[0m")
|
|
@@ -9,8 +9,7 @@ x-common-environment: &common-environment
|
|
|
9
9
|
x-common-build-args: &common-build-args
|
|
10
10
|
PACKAGE_NAME: ${PACKAGE_NAME}
|
|
11
11
|
PYTHON_VERSION: ${PYTHON_VERSION}
|
|
12
|
-
|
|
13
|
-
PACKAGE_MANAGER_VERSION: ${PACKAGE_MANAGER_VERSION}
|
|
12
|
+
UV_VERSION: ${UV_VERSION}
|
|
14
13
|
|
|
15
14
|
services:
|
|
16
15
|
api:
|
|
@@ -8,8 +8,7 @@ x-common-environment: &common-environment
|
|
|
8
8
|
x-common-build-args: &common-build-args
|
|
9
9
|
PACKAGE_NAME: ${PACKAGE_NAME}
|
|
10
10
|
PYTHON_VERSION: ${PYTHON_VERSION}
|
|
11
|
-
|
|
12
|
-
PACKAGE_MANAGER_VERSION: ${PACKAGE_MANAGER_VERSION}
|
|
11
|
+
UV_VERSION: ${UV_VERSION}
|
|
13
12
|
WORKDIR_PATH: ${WORKDIR_PATH}
|
|
14
13
|
|
|
15
14
|
services:
|
|
@@ -7,33 +7,10 @@ ARG PYTHON_VERSION=3
|
|
|
7
7
|
# See https://hub.docker.com/_/python for available variants
|
|
8
8
|
ARG PYTHON_VARIANT=slim
|
|
9
9
|
ARG WORKDIR_PATH=/workspace
|
|
10
|
-
{% set package_manager = PACKAGE_MANAGER|default('poetry') %}
|
|
11
10
|
|
|
12
11
|
FROM python:${PYTHON_VERSION} AS builder
|
|
13
12
|
|
|
14
13
|
ARG PACKAGE_VERSION
|
|
15
|
-
|
|
16
|
-
{% if package_manager == 'poetry' %}
|
|
17
|
-
ARG POETRY_VERSION
|
|
18
|
-
ARG POETRY_DYNAMIC_VERSIONING_PLUGIN_VERSION
|
|
19
|
-
ARG POETRY_PLUGIN_EXPORT_VERSION
|
|
20
|
-
|
|
21
|
-
# Bypass VCS-based version detection: use the host-computed version directly.
|
|
22
|
-
# This avoids requiring a .git directory in the build context and prevents
|
|
23
|
-
# false dirty-version detection from a partial working tree.
|
|
24
|
-
ENV POETRY_DYNAMIC_VERSIONING_BYPASS=${PACKAGE_VERSION}
|
|
25
|
-
|
|
26
|
-
# Install Poetry and required Poetry plugins for package build
|
|
27
|
-
RUN --mount=type=cache,target=/root/.cache/pip,id=pip-cache{{ CACHE_ID_SUFFIX }} \
|
|
28
|
-
sh -c 'set -eu; \
|
|
29
|
-
poetry_spec="poetry"; \
|
|
30
|
-
if [ -n "${POETRY_VERSION:-}" ]; then poetry_spec="poetry==$POETRY_VERSION"; fi; \
|
|
31
|
-
dynamic_spec="poetry-dynamic-versioning[plugin]"; \
|
|
32
|
-
if [ -n "${POETRY_DYNAMIC_VERSIONING_PLUGIN_VERSION:-}" ]; then dynamic_spec="poetry-dynamic-versioning[plugin]==$POETRY_DYNAMIC_VERSIONING_PLUGIN_VERSION"; fi; \
|
|
33
|
-
export_spec="poetry-plugin-export"; \
|
|
34
|
-
if [ -n "${POETRY_PLUGIN_EXPORT_VERSION:-}" ]; then export_spec="poetry-plugin-export==$POETRY_PLUGIN_EXPORT_VERSION"; fi; \
|
|
35
|
-
pip install --root-user-action=ignore "$poetry_spec" "$dynamic_spec" "$export_spec"'
|
|
36
|
-
{% else %}
|
|
37
14
|
ARG UV_VERSION
|
|
38
15
|
|
|
39
16
|
# Bypass VCS-based version detection: use the host-computed version directly.
|
|
@@ -48,7 +25,6 @@ RUN --mount=type=cache,target=/root/.cache/pip,id=pip-cache{{ CACHE_ID_SUFFIX }}
|
|
|
48
25
|
else \
|
|
49
26
|
pip install --root-user-action=ignore uv; \
|
|
50
27
|
fi'
|
|
51
|
-
{% endif %}
|
|
52
28
|
|
|
53
29
|
# Build package
|
|
54
30
|
WORKDIR /tmp/build
|
|
@@ -56,24 +32,15 @@ COPY . /tmp/build/
|
|
|
56
32
|
|
|
57
33
|
{% if HAS_DEBUG_DEPS %}
|
|
58
34
|
# Export debug requirements when the project defines a debug dependency group
|
|
59
|
-
{% if package_manager == 'poetry' %}
|
|
60
|
-
RUN --mount=type=cache,target=/root/.cache/pip,id=pip-cache{{ CACHE_ID_SUFFIX }} \
|
|
61
|
-
poetry export --only debug --without-hashes -f requirements.txt --output requirements-debug.txt
|
|
62
|
-
{% else %}
|
|
63
35
|
RUN --mount=type=cache,target=/root/.cache/uv,id=uv-cache{{ CACHE_ID_SUFFIX }} \
|
|
64
36
|
uv export --group debug --no-hashes --format requirements-txt --output-file requirements-debug.txt
|
|
65
37
|
{% endif %}
|
|
66
|
-
{% endif %}
|
|
67
38
|
|
|
68
|
-
# Build the wheel, caching the
|
|
39
|
+
# Build the wheel, caching the uv cache directory to speed up subsequent builds.
|
|
69
40
|
# If running this in a CI system, you must be using a persistent builder to take
|
|
70
41
|
# advantage of the cache mount, and you should configure your CI to persist the
|
|
71
42
|
# cache directory between builds
|
|
72
|
-
{% if package_manager == 'poetry' %}
|
|
73
|
-
RUN --mount=type=cache,target=/root/.cache/pypoetry,id=pypoetry-cache{{ CACHE_ID_SUFFIX }} poetry build --format=wheel
|
|
74
|
-
{% else %}
|
|
75
43
|
RUN --mount=type=cache,target=/root/.cache/uv,id=uv-cache{{ CACHE_ID_SUFFIX }} uv build --wheel
|
|
76
|
-
{% endif %}
|
|
77
44
|
|
|
78
45
|
FROM python:${PYTHON_VERSION}-${PYTHON_VARIANT} AS runtime
|
|
79
46
|
ARG WORKDIR_PATH=/workspace
|
|
@@ -289,37 +289,17 @@ def render_build_image(
|
|
|
289
289
|
commit_tag = version_tag
|
|
290
290
|
|
|
291
291
|
python_version = platform.python_version()
|
|
292
|
-
package_manager = project.get_package_manager()
|
|
293
|
-
package_manager_version = project.get_package_manager_version(package_manager)
|
|
294
|
-
|
|
295
|
-
manager_build_args: dict[str, str | None]
|
|
296
|
-
if package_manager == project.PackageManager.POETRY:
|
|
297
|
-
manager_build_args = {
|
|
298
|
-
"POETRY_VERSION": package_manager_version,
|
|
299
|
-
"POETRY_DYNAMIC_VERSIONING_PLUGIN_VERSION": project.get_installed_requirement_version(
|
|
300
|
-
"poetry-dynamic-versioning[plugin]"
|
|
301
|
-
),
|
|
302
|
-
"POETRY_PLUGIN_EXPORT_VERSION": project.get_installed_requirement_version(
|
|
303
|
-
"poetry-plugin-export"
|
|
304
|
-
),
|
|
305
|
-
}
|
|
306
|
-
else:
|
|
307
|
-
manager_build_args = {
|
|
308
|
-
"UV_VERSION": package_manager_version,
|
|
309
|
-
}
|
|
310
292
|
|
|
311
293
|
build_args = _merge_build_args(
|
|
312
294
|
{
|
|
313
295
|
"PYTHON_VERSION": python_version,
|
|
314
|
-
"
|
|
315
|
-
"PACKAGE_MANAGER_VERSION": package_manager_version,
|
|
296
|
+
"UV_VERSION": project.get_uv_version(),
|
|
316
297
|
"PACKAGE_VERSION": package_version,
|
|
317
298
|
"PACKAGE_NAME": utils.get_package_name(use_underscores=True),
|
|
318
299
|
"AUTHORS": ",".join(
|
|
319
300
|
[f"{name} <{email}>" for name, email in project.get_authors()]
|
|
320
301
|
),
|
|
321
302
|
"GIT_COMMIT": commit_tag,
|
|
322
|
-
**manager_build_args,
|
|
323
303
|
},
|
|
324
304
|
extra_build_args,
|
|
325
305
|
)
|
{common_python_tasks-0.8.0 → common_python_tasks-0.9.0}/src/common_python_tasks/docker_compose.py
RENAMED
|
@@ -14,7 +14,7 @@ from poethepoet_tasks import TaskCollection
|
|
|
14
14
|
|
|
15
15
|
from . import utils
|
|
16
16
|
from .env import get_workdir_path
|
|
17
|
-
from .project import
|
|
17
|
+
from .project import get_uv_version
|
|
18
18
|
|
|
19
19
|
LOGGER = logging.getLogger(__name__)
|
|
20
20
|
|
|
@@ -239,8 +239,7 @@ _COMPOSE_VAR_REQUIREMENTS: dict[str, dict[str, set[str]]] = {
|
|
|
239
239
|
"ENVIRONMENT",
|
|
240
240
|
"IMAGE_TAG",
|
|
241
241
|
"PYTHON_VERSION",
|
|
242
|
-
"
|
|
243
|
-
"PACKAGE_MANAGER_VERSION",
|
|
242
|
+
"UV_VERSION",
|
|
244
243
|
},
|
|
245
244
|
"compose-db": {
|
|
246
245
|
"PACKAGE_NAME",
|
|
@@ -250,8 +249,7 @@ _COMPOSE_VAR_REQUIREMENTS: dict[str, dict[str, set[str]]] = {
|
|
|
250
249
|
"DB_PORT",
|
|
251
250
|
"IMAGE_TAG",
|
|
252
251
|
"PYTHON_VERSION",
|
|
253
|
-
"
|
|
254
|
-
"PACKAGE_MANAGER_VERSION",
|
|
252
|
+
"UV_VERSION",
|
|
255
253
|
"POSTGRES_VERSION",
|
|
256
254
|
"WORKDIR_PATH",
|
|
257
255
|
},
|
|
@@ -337,13 +335,12 @@ def get_compose_env(
|
|
|
337
335
|
"ENVIRONMENT": os.getenv("ENVIRONMENT", "production"),
|
|
338
336
|
"IMAGE_TAG": image_tag or "latest",
|
|
339
337
|
"PACKAGE_NAME": package_name,
|
|
340
|
-
"PACKAGE_MANAGER": get_package_manager(),
|
|
341
|
-
"PACKAGE_MANAGER_VERSION": get_package_manager_version(),
|
|
342
338
|
"PACKAGE_UNDERSCORE_NAME": utils.package_name_to_underscore(package_name),
|
|
343
339
|
"WORKDIR_PATH": get_workdir_path(),
|
|
344
340
|
"POSTGRES_VERSION": os.getenv("POSTGRES_VERSION", "17"),
|
|
345
341
|
"PYTHON_VERSION": platform.python_version(),
|
|
346
342
|
"SECRET_KEY": os.getenv("SECRET_KEY", ""),
|
|
343
|
+
"UV_VERSION": get_uv_version(),
|
|
347
344
|
}
|
|
348
345
|
|
|
349
346
|
if compose_type and compose_files:
|
|
@@ -28,6 +28,18 @@ def _is_unreleased_placeholder(notes: str) -> bool:
|
|
|
28
28
|
return normalized in {"[unreleased]", "## [unreleased]", "## unreleased"}
|
|
29
29
|
|
|
30
30
|
|
|
31
|
+
def _pattern_targets_hidden_paths(pattern: str) -> bool:
|
|
32
|
+
return any(
|
|
33
|
+
part.startswith(".")
|
|
34
|
+
for part in pattern.split("/")
|
|
35
|
+
if part and part not in {".", ".."}
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _path_has_hidden_segment(path: Path) -> bool:
|
|
40
|
+
return any(part.startswith(".") for part in path.parts if part not in {".", ".."})
|
|
41
|
+
|
|
42
|
+
|
|
31
43
|
def _latest_tagged_changelog() -> str | None:
|
|
32
44
|
result = utils.run_git_cliff(["--latest"], capture_output=True)
|
|
33
45
|
changelog = result.stdout.strip()
|
|
@@ -538,6 +550,8 @@ def get_github_release_asset_paths(
|
|
|
538
550
|
interpreted as colon-separated paths or glob patterns.
|
|
539
551
|
If not provided, the default value is `dist/*`. An empty list
|
|
540
552
|
explicitly disables asset selection.
|
|
553
|
+
Wildcard patterns only include hidden files when the pattern itself
|
|
554
|
+
explicitly targets hidden paths (for example, `dist/.*`).
|
|
541
555
|
|
|
542
556
|
Returns:
|
|
543
557
|
A sorted list of existing asset paths.
|
|
@@ -561,9 +575,14 @@ def get_github_release_asset_paths(
|
|
|
561
575
|
asset_paths = []
|
|
562
576
|
for part in source_items:
|
|
563
577
|
if any(char in part for char in "*?[]"):
|
|
578
|
+
matches = [path for path in Path(".").glob(part) if path.is_file()]
|
|
579
|
+
if not _pattern_targets_hidden_paths(part):
|
|
580
|
+
matches = [
|
|
581
|
+
path for path in matches if not _path_has_hidden_segment(path)
|
|
582
|
+
]
|
|
564
583
|
asset_paths.extend(
|
|
565
584
|
sorted(
|
|
566
|
-
|
|
585
|
+
matches,
|
|
567
586
|
key=lambda p: str(p),
|
|
568
587
|
)
|
|
569
588
|
)
|