tempest-cli 0.2.0__tar.gz → 0.4.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.
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/CHANGELOG.md +76 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/PKG-INFO +38 -17
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/README.md +35 -15
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/changelog.en.md +42 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/changelog.md +41 -0
- tempest_cli-0.4.0/docs/commands.en.md +159 -0
- tempest_cli-0.4.0/docs/commands.md +156 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/configuration.en.md +6 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/configuration.md +6 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/index.en.md +6 -1
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/index.md +6 -1
- tempest_cli-0.4.0/docs/installation.en.md +112 -0
- tempest_cli-0.4.0/docs/installation.md +112 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/library.en.md +1 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/library.md +1 -0
- tempest_cli-0.4.0/docs/rules.en.md +252 -0
- tempest_cli-0.4.0/docs/rules.md +249 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/mkdocs.yml +3 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/pyproject.toml +17 -6
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tempest_cli/__init__.py +6 -4
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tempest_cli/lint.py +246 -15
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tempest_cli/main.py +121 -4
- tempest_cli-0.4.0/tests/test_fast.py +388 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tests/test_lint_runners.py +25 -4
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/uv.lock +29 -3
- tempest_cli-0.2.0/docs/commands.en.md +0 -82
- tempest_cli-0.2.0/docs/commands.md +0 -81
- tempest_cli-0.2.0/docs/installation.en.md +0 -90
- tempest_cli-0.2.0/docs/installation.md +0 -89
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/.github/workflows/ci.yml +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/.github/workflows/docs.yml +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/.github/workflows/release-pypi.yml +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/.gitignore +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/LICENSE +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/Makefile +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/pr-prompt.en.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/pr-prompt.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/reference.en.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/docs/reference.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tempest_cli/_templates/pull_request_template.en-US.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tempest_cli/_templates/pull_request_template.pt-BR.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tempest_cli/config.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tempest_cli/pr_prompt.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tempest_cli/py.typed +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tests/__init__.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tests/test_cli.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tests/test_config.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tests/test_lint_strictness.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.4.0}/tests/test_pr_prompt.py +0 -0
|
@@ -5,6 +5,82 @@ All notable changes to **tempest-cli** are listed below.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.0] — 2026-09-27
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`test --fast` and `check --fast`: the suite in parallel.** `--fast`
|
|
13
|
+
runs pytest as `pytest -n <workers> -p no:cacheprovider [target]`, with
|
|
14
|
+
pytest-xdist spreading the suite across the cores; `--workers` / `-w`
|
|
15
|
+
takes what `pytest -n` takes (an integer, `auto` — the default — or
|
|
16
|
+
`logical`) and is a usage error (exit 2) without `--fast`. The cache
|
|
17
|
+
plugin is off because several workers writing `.pytest_cache` at once
|
|
18
|
+
is a race that buys nothing. The target is forwarded and pytest's exit
|
|
19
|
+
code comes straight back, as in the serial run. It is a flag rather
|
|
20
|
+
than a `test fast` subcommand because `test` already takes a
|
|
21
|
+
positional path: `test fast` keeps meaning the `fast/` folder.
|
|
22
|
+
Requested in mauriciobenjamin700/tempest-fastapi-sdk#328.
|
|
23
|
+
|
|
24
|
+
Measured on a machine with 6 physical cores / 12 threads. On this
|
|
25
|
+
package's own suite (100 tests, warm environment, three runs each)
|
|
26
|
+
`tempest-cli test` took 2.2 s and `tempest-cli test --fast` 1.6–1.7 s
|
|
27
|
+
(12 workers: no `psutil` here, so `auto` counts logical CPUs) — worker
|
|
28
|
+
start-up is most of the fast run at this size. On the
|
|
29
|
+
tempest-fastapi-sdk suite (10 218 tests, one run each, same
|
|
30
|
+
invocation), pytest reported 2127 s serial and 411 s with `--fast`
|
|
31
|
+
(`auto` → 6 workers, since `psutil` is installed there), about 5.2x;
|
|
32
|
+
both runs ended with the same 10 failures, all from `ruff` being a dead
|
|
33
|
+
pyenv shim on that `PATH`.
|
|
34
|
+
|
|
35
|
+
`auto` is pytest-xdist's rule, not ours: physical cores when `psutil`
|
|
36
|
+
is importable, logical CPUs otherwise. `-w logical` asks for the
|
|
37
|
+
threads explicitly.
|
|
38
|
+
|
|
39
|
+
- **A missing pytest-xdist is a sentence, not `unrecognized arguments:
|
|
40
|
+
-n`.** Before spawning, `--fast` asks the interpreter pytest will run
|
|
41
|
+
under — read from the pytest script's shebang, its sibling `python`,
|
|
42
|
+
or the same `uv run --with pytest` overlay — whether it can import
|
|
43
|
+
`xdist`. When it cannot, the message names `pytest-xdist`,
|
|
44
|
+
`tempest-cli[tools]` and `tempest-fastapi-sdk[tests]`, and the exit code
|
|
45
|
+
is 127, with no traceback. `check --fast` makes that check before its
|
|
46
|
+
first step. A probe that cannot run at all is not taken as "missing":
|
|
47
|
+
the run proceeds and pytest reports for itself.
|
|
48
|
+
|
|
49
|
+
- **`run_pytest(..., fast=, workers=)` and `run_full_check(..., fast=,
|
|
50
|
+
workers=)`** for library callers — keyword-only, defaulting to the
|
|
51
|
+
serial run, so every existing call is unchanged. `DEFAULT_FAST_WORKERS`,
|
|
52
|
+
`XDIST_MODULE` and `MISSING_TOOL_EXIT_CODE` are exported from
|
|
53
|
+
`tempest_cli.lint`.
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- **`[tools]` now carries `pytest-xdist>=3.8.0`** next to mypy and pytest,
|
|
58
|
+
so the bundle is enough for `--fast`. Its `requires-dist`
|
|
59
|
+
(`execnet>=2.1`, `pytest>=7.0.0`) has no upper bound.
|
|
60
|
+
|
|
61
|
+
## [0.3.0] — 2026-08-15
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
|
|
65
|
+
- **`ruff` now ships with the package.** It moved from the `[tools]`
|
|
66
|
+
extra into the runtime dependencies, so `uv add --dev tempest-cli` is
|
|
67
|
+
enough for `lint`, `fix`, `format` and `fmt-check` to run — no second
|
|
68
|
+
install, and no dependency on `uv` being around to fetch one. The cost
|
|
69
|
+
is nil: ruff is a static binary wheel with no Python dependencies of
|
|
70
|
+
its own, so no bound of its reaches a consumer's resolution.
|
|
71
|
+
|
|
72
|
+
`mypy` and `pytest` stay out on purpose. A mypy bump changes which
|
|
73
|
+
errors a codebase reports and pytest has to match the suite and its
|
|
74
|
+
plugins — those are the project's call. `[tools]` now installs exactly
|
|
75
|
+
those two.
|
|
76
|
+
|
|
77
|
+
- **The project's environment is searched before the CLI's own.** With
|
|
78
|
+
ruff bundled, the CLI's environment always has one; looking there
|
|
79
|
+
first would silently override a version the project pinned whenever
|
|
80
|
+
`tempest-cli` is installed apart from it (`uv tool install`, pipx).
|
|
81
|
+
The order is now `$VIRTUAL_ENV` → nearest `.venv` → the CLI's own
|
|
82
|
+
environment → `PATH` → `uv run --with`.
|
|
83
|
+
|
|
8
84
|
## [0.2.0] — 2026-08-15
|
|
9
85
|
|
|
10
86
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tempest-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Framework-agnostic quality gate for Python projects: ruff + mypy + pytest behind one command, with a typing-strictness dial and a PR-description prompt generator.
|
|
5
5
|
Project-URL: Homepage, https://github.com/mauriciobenjamin700/tempest-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/mauriciobenjamin700/tempest-cli
|
|
@@ -22,11 +22,12 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
|
22
22
|
Classifier: Topic :: Utilities
|
|
23
23
|
Classifier: Typing :: Typed
|
|
24
24
|
Requires-Python: >=3.11
|
|
25
|
+
Requires-Dist: ruff>=0.8.0
|
|
25
26
|
Requires-Dist: typer>=0.12.0
|
|
26
27
|
Provides-Extra: tools
|
|
27
28
|
Requires-Dist: mypy>=1.13.0; extra == 'tools'
|
|
29
|
+
Requires-Dist: pytest-xdist>=3.8.0; extra == 'tools'
|
|
28
30
|
Requires-Dist: pytest>=8.3.3; extra == 'tools'
|
|
29
|
-
Requires-Dist: ruff>=0.8.0; extra == 'tools'
|
|
30
31
|
Description-Content-Type: text/markdown
|
|
31
32
|
|
|
32
33
|
# tempest-cli
|
|
@@ -42,7 +43,8 @@ One command for the quality gate of any Python project — `ruff` +
|
|
|
42
43
|
`pyproject.toml` instead of in four different Makefile targets.
|
|
43
44
|
|
|
44
45
|
Framework-agnostic on purpose: Django, Flask, Litestar, FastAPI, a
|
|
45
|
-
library, a script.
|
|
46
|
+
library, a script. It brings `ruff` along, so the gate runs the moment
|
|
47
|
+
you install it; `typer` is the only other runtime dependency.
|
|
46
48
|
|
|
47
49
|
```bash
|
|
48
50
|
uv add --dev tempest-cli
|
|
@@ -72,8 +74,8 @@ remembered to pass.
|
|
|
72
74
|
| `tempest-cli format` | `ruff format` (writes) |
|
|
73
75
|
| `tempest-cli fmt-check` | `ruff format --check` (read-only) |
|
|
74
76
|
| `tempest-cli type` | `mypy` |
|
|
75
|
-
| `tempest-cli test` | `pytest` |
|
|
76
|
-
| `tempest-cli check` | all four, in order, stopping at the first failure |
|
|
77
|
+
| `tempest-cli test` | `pytest` (`--fast` spreads it across cores with pytest-xdist: `-n auto -p no:cacheprovider`, `-w N` to choose) |
|
|
78
|
+
| `tempest-cli check` | all four, in order, stopping at the first failure (`--fast` runs the test step in parallel) |
|
|
77
79
|
| `tempest-cli pr-prompt` | builds the prompt that makes an AI write this branch's PR description |
|
|
78
80
|
|
|
79
81
|
Every command takes an optional path (`tempest-cli lint src/`) and
|
|
@@ -103,6 +105,13 @@ they avoid `Any`.
|
|
|
103
105
|
Override per run with `--strictness` / `-s`. Absent config means
|
|
104
106
|
`standard`.
|
|
105
107
|
|
|
108
|
+
Everything that is *not* typing — silencing an untyped library, skipping
|
|
109
|
+
generated code, dropping a rule that does not fit your framework — is
|
|
110
|
+
ordinary `[tool.ruff]` / `[tool.mypy]` configuration. The recipes,
|
|
111
|
+
including the one that takes a legacy Django project to a green gate,
|
|
112
|
+
are in **[Tuning the rules](https://mauriciobenjamin700.github.io/tempest-cli/rules/)**
|
|
113
|
+
([EN](https://mauriciobenjamin700.github.io/tempest-cli/en/rules/)).
|
|
114
|
+
|
|
106
115
|
## PR descriptions from the branch itself
|
|
107
116
|
|
|
108
117
|
```bash
|
|
@@ -141,24 +150,36 @@ cli: typer.Typer = typer.Typer(name="mytool")
|
|
|
141
150
|
register_commands(cli)
|
|
142
151
|
```
|
|
143
152
|
|
|
144
|
-
##
|
|
145
|
-
|
|
146
|
-
`tempest-cli` shells out to whatever `ruff`, `mypy` and `pytest` it
|
|
147
|
-
finds — it does not pin them, so your project chooses the versions. The
|
|
148
|
-
lookup runs in this order:
|
|
153
|
+
## Where the tools come from
|
|
149
154
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
**`ruff` comes with the package** — six of the eight commands are ruff,
|
|
156
|
+
so `lint`, `fix`, `format` and `fmt-check` work straight after
|
|
157
|
+
`uv add --dev tempest-cli`, with nothing else to install. It is a static
|
|
158
|
+
binary wheel with no Python dependencies of its own, so nothing of its
|
|
159
|
+
propagates into your resolution.
|
|
155
160
|
|
|
156
|
-
|
|
161
|
+
`mypy` and `pytest` are deliberately left to you — a mypy bump changes
|
|
162
|
+
which errors your code reports, and pytest has to match your plugins and
|
|
163
|
+
your suite. Add them yourself, or take the bundle:
|
|
157
164
|
|
|
158
165
|
```bash
|
|
159
|
-
uv add --dev "tempest-cli[tools]"
|
|
166
|
+
uv add --dev "tempest-cli[tools]" # mypy + pytest + pytest-xdist
|
|
160
167
|
```
|
|
161
168
|
|
|
169
|
+
`pytest-xdist` is what `test --fast` runs the suite with; its
|
|
170
|
+
`requires-dist` (`execnet>=2.1`, `pytest>=7.0.0`) carries no upper bound.
|
|
171
|
+
|
|
172
|
+
Whatever you pin wins over the bundled ruff. The lookup runs in this
|
|
173
|
+
order:
|
|
174
|
+
|
|
175
|
+
1. the project's environment — `$VIRTUAL_ENV`, then the nearest `.venv`
|
|
176
|
+
up the tree;
|
|
177
|
+
2. the environment `tempest-cli` itself runs from (where the bundled
|
|
178
|
+
ruff lives);
|
|
179
|
+
3. `PATH`, skipping a pyenv/asdf shim that dispatches nowhere (the one
|
|
180
|
+
that answers `pyenv: ruff: command not found`);
|
|
181
|
+
4. `uv run --with <tool> <tool>`, when `uv` is available.
|
|
182
|
+
|
|
162
183
|
## Relationship with tempest-fastapi-sdk
|
|
163
184
|
|
|
164
185
|
This package was extracted from
|
|
@@ -11,7 +11,8 @@ One command for the quality gate of any Python project — `ruff` +
|
|
|
11
11
|
`pyproject.toml` instead of in four different Makefile targets.
|
|
12
12
|
|
|
13
13
|
Framework-agnostic on purpose: Django, Flask, Litestar, FastAPI, a
|
|
14
|
-
library, a script.
|
|
14
|
+
library, a script. It brings `ruff` along, so the gate runs the moment
|
|
15
|
+
you install it; `typer` is the only other runtime dependency.
|
|
15
16
|
|
|
16
17
|
```bash
|
|
17
18
|
uv add --dev tempest-cli
|
|
@@ -41,8 +42,8 @@ remembered to pass.
|
|
|
41
42
|
| `tempest-cli format` | `ruff format` (writes) |
|
|
42
43
|
| `tempest-cli fmt-check` | `ruff format --check` (read-only) |
|
|
43
44
|
| `tempest-cli type` | `mypy` |
|
|
44
|
-
| `tempest-cli test` | `pytest` |
|
|
45
|
-
| `tempest-cli check` | all four, in order, stopping at the first failure |
|
|
45
|
+
| `tempest-cli test` | `pytest` (`--fast` spreads it across cores with pytest-xdist: `-n auto -p no:cacheprovider`, `-w N` to choose) |
|
|
46
|
+
| `tempest-cli check` | all four, in order, stopping at the first failure (`--fast` runs the test step in parallel) |
|
|
46
47
|
| `tempest-cli pr-prompt` | builds the prompt that makes an AI write this branch's PR description |
|
|
47
48
|
|
|
48
49
|
Every command takes an optional path (`tempest-cli lint src/`) and
|
|
@@ -72,6 +73,13 @@ they avoid `Any`.
|
|
|
72
73
|
Override per run with `--strictness` / `-s`. Absent config means
|
|
73
74
|
`standard`.
|
|
74
75
|
|
|
76
|
+
Everything that is *not* typing — silencing an untyped library, skipping
|
|
77
|
+
generated code, dropping a rule that does not fit your framework — is
|
|
78
|
+
ordinary `[tool.ruff]` / `[tool.mypy]` configuration. The recipes,
|
|
79
|
+
including the one that takes a legacy Django project to a green gate,
|
|
80
|
+
are in **[Tuning the rules](https://mauriciobenjamin700.github.io/tempest-cli/rules/)**
|
|
81
|
+
([EN](https://mauriciobenjamin700.github.io/tempest-cli/en/rules/)).
|
|
82
|
+
|
|
75
83
|
## PR descriptions from the branch itself
|
|
76
84
|
|
|
77
85
|
```bash
|
|
@@ -110,24 +118,36 @@ cli: typer.Typer = typer.Typer(name="mytool")
|
|
|
110
118
|
register_commands(cli)
|
|
111
119
|
```
|
|
112
120
|
|
|
113
|
-
##
|
|
114
|
-
|
|
115
|
-
`tempest-cli` shells out to whatever `ruff`, `mypy` and `pytest` it
|
|
116
|
-
finds — it does not pin them, so your project chooses the versions. The
|
|
117
|
-
lookup runs in this order:
|
|
121
|
+
## Where the tools come from
|
|
118
122
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
**`ruff` comes with the package** — six of the eight commands are ruff,
|
|
124
|
+
so `lint`, `fix`, `format` and `fmt-check` work straight after
|
|
125
|
+
`uv add --dev tempest-cli`, with nothing else to install. It is a static
|
|
126
|
+
binary wheel with no Python dependencies of its own, so nothing of its
|
|
127
|
+
propagates into your resolution.
|
|
124
128
|
|
|
125
|
-
|
|
129
|
+
`mypy` and `pytest` are deliberately left to you — a mypy bump changes
|
|
130
|
+
which errors your code reports, and pytest has to match your plugins and
|
|
131
|
+
your suite. Add them yourself, or take the bundle:
|
|
126
132
|
|
|
127
133
|
```bash
|
|
128
|
-
uv add --dev "tempest-cli[tools]"
|
|
134
|
+
uv add --dev "tempest-cli[tools]" # mypy + pytest + pytest-xdist
|
|
129
135
|
```
|
|
130
136
|
|
|
137
|
+
`pytest-xdist` is what `test --fast` runs the suite with; its
|
|
138
|
+
`requires-dist` (`execnet>=2.1`, `pytest>=7.0.0`) carries no upper bound.
|
|
139
|
+
|
|
140
|
+
Whatever you pin wins over the bundled ruff. The lookup runs in this
|
|
141
|
+
order:
|
|
142
|
+
|
|
143
|
+
1. the project's environment — `$VIRTUAL_ENV`, then the nearest `.venv`
|
|
144
|
+
up the tree;
|
|
145
|
+
2. the environment `tempest-cli` itself runs from (where the bundled
|
|
146
|
+
ruff lives);
|
|
147
|
+
3. `PATH`, skipping a pyenv/asdf shim that dispatches nowhere (the one
|
|
148
|
+
that answers `pyenv: ruff: command not found`);
|
|
149
|
+
4. `uv run --with <tool> <tool>`, when `uv` is available.
|
|
150
|
+
|
|
131
151
|
## Relationship with tempest-fastapi-sdk
|
|
132
152
|
|
|
133
153
|
This package was extracted from
|
|
@@ -3,6 +3,48 @@
|
|
|
3
3
|
The full history lives in the repository's
|
|
4
4
|
[`CHANGELOG.md`](https://github.com/mauriciobenjamin700/tempest-cli/blob/main/CHANGELOG.md).
|
|
5
5
|
|
|
6
|
+
## [0.4.0] — 2026-09-27
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **`test --fast` and `check --fast`: the suite in parallel.** Runs
|
|
11
|
+
`pytest -n <workers> -p no:cacheprovider [target]` with pytest-xdist;
|
|
12
|
+
`--workers` / `-w` takes what `pytest -n` takes (an integer, `auto` —
|
|
13
|
+
the default — or `logical`) and is a usage error without `--fast`. The
|
|
14
|
+
target is forwarded and pytest's exit code comes back untranslated. It
|
|
15
|
+
is a flag, not a subcommand, because `test fast` keeps meaning the
|
|
16
|
+
`fast/` folder. [Details](commands.md#the-suite-in-parallel-fast).
|
|
17
|
+
- **A missing pytest-xdist is a sentence, not `unrecognized arguments:
|
|
18
|
+
-n`.** `--fast` asks the interpreter that will run pytest whether it
|
|
19
|
+
can import `xdist`; when it cannot, the message names the package and
|
|
20
|
+
the extras (`tempest-cli[tools]`, `tempest-fastapi-sdk[tests]`) and the
|
|
21
|
+
exit code is 127, with no traceback. Under `check --fast` the check
|
|
22
|
+
comes before the first step.
|
|
23
|
+
- **`run_pytest` / `run_full_check` gain `fast=` and `workers=`**,
|
|
24
|
+
keyword-only, serial by default.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- **`[tools]` now carries `pytest-xdist>=3.8.0`.** No upper bound in its
|
|
29
|
+
`requires-dist` (`execnet>=2.1`, `pytest>=7.0.0`).
|
|
30
|
+
|
|
31
|
+
## [0.3.0] — 2026-08-15
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- **`ruff` now ships with the package.** It left the `[tools]` extra for
|
|
36
|
+
the runtime dependencies, so `uv add --dev tempest-cli` is enough for
|
|
37
|
+
`lint`, `fix`, `format` and `fmt-check` to run. The cost is nil: ruff
|
|
38
|
+
is a static binary wheel with no Python dependencies of its own, so no
|
|
39
|
+
bound of its reaches a consumer's resolution. `mypy` and `pytest` stay
|
|
40
|
+
out on purpose; `[tools]` now installs exactly those two.
|
|
41
|
+
- **The project's environment is searched before the CLI's own.** With
|
|
42
|
+
ruff bundled, the CLI's environment always has one — looking there
|
|
43
|
+
first would silently override a version the project pinned whenever
|
|
44
|
+
`tempest-cli` lives apart from it (`uv tool install`, pipx). The order
|
|
45
|
+
is now `$VIRTUAL_ENV` → nearest `.venv` → the CLI's environment →
|
|
46
|
+
`PATH` → `uv run --with`.
|
|
47
|
+
|
|
6
48
|
## [0.2.0] — 2026-08-15
|
|
7
49
|
|
|
8
50
|
### Added
|
|
@@ -4,6 +4,47 @@ O histórico completo vive no
|
|
|
4
4
|
[`CHANGELOG.md`](https://github.com/mauriciobenjamin700/tempest-cli/blob/main/CHANGELOG.md)
|
|
5
5
|
do repositório.
|
|
6
6
|
|
|
7
|
+
## [0.4.0] — 2026-09-27
|
|
8
|
+
|
|
9
|
+
### Adicionado
|
|
10
|
+
|
|
11
|
+
- **`test --fast` e `check --fast`: a suíte em paralelo.** Roda
|
|
12
|
+
`pytest -n <workers> -p no:cacheprovider [alvo]` com o pytest-xdist;
|
|
13
|
+
`--workers` / `-w` aceita o que o `pytest -n` aceita (inteiro, `auto` —
|
|
14
|
+
o padrão — ou `logical`) e é erro de uso sem `--fast`. O alvo é
|
|
15
|
+
repassado e o código de saída do pytest volta sem tradução. É flag, e
|
|
16
|
+
não subcomando, porque `test fast` continua significando a pasta
|
|
17
|
+
`fast/`. [Detalhes](commands.md#a-suite-em-paralelo-fast).
|
|
18
|
+
- **pytest-xdist ausente vira frase, não `unrecognized arguments: -n`.**
|
|
19
|
+
O `--fast` pergunta ao interpretador que vai rodar o pytest se ele
|
|
20
|
+
importa o `xdist`; faltando, a mensagem nomeia o pacote e os extras
|
|
21
|
+
(`tempest-cli[tools]`, `tempest-fastapi-sdk[tests]`) e a saída é 127,
|
|
22
|
+
sem traceback. No `check --fast` a checagem vem antes do primeiro passo.
|
|
23
|
+
- **`run_pytest` / `run_full_check` ganham `fast=` e `workers=`**
|
|
24
|
+
keyword-only, com default serial.
|
|
25
|
+
|
|
26
|
+
### Mudado
|
|
27
|
+
|
|
28
|
+
- **O `[tools]` agora leva `pytest-xdist>=3.8.0`.** Sem teto no
|
|
29
|
+
`requires-dist` (`execnet>=2.1`, `pytest>=7.0.0`).
|
|
30
|
+
|
|
31
|
+
## [0.3.0] — 2026-08-15
|
|
32
|
+
|
|
33
|
+
### Mudado
|
|
34
|
+
|
|
35
|
+
- **O `ruff` agora vem junto com o pacote.** Saiu do extra `[tools]` e
|
|
36
|
+
virou dependência: `uv add --dev tempest-cli` já basta para `lint`,
|
|
37
|
+
`fix`, `format` e `fmt-check` rodarem. Custo zero — o ruff é binário
|
|
38
|
+
estático, sem dependência Python, então nenhum limite dele entra na
|
|
39
|
+
resolução de quem instala. `mypy` e `pytest` continuam de fora de
|
|
40
|
+
propósito; `[tools]` agora instala exatamente esses dois.
|
|
41
|
+
- **O ambiente do projeto passa a ser procurado antes do da CLI.** Com o
|
|
42
|
+
ruff embutido, o ambiente da CLI sempre tem um — procurar ali primeiro
|
|
43
|
+
sobrescreveria em silêncio a versão que o projeto fixou quando o
|
|
44
|
+
`tempest-cli` mora fora dele (`uv tool install`, pipx). A ordem agora é
|
|
45
|
+
`$VIRTUAL_ENV` → `.venv` mais próximo → ambiente da CLI → `PATH` →
|
|
46
|
+
`uv run --with`.
|
|
47
|
+
|
|
7
48
|
## [0.2.0] — 2026-08-15
|
|
8
49
|
|
|
9
50
|
### Adicionado
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Commands
|
|
2
|
+
|
|
3
|
+
Eight commands. All take an optional path and return the underlying
|
|
4
|
+
tool's exit code.
|
|
5
|
+
|
|
6
|
+
| Command | Runs |
|
|
7
|
+
| --- | --- |
|
|
8
|
+
| `lint` | `ruff check` |
|
|
9
|
+
| `fix` | `ruff check --fix` then `ruff format` |
|
|
10
|
+
| `format` | `ruff format` (writes) |
|
|
11
|
+
| `fmt-check` | `ruff format --check` (read-only) |
|
|
12
|
+
| `type` | `mypy` |
|
|
13
|
+
| `test` | `pytest` |
|
|
14
|
+
| `check` | the four above, in order, stopping at the first failure |
|
|
15
|
+
| `pr-prompt` | builds the PR-description prompt — [its own page](pr-prompt.md) |
|
|
16
|
+
|
|
17
|
+
!!! tip "`tc` is the short form"
|
|
18
|
+
The package installs `tempest-cli` and `tc` pointing at the same
|
|
19
|
+
program. The examples use the long name; `tc check`, `tc fix` and
|
|
20
|
+
`tc type -s strict` work exactly the same.
|
|
21
|
+
|
|
22
|
+
## The full gate
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
tempest-cli check # the whole project
|
|
26
|
+
tempest-cli check src/ # a single path
|
|
27
|
+
tempest-cli check -s strict # with raised typing strictness for this run
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The order is deliberate: **lint → formatting → types → tests**. What
|
|
31
|
+
fails fastest and is cheapest to fix comes first, and the run stops at
|
|
32
|
+
the first failure — there is no point running the whole suite when the
|
|
33
|
+
imports are unsorted.
|
|
34
|
+
|
|
35
|
+
## Fixing what can be fixed
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
tempest-cli fix # safe autofixes + formatting
|
|
39
|
+
tempest-cli fix --unsafe # also ruff's risky autofixes
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`fix` makes two passes: `ruff check --fix` (sorts and dedupes imports,
|
|
43
|
+
drops unused ones, normalizes quotes) and then `ruff format`
|
|
44
|
+
(indentation, line length, blank lines).
|
|
45
|
+
|
|
46
|
+
!!! warning "`--unsafe` can change behavior"
|
|
47
|
+
Ruff's "unsafe" autofixes are the ones that may alter semantics.
|
|
48
|
+
They are off by default. Turned them on? Read the `git diff` before
|
|
49
|
+
committing.
|
|
50
|
+
|
|
51
|
+
## One at a time
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
tempest-cli lint src/
|
|
55
|
+
tempest-cli fmt-check
|
|
56
|
+
tempest-cli type mypackage
|
|
57
|
+
tempest-cli test tests/unit
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`test` forwards the path to pytest as a filter; with no argument it runs
|
|
61
|
+
the whole suite.
|
|
62
|
+
|
|
63
|
+
## The suite in parallel: `--fast`
|
|
64
|
+
|
|
65
|
+
A suite whose tests are already isolated (a database per test, no global
|
|
66
|
+
state) pays the serial time and buys nothing for it. `--fast` spreads the
|
|
67
|
+
suite across the cores with
|
|
68
|
+
[pytest-xdist](https://pytest-xdist.readthedocs.io/):
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
tempest-cli test --fast # -n auto: one worker per core
|
|
72
|
+
tempest-cli test --fast -w 4 # four workers
|
|
73
|
+
tempest-cli test tests/unit --fast # the target is still forwarded
|
|
74
|
+
tempest-cli check --fast # the full gate, with the test step in parallel
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Underneath it becomes `pytest -n <workers> -p no:cacheprovider [target]`.
|
|
78
|
+
`-p no:cacheprovider` is there because several workers writing
|
|
79
|
+
`.pytest_cache` at once is a race that buys nothing — and that cache is
|
|
80
|
+
what `--lf` / `--ff` read, so those two remain a serial-run affair.
|
|
81
|
+
|
|
82
|
+
`--workers` (`-w`) takes what `pytest -n` takes: an integer, `auto` (the
|
|
83
|
+
default) or `logical`. Without `--fast` it is a usage error (exit 2)
|
|
84
|
+
instead of being silently ignored.
|
|
85
|
+
|
|
86
|
+
!!! info "`auto` counts physical cores when `psutil` is installed"
|
|
87
|
+
pytest-xdist decides: with `psutil` importable, `auto` is the number of
|
|
88
|
+
**physical** cores; without it, the number of logical CPUs. On a machine
|
|
89
|
+
with 6 cores and 12 threads, with `psutil` in the environment, `auto`
|
|
90
|
+
started `created: 6/6 workers`. Want the 12 threads? `-w logical` or
|
|
91
|
+
`-w 12`.
|
|
92
|
+
|
|
93
|
+
!!! note "Why a flag, not `tempest-cli test fast`"
|
|
94
|
+
`test` already takes a positional path. `test fast` keeps meaning
|
|
95
|
+
"run pytest on the `fast/` folder" — a subcommand by that name would
|
|
96
|
+
break anyone who has one.
|
|
97
|
+
|
|
98
|
+
### Without pytest-xdist
|
|
99
|
+
|
|
100
|
+
Before running anything, the CLI asks **the very interpreter that will
|
|
101
|
+
run pytest** whether it can import `xdist` — not the CLI's own
|
|
102
|
+
interpreter, which under `uv tool install` or pipx lives in a different
|
|
103
|
+
environment. When it is missing, the message names what to install and
|
|
104
|
+
the exit code is **127**, with no traceback:
|
|
105
|
+
|
|
106
|
+
```console
|
|
107
|
+
$ tempest-cli test --fast
|
|
108
|
+
error: --fast needs pytest-xdist, which is not installed in the environment pytest runs in (.venv/bin/pytest). Install it with 'uv add --dev pytest-xdist' — or a bundle that carries it, 'uv add --dev "tempest-cli[tools]"' or 'uv add --dev "tempest-fastapi-sdk[tests]"' — and retry, or drop --fast to run the suite serially.
|
|
109
|
+
$ echo $?
|
|
110
|
+
127
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Under `check --fast` the check happens **before** the first step: there
|
|
114
|
+
is no point waiting for lint and mypy to finish to learn the tests will
|
|
115
|
+
not run.
|
|
116
|
+
|
|
117
|
+
### A test that fails only in parallel
|
|
118
|
+
|
|
119
|
+
Parallelism exposes tests that depend on order or on an idle machine:
|
|
120
|
+
two tests writing the same file, the same port, a module-level global, a
|
|
121
|
+
fixed `sleep` waiting for something that takes longer once every core is
|
|
122
|
+
busy. Before treating the failure as a regression, run the test **alone
|
|
123
|
+
and serially**:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
tempest-cli test "tests/test_scheduler.py::test_lease_expires"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- **It passes alone**: the defect is the test's isolation, not the change
|
|
130
|
+
under review. Fix the test (a file under `tmp_path`, a free port, wait
|
|
131
|
+
on a condition instead of a `sleep`).
|
|
132
|
+
- **It fails alone too**: it is a real regression.
|
|
133
|
+
|
|
134
|
+
## What each returns
|
|
135
|
+
|
|
136
|
+
The exit code is the tool's own, untranslated:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
tempest-cli lint; echo "exited $?"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
There is exactly one code of its own: **127**, when the tool is in none
|
|
143
|
+
of the places the CLI looks — the run's environment, `PATH`, `uv run
|
|
144
|
+
--with` — and the message then names what was missing and how to install
|
|
145
|
+
it. The lookup order is in
|
|
146
|
+
[Installation](installation.md#where-ruff-mypy-and-pytest-come-from).
|
|
147
|
+
The same 127 comes out of `--fast` when pytest-xdist is not in pytest's
|
|
148
|
+
environment.
|
|
149
|
+
|
|
150
|
+
## Recap
|
|
151
|
+
|
|
152
|
+
- `check` is lint + fmt-check + type + test, in order, stopping at the
|
|
153
|
+
first failure.
|
|
154
|
+
- `fix` is the pass that repairs; `--unsafe` only when you will review.
|
|
155
|
+
- `test --fast` / `check --fast` run the suite with pytest-xdist
|
|
156
|
+
(`-n auto`, `-w N` to choose); a test that fails only in parallel is
|
|
157
|
+
checked by running it alone.
|
|
158
|
+
- Exit codes are the tools'; 127 means a missing tool (or the
|
|
159
|
+
pytest-xdist `--fast` needs).
|