tempest-cli 0.2.0__tar.gz → 0.3.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.3.0}/CHANGELOG.md +23 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/PKG-INFO +24 -14
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/README.md +22 -12
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/changelog.en.md +17 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/changelog.md +17 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/index.en.md +3 -1
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/index.md +3 -1
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/installation.en.md +42 -25
- tempest_cli-0.3.0/docs/installation.md +107 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/pyproject.toml +13 -6
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tempest_cli/__init__.py +6 -4
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tempest_cli/lint.py +15 -8
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tests/test_lint_runners.py +25 -4
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/uv.lock +3 -3
- tempest_cli-0.2.0/docs/installation.md +0 -89
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/.github/workflows/ci.yml +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/.github/workflows/docs.yml +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/.github/workflows/release-pypi.yml +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/.gitignore +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/LICENSE +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/Makefile +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/commands.en.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/commands.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/configuration.en.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/configuration.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/library.en.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/library.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/pr-prompt.en.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/pr-prompt.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/reference.en.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/docs/reference.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/mkdocs.yml +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tempest_cli/_templates/pull_request_template.en-US.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tempest_cli/_templates/pull_request_template.pt-BR.md +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tempest_cli/config.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tempest_cli/main.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tempest_cli/pr_prompt.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tempest_cli/py.typed +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tests/__init__.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tests/test_cli.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tests/test_config.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tests/test_lint_strictness.py +0 -0
- {tempest_cli-0.2.0 → tempest_cli-0.3.0}/tests/test_pr_prompt.py +0 -0
|
@@ -5,6 +5,29 @@ 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.3.0] — 2026-08-15
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **`ruff` now ships with the package.** It moved from the `[tools]`
|
|
13
|
+
extra into the runtime dependencies, so `uv add --dev tempest-cli` is
|
|
14
|
+
enough for `lint`, `fix`, `format` and `fmt-check` to run — no second
|
|
15
|
+
install, and no dependency on `uv` being around to fetch one. The cost
|
|
16
|
+
is nil: ruff is a static binary wheel with no Python dependencies of
|
|
17
|
+
its own, so no bound of its reaches a consumer's resolution.
|
|
18
|
+
|
|
19
|
+
`mypy` and `pytest` stay out on purpose. A mypy bump changes which
|
|
20
|
+
errors a codebase reports and pytest has to match the suite and its
|
|
21
|
+
plugins — those are the project's call. `[tools]` now installs exactly
|
|
22
|
+
those two.
|
|
23
|
+
|
|
24
|
+
- **The project's environment is searched before the CLI's own.** With
|
|
25
|
+
ruff bundled, the CLI's environment always has one; looking there
|
|
26
|
+
first would silently override a version the project pinned whenever
|
|
27
|
+
`tempest-cli` is installed apart from it (`uv tool install`, pipx).
|
|
28
|
+
The order is now `$VIRTUAL_ENV` → nearest `.venv` → the CLI's own
|
|
29
|
+
environment → `PATH` → `uv run --with`.
|
|
30
|
+
|
|
8
31
|
## [0.2.0] — 2026-08-15
|
|
9
32
|
|
|
10
33
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tempest-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.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,11 @@ 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'
|
|
28
29
|
Requires-Dist: pytest>=8.3.3; extra == 'tools'
|
|
29
|
-
Requires-Dist: ruff>=0.8.0; extra == 'tools'
|
|
30
30
|
Description-Content-Type: text/markdown
|
|
31
31
|
|
|
32
32
|
# tempest-cli
|
|
@@ -42,7 +42,8 @@ One command for the quality gate of any Python project — `ruff` +
|
|
|
42
42
|
`pyproject.toml` instead of in four different Makefile targets.
|
|
43
43
|
|
|
44
44
|
Framework-agnostic on purpose: Django, Flask, Litestar, FastAPI, a
|
|
45
|
-
library, a script.
|
|
45
|
+
library, a script. It brings `ruff` along, so the gate runs the moment
|
|
46
|
+
you install it; `typer` is the only other runtime dependency.
|
|
46
47
|
|
|
47
48
|
```bash
|
|
48
49
|
uv add --dev tempest-cli
|
|
@@ -141,24 +142,33 @@ cli: typer.Typer = typer.Typer(name="mytool")
|
|
|
141
142
|
register_commands(cli)
|
|
142
143
|
```
|
|
143
144
|
|
|
144
|
-
##
|
|
145
|
+
## Where the tools come from
|
|
145
146
|
|
|
146
|
-
`
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
**`ruff` comes with the package** — six of the eight commands are ruff,
|
|
148
|
+
so `lint`, `fix`, `format` and `fmt-check` work straight after
|
|
149
|
+
`uv add --dev tempest-cli`, with nothing else to install. It is a static
|
|
150
|
+
binary wheel with no Python dependencies of its own, so nothing of its
|
|
151
|
+
propagates into your resolution.
|
|
149
152
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
that answers `pyenv: ruff: command not found`);
|
|
154
|
-
3. `uv run --with <tool> <tool>`, when `uv` is available.
|
|
155
|
-
|
|
156
|
-
To install the three alongside it:
|
|
153
|
+
`mypy` and `pytest` are deliberately left to you — a mypy bump changes
|
|
154
|
+
which errors your code reports, and pytest has to match your plugins and
|
|
155
|
+
your suite. Add them yourself, or take the bundle:
|
|
157
156
|
|
|
158
157
|
```bash
|
|
159
158
|
uv add --dev "tempest-cli[tools]"
|
|
160
159
|
```
|
|
161
160
|
|
|
161
|
+
Whatever you pin wins over the bundled ruff. The lookup runs in this
|
|
162
|
+
order:
|
|
163
|
+
|
|
164
|
+
1. the project's environment — `$VIRTUAL_ENV`, then the nearest `.venv`
|
|
165
|
+
up the tree;
|
|
166
|
+
2. the environment `tempest-cli` itself runs from (where the bundled
|
|
167
|
+
ruff lives);
|
|
168
|
+
3. `PATH`, skipping a pyenv/asdf shim that dispatches nowhere (the one
|
|
169
|
+
that answers `pyenv: ruff: command not found`);
|
|
170
|
+
4. `uv run --with <tool> <tool>`, when `uv` is available.
|
|
171
|
+
|
|
162
172
|
## Relationship with tempest-fastapi-sdk
|
|
163
173
|
|
|
164
174
|
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
|
|
@@ -110,24 +111,33 @@ cli: typer.Typer = typer.Typer(name="mytool")
|
|
|
110
111
|
register_commands(cli)
|
|
111
112
|
```
|
|
112
113
|
|
|
113
|
-
##
|
|
114
|
+
## Where the tools come from
|
|
114
115
|
|
|
115
|
-
`
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
**`ruff` comes with the package** — six of the eight commands are ruff,
|
|
117
|
+
so `lint`, `fix`, `format` and `fmt-check` work straight after
|
|
118
|
+
`uv add --dev tempest-cli`, with nothing else to install. It is a static
|
|
119
|
+
binary wheel with no Python dependencies of its own, so nothing of its
|
|
120
|
+
propagates into your resolution.
|
|
118
121
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
that answers `pyenv: ruff: command not found`);
|
|
123
|
-
3. `uv run --with <tool> <tool>`, when `uv` is available.
|
|
124
|
-
|
|
125
|
-
To install the three alongside it:
|
|
122
|
+
`mypy` and `pytest` are deliberately left to you — a mypy bump changes
|
|
123
|
+
which errors your code reports, and pytest has to match your plugins and
|
|
124
|
+
your suite. Add them yourself, or take the bundle:
|
|
126
125
|
|
|
127
126
|
```bash
|
|
128
127
|
uv add --dev "tempest-cli[tools]"
|
|
129
128
|
```
|
|
130
129
|
|
|
130
|
+
Whatever you pin wins over the bundled ruff. The lookup runs in this
|
|
131
|
+
order:
|
|
132
|
+
|
|
133
|
+
1. the project's environment — `$VIRTUAL_ENV`, then the nearest `.venv`
|
|
134
|
+
up the tree;
|
|
135
|
+
2. the environment `tempest-cli` itself runs from (where the bundled
|
|
136
|
+
ruff lives);
|
|
137
|
+
3. `PATH`, skipping a pyenv/asdf shim that dispatches nowhere (the one
|
|
138
|
+
that answers `pyenv: ruff: command not found`);
|
|
139
|
+
4. `uv run --with <tool> <tool>`, when `uv` is available.
|
|
140
|
+
|
|
131
141
|
## Relationship with tempest-fastapi-sdk
|
|
132
142
|
|
|
133
143
|
This package was extracted from
|
|
@@ -3,6 +3,23 @@
|
|
|
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.3.0] — 2026-08-15
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- **`ruff` now ships with the package.** It left the `[tools]` extra for
|
|
11
|
+
the runtime dependencies, so `uv add --dev tempest-cli` is enough for
|
|
12
|
+
`lint`, `fix`, `format` and `fmt-check` to run. The cost is nil: ruff
|
|
13
|
+
is a static binary wheel with no Python dependencies of its own, so no
|
|
14
|
+
bound of its reaches a consumer's resolution. `mypy` and `pytest` stay
|
|
15
|
+
out on purpose; `[tools]` now installs exactly those two.
|
|
16
|
+
- **The project's environment is searched before the CLI's own.** With
|
|
17
|
+
ruff bundled, the CLI's environment always has one — looking there
|
|
18
|
+
first would silently override a version the project pinned whenever
|
|
19
|
+
`tempest-cli` lives apart from it (`uv tool install`, pipx). The order
|
|
20
|
+
is now `$VIRTUAL_ENV` → nearest `.venv` → the CLI's environment →
|
|
21
|
+
`PATH` → `uv run --with`.
|
|
22
|
+
|
|
6
23
|
## [0.2.0] — 2026-08-15
|
|
7
24
|
|
|
8
25
|
### Added
|
|
@@ -4,6 +4,23 @@ 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.3.0] — 2026-08-15
|
|
8
|
+
|
|
9
|
+
### Mudado
|
|
10
|
+
|
|
11
|
+
- **O `ruff` agora vem junto com o pacote.** Saiu do extra `[tools]` e
|
|
12
|
+
virou dependência: `uv add --dev tempest-cli` já basta para `lint`,
|
|
13
|
+
`fix`, `format` e `fmt-check` rodarem. Custo zero — o ruff é binário
|
|
14
|
+
estático, sem dependência Python, então nenhum limite dele entra na
|
|
15
|
+
resolução de quem instala. `mypy` e `pytest` continuam de fora de
|
|
16
|
+
propósito; `[tools]` agora instala exatamente esses dois.
|
|
17
|
+
- **O ambiente do projeto passa a ser procurado antes do da CLI.** Com o
|
|
18
|
+
ruff embutido, o ambiente da CLI sempre tem um — procurar ali primeiro
|
|
19
|
+
sobrescreveria em silêncio a versão que o projeto fixou quando o
|
|
20
|
+
`tempest-cli` mora fora dele (`uv tool install`, pipx). A ordem agora é
|
|
21
|
+
`$VIRTUAL_ENV` → `.venv` mais próximo → ambiente da CLI → `PATH` →
|
|
22
|
+
`uv run --with`.
|
|
23
|
+
|
|
7
24
|
## [0.2.0] — 2026-08-15
|
|
8
25
|
|
|
9
26
|
### Adicionado
|
|
@@ -5,7 +5,9 @@ and `pytest` — with the typing strictness living in `pyproject.toml`
|
|
|
5
5
|
instead of spread across four Makefile targets.
|
|
6
6
|
|
|
7
7
|
Framework-agnostic on purpose: Django, Flask, Litestar, FastAPI, a
|
|
8
|
-
library, a script.
|
|
8
|
+
library, a script. There are two runtime dependencies: `typer` and
|
|
9
|
+
`ruff` — the latter ships along, so the gate runs the moment you install
|
|
10
|
+
it.
|
|
9
11
|
|
|
10
12
|
```bash
|
|
11
13
|
uv add --dev tempest-cli
|
|
@@ -5,7 +5,9 @@ Um comando para o gate de qualidade de qualquer projeto Python — `ruff`,
|
|
|
5
5
|
em vez de espalhado por quatro alvos de Makefile.
|
|
6
6
|
|
|
7
7
|
Agnóstico de framework de propósito: Django, Flask, Litestar, FastAPI,
|
|
8
|
-
uma biblioteca, um script.
|
|
8
|
+
uma biblioteca, um script. As dependências de runtime são duas: o
|
|
9
|
+
`typer` e o `ruff` — que já vem junto, para o gate rodar assim que
|
|
10
|
+
instala.
|
|
9
11
|
|
|
10
12
|
```bash
|
|
11
13
|
uv add --dev tempest-cli
|
|
@@ -10,7 +10,9 @@ Or with pip:
|
|
|
10
10
|
pip install tempest-cli
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Requires **Python 3.11+**.
|
|
13
|
+
Requires **Python 3.11+**. It brings `ruff` along — six of the eight
|
|
14
|
+
commands are ruff, so the gate runs the moment the package installs. The
|
|
15
|
+
other runtime dependency is `typer`.
|
|
14
16
|
|
|
15
17
|
It installs **two executables**: `tempest-cli` and the short alias `tc`.
|
|
16
18
|
They are the same program — everything in these docs applies to both.
|
|
@@ -26,15 +28,42 @@ tc check # identical to tempest-cli check
|
|
|
26
28
|
|
|
27
29
|
## Where ruff, mypy and pytest come from
|
|
28
30
|
|
|
29
|
-
`
|
|
30
|
-
|
|
31
|
+
**`ruff` comes with the package**: install it and `lint`, `fix`,
|
|
32
|
+
`format` and `fmt-check` already work — nothing else to install.
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
```bash
|
|
35
|
+
uv add --dev tempest-cli
|
|
36
|
+
tempest-cli fix # runs right away
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`mypy` and `pytest` stay with you. A mypy bump changes which errors your
|
|
40
|
+
code starts reporting, and pytest has to match your plugins and your
|
|
41
|
+
suite — those versions are the project's call. Add them yourself, or
|
|
42
|
+
take the bundle:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
uv add --dev "tempest-cli[tools]" # mypy + pytest
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
!!! question "Why ruff is a dependency and the other two are not"
|
|
49
|
+
Six of the eight commands are ruff — a `tempest-cli` without ruff is
|
|
50
|
+
a gate that cannot run. And it costs nothing: ruff is a static
|
|
51
|
+
binary with no Python dependencies at all, so no bound of its enters
|
|
52
|
+
your project's resolution. mypy and pytest, in contrast, run through
|
|
53
|
+
your code and your suite; pinning them here would be deciding for
|
|
54
|
+
you.
|
|
55
|
+
|
|
56
|
+
### The lookup order
|
|
57
|
+
|
|
58
|
+
What your project pins **wins** over the bundled ruff. The CLI runs the
|
|
59
|
+
first thing it finds, in this order:
|
|
60
|
+
|
|
61
|
+
1. **the project's environment** — `$VIRTUAL_ENV`, then the nearest
|
|
62
|
+
`.venv` up the tree;
|
|
63
|
+
2. **the CLI's own environment** — where the bundled ruff lives;
|
|
64
|
+
3. **`PATH`** — skipping a version-manager shim that dispatches nowhere
|
|
36
65
|
(see below);
|
|
37
|
-
|
|
66
|
+
4. **`uv run --with <tool> <tool>`** when `uv` is available — the
|
|
38
67
|
project's environment plus the tool, with no activation and no prior
|
|
39
68
|
`uv sync` required.
|
|
40
69
|
|
|
@@ -46,22 +75,10 @@ tool and how to install it, instead of raising a traceback.
|
|
|
46
75
|
globally and holds a stub for every tool any installed version ever
|
|
47
76
|
provided. Looking up `ruff` there finds `~/.pyenv/shims/ruff` even
|
|
48
77
|
when the project has no ruff at all — and running it prints
|
|
49
|
-
`pyenv: ruff: command not found`. So the run's own
|
|
78
|
+
`pyenv: ruff: command not found`. So the run's own environments win
|
|
50
79
|
over `PATH`, and a shim is only accepted after proving it dispatches
|
|
51
80
|
(`<tool> --version` exiting `0`).
|
|
52
81
|
|
|
53
|
-
!!! tip "Why the versions are not pinned"
|
|
54
|
-
A ruff version pinned here would become the ceiling for every
|
|
55
|
-
project installing this package — and upgrading the linter is a
|
|
56
|
-
decision for whoever writes the code, not for whoever packages the
|
|
57
|
-
gate.
|
|
58
|
-
|
|
59
|
-
If you would rather install all three alongside:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
uv add --dev "tempest-cli[tools]"
|
|
63
|
-
```
|
|
64
|
-
|
|
65
82
|
## Verifying
|
|
66
83
|
|
|
67
84
|
```bash
|
|
@@ -82,9 +99,9 @@ it exactly as it would read `ruff` directly:
|
|
|
82
99
|
|
|
83
100
|
## Recap
|
|
84
101
|
|
|
85
|
-
- `uv add --dev tempest-cli`, Python 3.11+, `
|
|
86
|
-
|
|
102
|
+
- `uv add --dev tempest-cli`, Python 3.11+, `ruff` already included.
|
|
103
|
+
- `mypy` and `pytest` are yours — or take `"tempest-cli[tools]"`.
|
|
87
104
|
- Two executables: `tempest-cli` and the `tc` alias.
|
|
88
|
-
-
|
|
89
|
-
shim)
|
|
105
|
+
- What the project pins beats the bundled ruff; then come `PATH` (never
|
|
106
|
+
a dead shim) and `uv run --with`.
|
|
90
107
|
- A missing tool means exit 127 with a message, not a traceback.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Instalação
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
uv add --dev tempest-cli
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
Ou com pip:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install tempest-cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requer **Python 3.11+**. Vem com o `ruff` junto — seis dos oito
|
|
14
|
+
comandos são ruff, então o gate roda assim que o pacote instala. A outra
|
|
15
|
+
dependência de runtime é o `typer`.
|
|
16
|
+
|
|
17
|
+
Ficam instalados **dois executáveis**: `tempest-cli` e o apelido curto
|
|
18
|
+
`tc`. São o mesmo programa — tudo nesta documentação vale para os dois.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
tc check # idêntico a tempest-cli check
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
!!! warning "`tc` também é o `tc(8)` do iproute2"
|
|
25
|
+
Enquanto o ambiente que instalou o pacote estiver no `PATH`, `tc`
|
|
26
|
+
resolve para esta CLI. Para o controlador de tráfego do Linux, chame
|
|
27
|
+
pelo caminho absoluto (`/usr/sbin/tc`) ou use `tempest-cli` e deixe
|
|
28
|
+
o `tc` livre.
|
|
29
|
+
|
|
30
|
+
## De onde vêm o ruff, o mypy e o pytest
|
|
31
|
+
|
|
32
|
+
O **`ruff` já vem junto**: instalou o pacote, `lint`, `fix`, `format` e
|
|
33
|
+
`fmt-check` funcionam — nada mais a instalar.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
uv add --dev tempest-cli
|
|
37
|
+
tempest-cli fix # roda agora mesmo
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
O `mypy` e o `pytest` ficam com você. Um bump de mypy muda quais erros o
|
|
41
|
+
seu código passa a reportar, e o pytest precisa casar com os seus plugins
|
|
42
|
+
e a sua suíte — versão dessas duas é decisão do projeto. Adicione você
|
|
43
|
+
mesmo, ou pegue o pacote pronto:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
uv add --dev "tempest-cli[tools]" # mypy + pytest
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
!!! question "Por que o ruff é dependência e as outras duas não"
|
|
50
|
+
Seis dos oito comandos são ruff — um `tempest-cli` sem ruff é um
|
|
51
|
+
gate que não roda. E o custo é zero: o ruff é um binário estático,
|
|
52
|
+
sem dependência Python nenhuma, então nenhum limite dele entra na
|
|
53
|
+
resolução do seu projeto. Já mypy e pytest atravessam o seu código e
|
|
54
|
+
a sua suíte; fixá-los aqui seria decidir por você.
|
|
55
|
+
|
|
56
|
+
### A ordem de busca
|
|
57
|
+
|
|
58
|
+
O que o seu projeto fixa **ganha** do ruff que veio junto. A CLI executa
|
|
59
|
+
o que encontrar primeiro, nesta ordem:
|
|
60
|
+
|
|
61
|
+
1. **o ambiente do projeto** — `$VIRTUAL_ENV`, depois o `.venv` mais
|
|
62
|
+
próximo subindo a árvore;
|
|
63
|
+
2. **o ambiente da própria CLI** — onde mora o ruff que veio junto;
|
|
64
|
+
3. **o `PATH`** — pulando um *shim* de gerenciador de versão que não
|
|
65
|
+
despacha para lugar nenhum (veja abaixo);
|
|
66
|
+
4. **`uv run --with <ferramenta> <ferramenta>`**, quando o `uv` está
|
|
67
|
+
disponível — o ambiente do projeto mais a ferramenta, sem exigir
|
|
68
|
+
ativação nem `uv sync` prévio.
|
|
69
|
+
|
|
70
|
+
Se nada resolver, o comando sai com **127** e diz qual ferramenta faltou
|
|
71
|
+
e como instalá-la, em vez de estourar um traceback.
|
|
72
|
+
|
|
73
|
+
!!! info "Por que o `PATH` não vem primeiro"
|
|
74
|
+
Em máquina com pyenv/asdf, o diretório `shims` está no `PATH`
|
|
75
|
+
globalmente e tem um stub para toda ferramenta que qualquer versão
|
|
76
|
+
instalada já forneceu. Procurar `ruff` ali acha
|
|
77
|
+
`~/.pyenv/shims/ruff` mesmo quando o projeto não tem ruff nenhum — e
|
|
78
|
+
rodá-lo dá `pyenv: ruff: command not found`. Por isso os ambientes da
|
|
79
|
+
execução ganham do `PATH`, e um shim só é aceito depois de provar que
|
|
80
|
+
despacha (`<ferramenta> --version` saindo `0`).
|
|
81
|
+
|
|
82
|
+
## Verificando
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
tempest-cli --version
|
|
86
|
+
tc --version # o mesmo programa
|
|
87
|
+
tempest-cli check --help
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Em CI
|
|
91
|
+
|
|
92
|
+
Cada comando devolve o código de saída da ferramenta por baixo, então o
|
|
93
|
+
job lê exatamente como leria o `ruff` direto:
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
- name: Quality gate
|
|
97
|
+
run: uv run tempest-cli check
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Recap
|
|
101
|
+
|
|
102
|
+
- `uv add --dev tempest-cli`, Python 3.11+, com o `ruff` já junto.
|
|
103
|
+
- `mypy` e `pytest` são seus — ou pegue `"tempest-cli[tools]"`.
|
|
104
|
+
- Dois executáveis: `tempest-cli` e o apelido `tc`.
|
|
105
|
+
- O que o projeto fixa ganha do ruff embutido; depois vêm o `PATH` (sem
|
|
106
|
+
shim morto) e o `uv run --with`.
|
|
107
|
+
- Ferramenta ausente = saída 127 com mensagem, não traceback.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tempest-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
description = "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
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -31,18 +31,25 @@ classifiers = [
|
|
|
31
31
|
"Typing :: Typed",
|
|
32
32
|
]
|
|
33
33
|
dependencies = [
|
|
34
|
+
# `ruff` ships with the package: six of the eight commands are ruff,
|
|
35
|
+
# so a tempest-cli without one is a gate that cannot run. It costs
|
|
36
|
+
# nothing to depend on — a static binary wheel with no Python
|
|
37
|
+
# dependencies of its own, so no bound of its propagates to anyone.
|
|
38
|
+
# The lookup still prefers a ruff the project pinned; this one is the
|
|
39
|
+
# fallback for a project that pinned none.
|
|
40
|
+
"ruff>=0.8.0",
|
|
34
41
|
"typer>=0.12.0",
|
|
35
42
|
]
|
|
36
43
|
|
|
37
44
|
[project.optional-dependencies]
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
45
|
+
# `mypy` and `pytest` are deliberately NOT dependencies. A mypy bump
|
|
46
|
+
# changes which errors a codebase reports, and pytest has to match the
|
|
47
|
+
# plugins and the test suite it runs — both are the project's call, not
|
|
48
|
+
# this package's. `[tools]` is the convenience bundle for whoever would
|
|
49
|
+
# rather pin them here than in their own dev group.
|
|
42
50
|
tools = [
|
|
43
51
|
"mypy>=1.13.0",
|
|
44
52
|
"pytest>=8.3.3",
|
|
45
|
-
"ruff>=0.8.0",
|
|
46
53
|
]
|
|
47
54
|
|
|
48
55
|
[project.urls]
|
|
@@ -5,9 +5,11 @@ typing-strictness dial read from ``[tool.tempest]`` in the project's
|
|
|
5
5
|
``pyproject.toml`` — and a generator for the prompt that makes an AI fill
|
|
6
6
|
a pull-request description from the branch's own diff.
|
|
7
7
|
|
|
8
|
-
It knows nothing about any web framework.
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
It knows nothing about any web framework. ``ruff`` ships with it, so the
|
|
9
|
+
lint/format commands work the moment it is installed; ``mypy`` and
|
|
10
|
+
``pytest`` are left to the project, which pins the versions it wants.
|
|
11
|
+
The tools are invoked from the project's environment first, so a pinned
|
|
12
|
+
version always beats the bundled one.
|
|
11
13
|
|
|
12
14
|
```bash
|
|
13
15
|
tempest-cli check # lint + fmt-check + type + test
|
|
@@ -49,7 +51,7 @@ from tempest_cli.pr_prompt import GitError as GitError
|
|
|
49
51
|
from tempest_cli.pr_prompt import PromptLanguage as PromptLanguage
|
|
50
52
|
from tempest_cli.pr_prompt import generate_pr_prompt as generate_pr_prompt
|
|
51
53
|
|
|
52
|
-
__version__: str = "0.
|
|
54
|
+
__version__: str = "0.3.0"
|
|
53
55
|
"""Installed package version."""
|
|
54
56
|
|
|
55
57
|
__all__: list[str] = [
|
|
@@ -42,19 +42,25 @@ def _environment_dirs() -> list[Path]:
|
|
|
42
42
|
environment has no ruff at all. The environments below are the ones
|
|
43
43
|
that actually belong to the run, so they are consulted first:
|
|
44
44
|
|
|
45
|
-
1.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
1. ``$VIRTUAL_ENV`` — the activated environment;
|
|
46
|
+
2. the nearest ``.venv`` walking up from the working directory — a
|
|
47
|
+
project environment that was never activated;
|
|
48
|
+
3. the directory of the interpreter running this CLI.
|
|
49
|
+
|
|
50
|
+
The project comes before the interpreter on purpose. ``ruff`` ships
|
|
51
|
+
as a dependency of this package, so the CLI's own environment always
|
|
52
|
+
has one; a project that pins its own must still get the version it
|
|
53
|
+
pinned, with the bundled one serving only as the fallback for a
|
|
54
|
+
project that pins nothing. When the CLI is installed *into* the
|
|
55
|
+
project (the common case) all three point at the same directory and
|
|
56
|
+
the order is moot — it only decides for ``uv tool install`` / pipx,
|
|
57
|
+
where the CLI lives in an environment of its own.
|
|
52
58
|
|
|
53
59
|
Returns:
|
|
54
60
|
list[Path]: Existing directories, in preference order, without
|
|
55
61
|
duplicates.
|
|
56
62
|
"""
|
|
57
|
-
roots: list[Path] = [
|
|
63
|
+
roots: list[Path] = []
|
|
58
64
|
virtual_env = os.environ.get("VIRTUAL_ENV")
|
|
59
65
|
if virtual_env:
|
|
60
66
|
roots.extend((Path(virtual_env) / "bin", Path(virtual_env) / "Scripts"))
|
|
@@ -68,6 +74,7 @@ def _environment_dirs() -> list[Path]:
|
|
|
68
74
|
if candidate.is_dir():
|
|
69
75
|
roots.extend((candidate / "bin", candidate / "Scripts"))
|
|
70
76
|
break
|
|
77
|
+
roots.append(Path(sys.executable).parent)
|
|
71
78
|
seen: set[Path] = set()
|
|
72
79
|
ordered: list[Path] = []
|
|
73
80
|
for root in roots:
|
|
@@ -320,10 +320,16 @@ def test_a_shim_probe_that_cannot_spawn_is_not_runnable(
|
|
|
320
320
|
assert lint._shim_runs(Path("/home/u/.pyenv/shims/ruff")) is False
|
|
321
321
|
|
|
322
322
|
|
|
323
|
-
def
|
|
323
|
+
def test_environment_dirs_prefers_the_project_over_the_cli_itself(
|
|
324
324
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
325
325
|
) -> None:
|
|
326
|
-
"""
|
|
326
|
+
"""A pinned ruff must win over the one shipped with this package.
|
|
327
|
+
|
|
328
|
+
`ruff` is a dependency of tempest-cli, so the CLI's own environment
|
|
329
|
+
always has one. Searching it first would silently override the
|
|
330
|
+
version a project pinned whenever the CLI lives elsewhere
|
|
331
|
+
(`uv tool install` / pipx).
|
|
332
|
+
"""
|
|
327
333
|
interpreter_dir = tmp_path / "cli-env" / "bin"
|
|
328
334
|
interpreter_dir.mkdir(parents=True)
|
|
329
335
|
active = tmp_path / "active"
|
|
@@ -332,8 +338,8 @@ def test_environment_dirs_prefers_the_running_interpreter(
|
|
|
332
338
|
monkeypatch.setenv("VIRTUAL_ENV", str(active))
|
|
333
339
|
monkeypatch.chdir(tmp_path)
|
|
334
340
|
dirs = lint._environment_dirs()
|
|
335
|
-
assert dirs[0] ==
|
|
336
|
-
assert active / "bin"
|
|
341
|
+
assert dirs[0] == active / "bin"
|
|
342
|
+
assert dirs.index(interpreter_dir) > dirs.index(active / "bin")
|
|
337
343
|
|
|
338
344
|
|
|
339
345
|
def test_environment_dirs_finds_an_unactivated_venv(
|
|
@@ -346,3 +352,18 @@ def test_environment_dirs_finds_an_unactivated_venv(
|
|
|
346
352
|
monkeypatch.delenv("VIRTUAL_ENV", raising=False)
|
|
347
353
|
monkeypatch.chdir(project / "src")
|
|
348
354
|
assert project / ".venv" / "bin" in lint._environment_dirs()
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def test_ruff_ships_with_the_package() -> None:
|
|
358
|
+
"""Installing tempest-cli must be enough to run the ruff commands.
|
|
359
|
+
|
|
360
|
+
Six of the eight commands are ruff. Reading the requirement from the
|
|
361
|
+
installed distribution, not from ``pyproject.toml``, is what proves
|
|
362
|
+
a user actually receives it.
|
|
363
|
+
"""
|
|
364
|
+
from importlib.metadata import requires
|
|
365
|
+
|
|
366
|
+
declared = requires("tempest-cli") or []
|
|
367
|
+
runtime = [item for item in declared if "extra ==" not in item]
|
|
368
|
+
assert any(item.startswith("ruff") for item in runtime), runtime
|
|
369
|
+
assert not any(item.startswith(("mypy", "pytest")) for item in runtime), runtime
|
|
@@ -1126,9 +1126,10 @@ wheels = [
|
|
|
1126
1126
|
|
|
1127
1127
|
[[package]]
|
|
1128
1128
|
name = "tempest-cli"
|
|
1129
|
-
version = "0.
|
|
1129
|
+
version = "0.3.0"
|
|
1130
1130
|
source = { editable = "." }
|
|
1131
1131
|
dependencies = [
|
|
1132
|
+
{ name = "ruff" },
|
|
1132
1133
|
{ name = "typer" },
|
|
1133
1134
|
]
|
|
1134
1135
|
|
|
@@ -1136,7 +1137,6 @@ dependencies = [
|
|
|
1136
1137
|
tools = [
|
|
1137
1138
|
{ name = "mypy" },
|
|
1138
1139
|
{ name = "pytest" },
|
|
1139
|
-
{ name = "ruff" },
|
|
1140
1140
|
]
|
|
1141
1141
|
|
|
1142
1142
|
[package.dev-dependencies]
|
|
@@ -1156,7 +1156,7 @@ docs = [
|
|
|
1156
1156
|
requires-dist = [
|
|
1157
1157
|
{ name = "mypy", marker = "extra == 'tools'", specifier = ">=1.13.0" },
|
|
1158
1158
|
{ name = "pytest", marker = "extra == 'tools'", specifier = ">=8.3.3" },
|
|
1159
|
-
{ name = "ruff",
|
|
1159
|
+
{ name = "ruff", specifier = ">=0.8.0" },
|
|
1160
1160
|
{ name = "typer", specifier = ">=0.12.0" },
|
|
1161
1161
|
]
|
|
1162
1162
|
provides-extras = ["tools"]
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# Instalação
|
|
2
|
-
|
|
3
|
-
```bash
|
|
4
|
-
uv add --dev tempest-cli
|
|
5
|
-
```
|
|
6
|
-
|
|
7
|
-
Ou com pip:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
pip install tempest-cli
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Requer **Python 3.11+**. A única dependência de runtime é o `typer`.
|
|
14
|
-
|
|
15
|
-
Ficam instalados **dois executáveis**: `tempest-cli` e o apelido curto
|
|
16
|
-
`tc`. São o mesmo programa — tudo nesta documentação vale para os dois.
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
tc check # idêntico a tempest-cli check
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
!!! warning "`tc` também é o `tc(8)` do iproute2"
|
|
23
|
-
Enquanto o ambiente que instalou o pacote estiver no `PATH`, `tc`
|
|
24
|
-
resolve para esta CLI. Para o controlador de tráfego do Linux, chame
|
|
25
|
-
pelo caminho absoluto (`/usr/sbin/tc`) ou use `tempest-cli` e deixe
|
|
26
|
-
o `tc` livre.
|
|
27
|
-
|
|
28
|
-
## De onde vêm o ruff, o mypy e o pytest
|
|
29
|
-
|
|
30
|
-
O `tempest-cli` **não** fixa versão de nenhum dos três: ele executa o que
|
|
31
|
-
encontrar, nesta ordem:
|
|
32
|
-
|
|
33
|
-
1. **o ambiente da execução** — o diretório do interpretador que está
|
|
34
|
-
rodando a CLI (onde o extra `[tools]` instala as três), depois
|
|
35
|
-
`$VIRTUAL_ENV`, depois o `.venv` mais próximo subindo a árvore;
|
|
36
|
-
2. **o `PATH`** — pulando um *shim* de gerenciador de versão que não
|
|
37
|
-
despacha para lugar nenhum (veja abaixo);
|
|
38
|
-
3. **`uv run --with <ferramenta> <ferramenta>`**, quando o `uv` está
|
|
39
|
-
disponível — o ambiente do projeto mais a ferramenta, sem exigir
|
|
40
|
-
ativação nem `uv sync` prévio.
|
|
41
|
-
|
|
42
|
-
Se nada resolver, o comando sai com **127** e diz qual ferramenta faltou
|
|
43
|
-
e como instalá-la, em vez de estourar um traceback.
|
|
44
|
-
|
|
45
|
-
!!! info "Por que o `PATH` não vem primeiro"
|
|
46
|
-
Em máquina com pyenv/asdf, o diretório `shims` está no `PATH`
|
|
47
|
-
globalmente e tem um stub para toda ferramenta que qualquer versão
|
|
48
|
-
instalada já forneceu. Procurar `ruff` ali acha
|
|
49
|
-
`~/.pyenv/shims/ruff` mesmo quando o projeto não tem ruff nenhum — e
|
|
50
|
-
rodá-lo dá `pyenv: ruff: command not found`. Por isso o ambiente da
|
|
51
|
-
execução ganha do `PATH`, e um shim só é aceito depois de provar que
|
|
52
|
-
despacha (`<ferramenta> --version` saindo `0`).
|
|
53
|
-
|
|
54
|
-
!!! tip "Por que não fixar as versões"
|
|
55
|
-
Uma versão de ruff fixada aqui viraria o teto de todo projeto que
|
|
56
|
-
instalasse este pacote — e atualizar o linter é decisão de quem
|
|
57
|
-
escreve o código, não de quem empacota o gate.
|
|
58
|
-
|
|
59
|
-
Se você prefere instalar as três junto:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
uv add --dev "tempest-cli[tools]"
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## Verificando
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
tempest-cli --version
|
|
69
|
-
tc --version # o mesmo programa
|
|
70
|
-
tempest-cli check --help
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Em CI
|
|
74
|
-
|
|
75
|
-
Cada comando devolve o código de saída da ferramenta por baixo, então o
|
|
76
|
-
job lê exatamente como leria o `ruff` direto:
|
|
77
|
-
|
|
78
|
-
```yaml
|
|
79
|
-
- name: Quality gate
|
|
80
|
-
run: uv run tempest-cli check
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Recap
|
|
84
|
-
|
|
85
|
-
- `uv add --dev tempest-cli`, Python 3.11+, só o `typer` de dependência.
|
|
86
|
-
- Dois executáveis: `tempest-cli` e o apelido `tc`.
|
|
87
|
-
- As ferramentas vêm do ambiente da execução, do `PATH` (sem shim morto)
|
|
88
|
-
ou do `uv run --with`.
|
|
89
|
-
- Ferramenta ausente = saída 127 com mensagem, não traceback.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tempest_cli-0.2.0 → tempest_cli-0.3.0}/tempest_cli/_templates/pull_request_template.en-US.md
RENAMED
|
File without changes
|
{tempest_cli-0.2.0 → tempest_cli-0.3.0}/tempest_cli/_templates/pull_request_template.pt-BR.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|