invoke-tasklib 0.0.8__tar.gz → 0.1.0a0__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.
- {invoke_tasklib-0.0.8 → invoke_tasklib-0.1.0a0}/.gitignore +2 -0
- invoke_tasklib-0.1.0a0/PKG-INFO +348 -0
- invoke_tasklib-0.1.0a0/README.md +320 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/__init__.py +248 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/_coverage.py +147 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/_discover.py +270 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/_files.py +225 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/_graph.py +499 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/_pyproject.py +75 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/_steps.py +388 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/check.py +165 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/clean.py +446 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/config/__init__.py +50 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/config/__main__.py +44 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/config/_constants.py +27 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/config/_derive.py +80 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/config/_invoke.py +160 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/config/_resolve.py +181 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/config/_schema.py +439 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/config/_validate.py +579 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/doc.py +405 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/env.py +270 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/fix.py +91 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/formatting.py +241 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/imports.py +126 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/lint.py +116 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/output.py +251 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/release.py +452 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/runner.py +324 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/security.py +64 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/show.py +182 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/testing.py +449 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/tools.py +404 -0
- invoke_tasklib-0.1.0a0/invoke_tasklib/typecheck.py +76 -0
- invoke_tasklib-0.1.0a0/pyproject.toml +284 -0
- invoke_tasklib-0.1.0a0/tests/__init__.py +0 -0
- invoke_tasklib-0.1.0a0/tests/benchmarks/__init__.py +0 -0
- invoke_tasklib-0.1.0a0/tests/benchmarks/test_config_benchmark.py +41 -0
- invoke_tasklib-0.1.0a0/tests/benchmarks/test_files_benchmark.py +30 -0
- invoke_tasklib-0.1.0a0/tests/benchmarks/test_graph_benchmark.py +51 -0
- invoke_tasklib-0.1.0a0/tests/benchmarks/test_init_benchmark.py +24 -0
- invoke_tasklib-0.1.0a0/tests/benchmarks/test_runner_benchmark.py +17 -0
- invoke_tasklib-0.1.0a0/tests/helpers.py +110 -0
- invoke_tasklib-0.1.0a0/tests/integration/__init__.py +0 -0
- invoke_tasklib-0.1.0a0/tests/integration/helpers.py +48 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_check.py +80 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_clean.py +86 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_doc.py +144 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_docs.py +151 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_doctest.py +17 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_env_config.py +176 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_env_install.py +57 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_env_python.py +31 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_env_tools.py +82 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_exit_codes.py +88 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_files.py +132 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_fix_converges.py +66 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_formatting.py +86 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_imports.py +271 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_output.py +35 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_project.py +204 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_quoting.py +21 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_read_only.py +74 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_readme.py +28 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_release.py +169 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_runner.py +67 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_security.py +49 -0
- invoke_tasklib-0.1.0a0/tests/integration/test_testing.py +158 -0
- invoke_tasklib-0.1.0a0/tests/unit/__init__.py +0 -0
- invoke_tasklib-0.1.0a0/tests/unit/config/__init__.py +0 -0
- invoke_tasklib-0.1.0a0/tests/unit/config/conftest.py +15 -0
- invoke_tasklib-0.1.0a0/tests/unit/config/test___main__.py +60 -0
- invoke_tasklib-0.1.0a0/tests/unit/config/test__derive.py +134 -0
- invoke_tasklib-0.1.0a0/tests/unit/config/test__invoke.py +135 -0
- invoke_tasklib-0.1.0a0/tests/unit/config/test__resolve.py +699 -0
- invoke_tasklib-0.1.0a0/tests/unit/config/test__schema.py +309 -0
- invoke_tasklib-0.1.0a0/tests/unit/config/test__validate.py +566 -0
- invoke_tasklib-0.1.0a0/tests/unit/conftest.py +29 -0
- invoke_tasklib-0.1.0a0/tests/unit/test__coverage.py +151 -0
- invoke_tasklib-0.1.0a0/tests/unit/test__discover.py +276 -0
- invoke_tasklib-0.1.0a0/tests/unit/test__files.py +352 -0
- invoke_tasklib-0.1.0a0/tests/unit/test__graph.py +708 -0
- invoke_tasklib-0.1.0a0/tests/unit/test__pyproject.py +79 -0
- invoke_tasklib-0.1.0a0/tests/unit/test__steps.py +708 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_architecture.py +330 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_check.py +512 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_clean.py +1019 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_doc.py +582 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_docstrings.py +107 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_env.py +675 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_fix.py +145 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_formatting.py +278 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_helpers.py +62 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_imports.py +315 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_init.py +461 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_lint.py +126 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_output.py +372 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_program_hints.py +66 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_release.py +809 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_runner.py +487 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_security.py +54 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_show.py +238 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_testing.py +853 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_tools.py +671 -0
- invoke_tasklib-0.1.0a0/tests/unit/test_typecheck.py +112 -0
- invoke_tasklib-0.0.8/PKG-INFO +0 -247
- invoke_tasklib-0.0.8/README.md +0 -219
- invoke_tasklib-0.0.8/invoke_tasklib/__init__.py +0 -71
- invoke_tasklib-0.0.8/invoke_tasklib/clean.py +0 -63
- invoke_tasklib-0.0.8/invoke_tasklib/config.py +0 -143
- invoke_tasklib-0.0.8/invoke_tasklib/doc.py +0 -59
- invoke_tasklib-0.0.8/invoke_tasklib/env.py +0 -103
- invoke_tasklib-0.0.8/invoke_tasklib/format.py +0 -89
- invoke_tasklib-0.0.8/invoke_tasklib/imports.py +0 -47
- invoke_tasklib-0.0.8/invoke_tasklib/lint.py +0 -34
- invoke_tasklib-0.0.8/invoke_tasklib/release.py +0 -47
- invoke_tasklib-0.0.8/invoke_tasklib/security.py +0 -22
- invoke_tasklib-0.0.8/invoke_tasklib/test.py +0 -169
- invoke_tasklib-0.0.8/invoke_tasklib/types.py +0 -21
- invoke_tasklib-0.0.8/pyproject.toml +0 -277
- {invoke_tasklib-0.0.8 → invoke_tasklib-0.1.0a0}/LICENSE +0 -0
- {invoke_tasklib-0.0.8 → invoke_tasklib-0.1.0a0}/invoke_tasklib/py.typed +0 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: invoke-tasklib
|
|
3
|
+
Version: 0.1.0a0
|
|
4
|
+
Summary: Reusable Invoke tasks shared across Python projects.
|
|
5
|
+
Project-URL: Homepage, https://github.com/durandtibo/invoke-tasklib
|
|
6
|
+
Project-URL: Repository, https://github.com/durandtibo/invoke-tasklib
|
|
7
|
+
Project-URL: Documentation, https://durandtibo.github.io/invoke-tasklib/
|
|
8
|
+
Project-URL: Changelog, https://github.com/durandtibo/invoke-tasklib/releases
|
|
9
|
+
Project-URL: Issues, https://github.com/durandtibo/invoke-tasklib/issues
|
|
10
|
+
Author-email: Thibaut Durand <durand.tibo+gh@gmail.com>
|
|
11
|
+
License-Expression: BSD-3-Clause
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: automation,devtools,invoke,tasks
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
23
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.11
|
|
26
|
+
Requires-Dist: invoke<4.0,>=3.0
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# invoke-tasklib
|
|
30
|
+
|
|
31
|
+
<p align="center">
|
|
32
|
+
<a href="https://github.com/durandtibo/invoke-tasklib/actions/workflows/ci.yaml">
|
|
33
|
+
<img alt="CI" src="https://github.com/durandtibo/invoke-tasklib/actions/workflows/ci.yaml/badge.svg">
|
|
34
|
+
</a>
|
|
35
|
+
<a href="https://github.com/durandtibo/invoke-tasklib/actions/workflows/nightly-package.yaml">
|
|
36
|
+
<img alt="Nightly Package Tests" src="https://github.com/durandtibo/invoke-tasklib/actions/workflows/nightly-package.yaml/badge.svg">
|
|
37
|
+
</a>
|
|
38
|
+
<a href="https://codecov.io/gh/durandtibo/invoke-tasklib">
|
|
39
|
+
<img alt="Codecov" src="https://codecov.io/gh/durandtibo/invoke-tasklib/branch/main/graph/badge.svg">
|
|
40
|
+
</a>
|
|
41
|
+
<br/>
|
|
42
|
+
<a href="https://durandtibo.github.io/invoke-tasklib/">
|
|
43
|
+
<img alt="Documentation" src="https://github.com/durandtibo/invoke-tasklib/actions/workflows/release-docs.yaml/badge.svg">
|
|
44
|
+
</a>
|
|
45
|
+
<a href="https://durandtibo.github.io/invoke-tasklib/dev/">
|
|
46
|
+
<img alt="Documentation" src="https://github.com/durandtibo/invoke-tasklib/actions/workflows/release-docs-dev.yaml/badge.svg">
|
|
47
|
+
</a>
|
|
48
|
+
<br/>
|
|
49
|
+
<a href="https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings">
|
|
50
|
+
<img alt="Doc style: google" src="https://img.shields.io/badge/%20style-google-3666d6.svg">
|
|
51
|
+
</a>
|
|
52
|
+
<a href="https://github.com/astral-sh/ruff">
|
|
53
|
+
<img alt="Ruff" src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json">
|
|
54
|
+
</a>
|
|
55
|
+
<a href="https://github.com/guilatrova/tryceratops">
|
|
56
|
+
<img alt="try/except style: tryceratops" src="https://img.shields.io/badge/try%2Fexcept%20style-tryceratops%20%F0%9F%A6%96%E2%9C%A8-black">
|
|
57
|
+
</a>
|
|
58
|
+
<br/>
|
|
59
|
+
<a href="https://pypi.org/project/invoke-tasklib/">
|
|
60
|
+
<img alt="PYPI version" src="https://img.shields.io/pypi/v/invoke-tasklib">
|
|
61
|
+
</a>
|
|
62
|
+
<a href="https://pypi.org/project/invoke-tasklib/">
|
|
63
|
+
<img alt="Python" src="https://img.shields.io/pypi/pyversions/invoke-tasklib.svg">
|
|
64
|
+
</a>
|
|
65
|
+
<a href="https://opensource.org/licenses/BSD-3-Clause">
|
|
66
|
+
<img alt="BSD-3-Clause" src="https://img.shields.io/pypi/l/invoke-tasklib">
|
|
67
|
+
</a>
|
|
68
|
+
<br/>
|
|
69
|
+
<a href="https://pepy.tech/project/invoke-tasklib">
|
|
70
|
+
<img alt="Downloads" src="https://static.pepy.tech/badge/invoke-tasklib">
|
|
71
|
+
</a>
|
|
72
|
+
<a href="https://pepy.tech/project/invoke-tasklib">
|
|
73
|
+
<img alt="Monthly downloads" src="https://static.pepy.tech/badge/invoke-tasklib/month">
|
|
74
|
+
</a>
|
|
75
|
+
<a href="https://github.com/durandtibo/invoke-tasklib/stargazers">
|
|
76
|
+
<img alt="GitHub stars" src="https://img.shields.io/github/stars/durandtibo/invoke-tasklib">
|
|
77
|
+
</a>
|
|
78
|
+
<br/>
|
|
79
|
+
<a href="https://www.bestpractices.dev/projects/14387">
|
|
80
|
+
<img src="https://www.bestpractices.dev/projects/14387/badge">
|
|
81
|
+
</a>
|
|
82
|
+
<a href="https://scorecard.dev/viewer/?uri=github.com/durandtibo/invoke-tasklib">
|
|
83
|
+
<img alt="OpenSSF Scorecard" src="https://img.shields.io/badge/dynamic/json?url=https://api.scorecard.dev/projects/github.com/durandtibo/invoke-tasklib&label=openssf%20scorecard&query=score">
|
|
84
|
+
</a>
|
|
85
|
+
</p>
|
|
86
|
+
|
|
87
|
+
Reusable [Invoke](https://www.pyinvoke.org/) tasks shared across Python
|
|
88
|
+
projects: formatting, linting, type-checking, testing, environment setup,
|
|
89
|
+
security auditing, releasing, documentation, and cleanup — all as a single
|
|
90
|
+
importable package instead of a `tasks.py` you copy-paste and let drift
|
|
91
|
+
between repositories.
|
|
92
|
+
|
|
93
|
+
:book: **Full documentation:** <https://durandtibo.github.io/invoke-tasklib/>
|
|
94
|
+
|
|
95
|
+
## Install
|
|
96
|
+
|
|
97
|
+
```shell
|
|
98
|
+
uv add --dev invoke-tasklib
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
or with `pip`:
|
|
102
|
+
|
|
103
|
+
```shell
|
|
104
|
+
pip install invoke-tasklib
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Prerequisite:** most tasks (`env.*`, `release.*`, `security.audit`) run
|
|
108
|
+
[`uv`](https://docs.astral.sh/uv/getting-started/installation/), so install
|
|
109
|
+
it even if you install `invoke-tasklib` with `pip`.
|
|
110
|
+
|
|
111
|
+
**Platforms:** Linux and macOS. Windows is not supported: the tasks rely on
|
|
112
|
+
a POSIX shell (for the quoting of the commands), and `make_ns` emits a
|
|
113
|
+
`RuntimeWarning` on Windows.
|
|
114
|
+
|
|
115
|
+
## Quickstart
|
|
116
|
+
|
|
117
|
+
**1. Add a `tasks.py`** at the root of your project:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
# tasks.py
|
|
121
|
+
from invoke_tasklib import make_ns
|
|
122
|
+
|
|
123
|
+
ns = make_ns()
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**2. Add an `invoke.yaml`** with, at minimum, your package name:
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
tasklib:
|
|
130
|
+
package:
|
|
131
|
+
name: my_package
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**3. List and run the tasks:**
|
|
135
|
+
|
|
136
|
+
```shell
|
|
137
|
+
invoke --list
|
|
138
|
+
invoke format.check-python lint.check-python
|
|
139
|
+
invoke test.unit
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
If a task fails because a tool like `ruff` or `pytest` isn't installed yet,
|
|
143
|
+
run `invoke env.install` first.
|
|
144
|
+
|
|
145
|
+
See the [Get Started guide](https://durandtibo.github.io/invoke-tasklib/get_started/)
|
|
146
|
+
for a full walkthrough.
|
|
147
|
+
|
|
148
|
+
## Tasks
|
|
149
|
+
|
|
150
|
+
Tasks are grouped into namespaces, one per module. Each task either
|
|
151
|
+
**checks/reports** (read-only, exits non-zero on violations) or
|
|
152
|
+
**mutates** (formats, builds, publishes) — the table below flags which.
|
|
153
|
+
|
|
154
|
+
| Namespace | Task | Behavior | Mutates? |
|
|
155
|
+
| ---------- | ----------------------------- | ---------------------------------------------------------------------------------------- | :------: |
|
|
156
|
+
| `format` | `format.check-python` | Check Python formatting with ruff | ❌ |
|
|
157
|
+
| `format` | `format.fix-python` | Format Python code with ruff | ✅ |
|
|
158
|
+
| `format` | `format.check-docstrings` | Check docstring formatting with docformatter | ❌ |
|
|
159
|
+
| `format` | `format.fix-docstrings` | Format docstrings with docformatter | ✅ |
|
|
160
|
+
| `format` | `format.check-shell` | Check shell scripts with shellcheck | ❌ |
|
|
161
|
+
| `format` | `format.check-shell-format` | Check the format of shell scripts with shfmt | ❌ |
|
|
162
|
+
| `format` | `format.fix-shell` | Format shell scripts with shfmt | ✅ |
|
|
163
|
+
| `lint` | `lint.check-python` | Check linting with ruff | ❌ |
|
|
164
|
+
| `lint` | `lint.fix-python` | Fix auto-fixable linting issues with ruff | ✅ |
|
|
165
|
+
| `lint` | `lint.check-spelling` | Check the spelling with codespell | ❌ |
|
|
166
|
+
| `lint` | `lint.pre-commit` | Run all the pre-commit hooks | ✅ |
|
|
167
|
+
| `imports` | `imports.check-cycles` | Check for cyclic import dependencies | ❌ |
|
|
168
|
+
| `imports` | `imports.check-isolated` | Check that every module imports on its own | ❌ |
|
|
169
|
+
| `types` | `types.check` | Check type hints with ty (`--complete` also runs pyright) | ❌ |
|
|
170
|
+
| `test` | `test.doctest` | Run doctests on source code and markdown files | ❌ |
|
|
171
|
+
| `test` | `test.doctest-src` | Run doctests on source code | ❌ |
|
|
172
|
+
| `test` | `test.doctest-markdown` | Run doctests on Python examples in markdown files | ❌ |
|
|
173
|
+
| `test` | `test.unit` | Run unit tests | ❌ |
|
|
174
|
+
| `test` | `test.integration` | Run integration tests | ❌ |
|
|
175
|
+
| `test` | `test.functional` | Run functional tests | ❌ |
|
|
176
|
+
| `test` | `test.all` | Run unit, integration, and functional tests | ❌ |
|
|
177
|
+
| `test` | `test.coverage-report` | Generate an HTML/terminal report from existing coverage data | ❌ |
|
|
178
|
+
| `test` | `test.benchmark` | Run performance benchmarks | ❌ |
|
|
179
|
+
| `env` | `env.create-venv` | Create a virtual environment and install the project | ✅ |
|
|
180
|
+
| `env` | `env.install` | Install project dependencies and the package (editable) | ✅ |
|
|
181
|
+
| `env` | `env.check-tools` | Check which tools (ruff, pyright, ...) are available | ❌ |
|
|
182
|
+
| `env` | `env.update` | Update dependencies and pre-commit hooks | ✅ |
|
|
183
|
+
| `env` | `env.show-installed-packages` | Show the installed packages | ❌ |
|
|
184
|
+
| `env` | `env.show-python-config` | Show the Python configuration | ❌ |
|
|
185
|
+
| `release` | `release.build` | Build the package and verify installation (`--check` also validates metadata with twine) | ✅ |
|
|
186
|
+
| `release` | `release.publish` | Build and publish the package to PyPI | ✅ |
|
|
187
|
+
| `doc` | `doc.publish-dev` | Publish development (unstable) docs | ✅ |
|
|
188
|
+
| `doc` | `doc.publish-latest` | Publish latest (stable) docs | ✅ |
|
|
189
|
+
| `doc` | `doc.build` | Build the docs, failing on warnings (`mkdocs build --strict`) | ❌ |
|
|
190
|
+
| `doc` | `doc.serve` | Serve the docs locally | ❌ |
|
|
191
|
+
| `security` | `security.audit` | Audit the locked dependencies for known vulnerabilities with pip-audit | ❌ |
|
|
192
|
+
| `check` | `check.all` (or `check`) | Run the main read-only checks | ❌ |
|
|
193
|
+
| `fix` | `fix.all` (or `fix`) | Fix the lint and format issues | ✅ |
|
|
194
|
+
| `clean` | `clean.all` (or `clean`) | Remove build artifacts and caches | ✅ |
|
|
195
|
+
| `clean` | `clean.pycache` | Remove all `__pycache__` directories | ✅ |
|
|
196
|
+
| `config` | `config.show` | Show the resolved config and where each value comes from | ❌ |
|
|
197
|
+
|
|
198
|
+
`format.*` and `lint.*` follow a naming convention: read-only checks are
|
|
199
|
+
named `check_<target>`, and the matching in-place fixer is named
|
|
200
|
+
`fix_<target>` (e.g. `check_python`/`fix_python`), so the counterpart of a
|
|
201
|
+
task is always easy to find. Follow this convention when adding new tasks
|
|
202
|
+
to these namespaces.
|
|
203
|
+
|
|
204
|
+
For task-by-task details, options (like `--cov` on `test.*` tasks), and the
|
|
205
|
+
tools each one wraps, see the
|
|
206
|
+
[User Guide](https://durandtibo.github.io/invoke-tasklib/uguide/).
|
|
207
|
+
|
|
208
|
+
## Configuration
|
|
209
|
+
|
|
210
|
+
Only `tasklib.package.name` is required — everything else has a sensible
|
|
211
|
+
default derived from it:
|
|
212
|
+
|
|
213
|
+
```yaml
|
|
214
|
+
tasklib:
|
|
215
|
+
package:
|
|
216
|
+
name: my_package # required
|
|
217
|
+
import_name: my_package # default: <package.name> with - replaced by _
|
|
218
|
+
python_version: "3.14" # used by env.create-venv (default: the version that uv chooses)
|
|
219
|
+
paths:
|
|
220
|
+
src: src/my_package # default: src/<package.import_name>
|
|
221
|
+
tests: tests
|
|
222
|
+
unit_tests: tests/unit # default: <tests>/unit
|
|
223
|
+
integration_tests: tests/integration # default: <tests>/integration
|
|
224
|
+
functional_tests: tests/functional # default: <tests>/functional
|
|
225
|
+
benchmarks: tests/benchmarks # default: <tests>/benchmarks
|
|
226
|
+
docs_config: docs/mkdocs.yml
|
|
227
|
+
groups:
|
|
228
|
+
install: dev # dependency groups of env.install
|
|
229
|
+
update: dev,docs # dependency groups of env.update
|
|
230
|
+
test:
|
|
231
|
+
unit_timeout: 10 # seconds, also integration_timeout and functional_timeout
|
|
232
|
+
xdoctest: true # pytest --xdoctest (needs xdoctest)
|
|
233
|
+
timeout: true # pytest --timeout (needs pytest-timeout)
|
|
234
|
+
cov_fail_under: 90 # threshold of --cov (default: not set)
|
|
235
|
+
cov_reports: html,xml,term
|
|
236
|
+
types:
|
|
237
|
+
checker: ty # type checker of types.check: ty, pyright or mypy
|
|
238
|
+
check:
|
|
239
|
+
tasks: format-python,format-docstrings,lint,types,imports,unit # steps of check.all
|
|
240
|
+
cov: false # run the unit step of check.all with --cov
|
|
241
|
+
fix:
|
|
242
|
+
tasks: lint,format-python,format-docstrings # steps of fix.all
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
`check.tasks` also accepts `doctest`, `shell`, `spelling`, `docs` and `audit`; `fix.tasks` also
|
|
246
|
+
accepts `shell`. `invoke config.show` prints the resolved values and where each one comes from.
|
|
247
|
+
|
|
248
|
+
See the [Config reference](https://durandtibo.github.io/invoke-tasklib/uguide/config/)
|
|
249
|
+
for how each path default is derived.
|
|
250
|
+
|
|
251
|
+
Every key can also be set with an `INVOKE_TASKLIB_<SECTION>_<KEY>` environment variable, for example
|
|
252
|
+
`INVOKE_TASKLIB_PATHS_SRC=lib` or `INVOKE_TASKLIB_TEST_UNIT_TIMEOUT=30`, which wins over
|
|
253
|
+
`invoke.yaml`. An invalid value, an unknown key (with the closest valid key suggested) or a wrong
|
|
254
|
+
working directory exits with the code 2 before any command runs. For editor completion, the JSON
|
|
255
|
+
schema of the `tasklib` section is published at
|
|
256
|
+
<https://durandtibo.github.io/invoke-tasklib/schema.json> (`python -m invoke_tasklib.config` prints
|
|
257
|
+
it).
|
|
258
|
+
|
|
259
|
+
## Conventions
|
|
260
|
+
|
|
261
|
+
- **Arguments:** the tasks that run a tool take `--args` (extra arguments for the tool, as one
|
|
262
|
+
string, e.g. `--args "-k foo -x"`) and, for the tasks that work on files, `--paths` (files or
|
|
263
|
+
directories instead of the default ones). Both are quoted, so a glob or `~` reaches the tool as
|
|
264
|
+
it is.
|
|
265
|
+
- **Exit codes:** `0` the task passed, or had nothing to do (a `⏭️` line says why); `1` the checked
|
|
266
|
+
thing failed; `2` invalid usage or config; `127` a tool is missing. A missing program or Python
|
|
267
|
+
module is reported with the command that installs it.
|
|
268
|
+
- **Composite tasks:** `invoke check` runs the main read-only checks and `invoke fix` the fixers;
|
|
269
|
+
`--only`, `--skip` and `--keep-going` select the steps and report all the failures at the end.
|
|
270
|
+
- **Dangerous tasks ask first:** `env.create-venv` asks before it clears `.venv` and
|
|
271
|
+
`release.publish` checks the git state and asks before it uploads (`--yes` skips the question,
|
|
272
|
+
`--dry-run` publishes nothing). `clean` stays inside the project and keeps what git tracks.
|
|
273
|
+
- **ASCII output:** set `INVOKE_TASKLIB_ASCII=1` to replace the emojis of the messages with
|
|
274
|
+
`[ok]`, `[fail]` and `[skip]`.
|
|
275
|
+
|
|
276
|
+
## Composing a custom subset of tasks
|
|
277
|
+
|
|
278
|
+
Need a different set of tasks, or a one-off task alongside the shared ones?
|
|
279
|
+
Use `make_ns`, which returns a new collection each time, so adding or removing tasks never affects
|
|
280
|
+
other importers. Leave out the tasks you do not use (for example the ones that publish):
|
|
281
|
+
|
|
282
|
+
```python
|
|
283
|
+
# tasks.py
|
|
284
|
+
from invoke import task
|
|
285
|
+
from invoke_tasklib import make_ns
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
@task
|
|
289
|
+
def my_custom_task(c):
|
|
290
|
+
r"""Run a one-off command."""
|
|
291
|
+
c.run("echo hello")
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
ns = make_ns(exclude=["release.publish", "doc"])
|
|
295
|
+
ns.add_task(my_custom_task)
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
`tasks.py` is imported by Invoke as a top-level module, so a task defined in another file of the
|
|
299
|
+
project is imported with an absolute import (`from my_tasks import my_custom_task`), not a
|
|
300
|
+
relative one (`from . import my_custom_task`), which fails with an `ImportError`.
|
|
301
|
+
|
|
302
|
+
or keep only some of them with `include`, e.g. `make_ns(include=["lint", "test.unit"])`. The names
|
|
303
|
+
are namespaces (`"doc"`) or tasks (`"release.publish"`); an unknown name raises a `ValueError`. The
|
|
304
|
+
`make_ns()` with no argument has all the tasks (the former pre-built `invoke_tasklib.ns`, one
|
|
305
|
+
collection shared by every importer, was removed). Individual task modules can also be composed by
|
|
306
|
+
hand:
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
# tasks.py
|
|
310
|
+
from invoke import Collection, task
|
|
311
|
+
from invoke_tasklib import lint, testing
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@task
|
|
315
|
+
def my_custom_task(c):
|
|
316
|
+
r"""Run a one-off command."""
|
|
317
|
+
c.run("echo hello")
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
ns = Collection(lint, Collection.from_module(testing, name=testing.NAMESPACE), my_custom_task)
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
The modules of the `format`, `types` and `test` namespaces are named `formatting`, `typecheck`
|
|
324
|
+
and `testing` so that they do not shadow the standard library (`types`, `test`) or a builtin
|
|
325
|
+
(`format`); pass `name=module.NAMESPACE` (every task module has the name of its namespace in `NAMESPACE`)
|
|
326
|
+
to `Collection.from_module` to keep the task names.
|
|
327
|
+
|
|
328
|
+
Prefer adding a config knob to a shared task over forking it; reserve custom
|
|
329
|
+
composition for things that are genuinely one-off to a single project.
|
|
330
|
+
|
|
331
|
+
## API Stability
|
|
332
|
+
|
|
333
|
+
:warning: `invoke-tasklib` is under active development and its API is not
|
|
334
|
+
yet stable — pin a specific version in your project's dependencies for
|
|
335
|
+
consistent behavior across releases.
|
|
336
|
+
|
|
337
|
+
## Contributing
|
|
338
|
+
|
|
339
|
+
Contributions are welcome! Please open an issue first to discuss
|
|
340
|
+
significant changes. See the
|
|
341
|
+
[developer guide](https://durandtibo.github.io/invoke-tasklib/dev/development/)
|
|
342
|
+
for how to set up a development environment.
|
|
343
|
+
|
|
344
|
+
## License
|
|
345
|
+
|
|
346
|
+
`invoke-tasklib` is licensed under the BSD 3-Clause "New" or "Revised"
|
|
347
|
+
license available in
|
|
348
|
+
[LICENSE](https://github.com/durandtibo/invoke-tasklib/blob/main/LICENSE).
|