readability-cli 0.8.4__tar.gz → 0.8.6__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.
- {readability_cli-0.8.4 → readability_cli-0.8.6}/.github/workflows/ci.yml +1 -1
- {readability_cli-0.8.4 → readability_cli-0.8.6}/.github/workflows/publish.yml +2 -2
- {readability_cli-0.8.4 → readability_cli-0.8.6}/.github/workflows/update-guides.yml +2 -2
- readability_cli-0.8.6/.prettierignore +2 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/PKG-INFO +88 -89
- {readability_cli-0.8.4 → readability_cli-0.8.6}/README.md +87 -88
- {readability_cli-0.8.4 → readability_cli-0.8.6}/configs/biome-default.json +5 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/pyproject.toml +1 -1
- {readability_cli-0.8.4 → readability_cli-0.8.6}/readability.py +31 -10
- {readability_cli-0.8.4 → readability_cli-0.8.6}/test_readability.py +85 -2
- {readability_cli-0.8.4 → readability_cli-0.8.6}/uv.lock +1 -1
- {readability_cli-0.8.4 → readability_cli-0.8.6}/.gitignore +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/.python-version +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/LICENSE +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/configs/pyrefly.toml +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/configs/ruff.toml +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/Rguide.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/cppguide.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/csharp-style.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/docguide-style.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/go-guide.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/htmlcssguide.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/javaguide.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/jsguide.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/jsoncstyleguide.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/objcguide.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/pyguide.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/shellguide.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/tsguide.md +0 -0
- {readability_cli-0.8.4 → readability_cli-0.8.6}/guides/vimscriptguide.md +0 -0
|
@@ -2,7 +2,7 @@ name: Publish
|
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
|
-
tags: [
|
|
5
|
+
tags: ["v*"]
|
|
6
6
|
|
|
7
7
|
jobs:
|
|
8
8
|
publish:
|
|
@@ -17,7 +17,7 @@ jobs:
|
|
|
17
17
|
- name: Set up Python
|
|
18
18
|
uses: astral-sh/setup-uv@v7
|
|
19
19
|
with:
|
|
20
|
-
python-version:
|
|
20
|
+
python-version: "3.14"
|
|
21
21
|
|
|
22
22
|
- name: Build distribution
|
|
23
23
|
run: uv build
|
|
@@ -2,7 +2,7 @@ name: Update Style Guides
|
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
schedule:
|
|
5
|
-
- cron:
|
|
5
|
+
- cron: "0 0 * * 0" # Weekly on Sunday at midnight
|
|
6
6
|
workflow_dispatch: # Ad-hoc trigger
|
|
7
7
|
|
|
8
8
|
jobs:
|
|
@@ -30,4 +30,4 @@ jobs:
|
|
|
30
30
|
uses: stefanzweifel/git-auto-commit-action@v5
|
|
31
31
|
with:
|
|
32
32
|
commit_message: "chore: update style guides [skip ci]"
|
|
33
|
-
file_pattern:
|
|
33
|
+
file_pattern: "guides/*.md"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: readability-cli
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.6
|
|
4
4
|
Summary: A CLI to lint, format, and type-check code with Google-style defaults, and pull Google style guides in markdown format.
|
|
5
5
|
Project-URL: Homepage, https://github.com/owahltinez/readability
|
|
6
6
|
Project-URL: Repository, https://github.com/owahltinez/readability
|
|
@@ -17,22 +17,21 @@ Description-Content-Type: text/markdown
|
|
|
17
17
|
A CLI tool that keeps code aligned with Google style conventions. It runs the
|
|
18
18
|
right linters, formatters, and type checkers for your project with sensible
|
|
19
19
|
defaults, and serves the official Google style guides in Markdown format. This
|
|
20
|
-
is ideal for AI agents or developers who want consistent code quality checks
|
|
21
|
-
|
|
20
|
+
is ideal for AI agents or developers who want consistent code quality checks and
|
|
21
|
+
quick access to style conventions without browsing HTML pages.
|
|
22
22
|
|
|
23
23
|
## Features
|
|
24
24
|
|
|
25
25
|
- **Linting & Formatting**: A `check` command that automatically detects and
|
|
26
26
|
runs relevant tools (Ruff, Pyrefly, Biome, Prettier, gofmt) for your project.
|
|
27
|
-
- **Sensible Defaults**:
|
|
28
|
-
|
|
29
|
-
own.
|
|
27
|
+
- **Sensible Defaults**: Google-style defaults for Ruff, Pyrefly, Biome, and
|
|
28
|
+
Prettier are used automatically when a project does not define its own.
|
|
30
29
|
- **Style Guides**: A `guide` command that fetches the latest Google style
|
|
31
|
-
guides (Python, Shell, C++, Java, JS/TS, Go, etc.) converted to Markdown,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- **Offline Mode**: Local caching of style guides for fast, offline access,
|
|
35
|
-
|
|
30
|
+
guides (Python, Shell, C++, Java, JS/TS, Go, etc.) converted to Markdown, and
|
|
31
|
+
outlines, addresses, and searches them by section rather than serving 200 KB
|
|
32
|
+
to be read whole.
|
|
33
|
+
- **Offline Mode**: Local caching of style guides for fast, offline access, kept
|
|
34
|
+
fresh with a single `sync` command.
|
|
36
35
|
|
|
37
36
|
## Quick Start
|
|
38
37
|
|
|
@@ -95,38 +94,39 @@ readability check . --fix
|
|
|
95
94
|
|
|
96
95
|
### Supported Tools
|
|
97
96
|
|
|
98
|
-
| Tool
|
|
99
|
-
|
|
100
|
-
| **Ruff**
|
|
101
|
-
| **Pyrefly**
|
|
102
|
-
| **Biome**
|
|
103
|
-
| **Prettier** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.css`, `.scss`, `.html`, `.md`, `.yml`, `.yaml` |
|
|
104
|
-
| **gofmt**
|
|
97
|
+
| Tool | Supported Extensions | Config Needed | Fetched By |
|
|
98
|
+
| ------------ | --------------------------------------------------------------------------------------- | --------------------------------- | ---------- |
|
|
99
|
+
| **Ruff** | `.py` | none, bundled | `uvx` |
|
|
100
|
+
| **Pyrefly** | `.py` | none, bundled | `uvx` |
|
|
101
|
+
| **Biome** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.jsonc`, `.css`, `.html` | none, bundled | `npx` |
|
|
102
|
+
| **Prettier** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.css`, `.scss`, `.html`, `.md`, `.yml`, `.yaml` | none for Markdown, YAML, and SCSS | `npx` |
|
|
103
|
+
| **gofmt** | `.go` | `go.mod` | — |
|
|
105
104
|
|
|
106
105
|
**You do not need to install any of these.** Each is resolved in order: a
|
|
107
|
-
project-local install (`node_modules/.bin`, `.venv/bin`) first, then whatever
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
106
|
+
project-local install (`node_modules/.bin`, `.venv/bin`) first, then whatever is
|
|
107
|
+
on your `PATH`, and only then fetched by `uvx` or `npx`. The runners cache what
|
|
108
|
+
they download, so the fetch happens once per machine and later runs are served
|
|
109
|
+
from disk and work offline.
|
|
111
110
|
|
|
112
|
-
That keeps this package at ~4 MB rather than the ~54 MB it would take to
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
That keeps this package at ~4 MB rather than the ~54 MB it would take to carry
|
|
112
|
+
Ruff and Pyrefly itself — a cost that would fall on everyone using only `guide`.
|
|
113
|
+
An installed copy always wins over a fetched one, so a project that pinned a
|
|
114
|
+
version is linted against the rules it chose.
|
|
116
115
|
|
|
117
116
|
Fetched tools carry a minimum version, enough to understand the bundled
|
|
118
117
|
configurations, and no maximum. A ceiling would freeze anyone who installed
|
|
119
|
-
nothing at whatever was current when this package shipped, and tie its
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
nothing at whatever was current when this package shipped, and tie its releases
|
|
119
|
+
to Ruff's — which has published seventeen minor series, roughly one every six
|
|
120
|
+
weeks. If you need a fixed version, install it: an installed tool always wins
|
|
121
|
+
over a fetched one.
|
|
123
122
|
|
|
124
|
-
Set `UV_OFFLINE=1` to forbid fetching. A tool that then cannot be reached
|
|
125
|
-
|
|
123
|
+
Set `UV_OFFLINE=1` to forbid fetching. A tool that then cannot be reached fails
|
|
124
|
+
the run rather than passing it.
|
|
126
125
|
|
|
127
126
|
Ruff, Pyrefly, and Biome ship with bundled configurations, so they run on any
|
|
128
|
-
file they handle without the project arranging anything. Prettier
|
|
129
|
-
|
|
127
|
+
file they handle without the project arranging anything. Prettier does the same
|
|
128
|
+
for Markdown, YAML, and SCSS; a Prettier configuration opts its overlapping web
|
|
129
|
+
formats into Prettier too. Gofmt waits for a `go.mod` file.
|
|
130
130
|
|
|
131
131
|
A tool that could not be reached at all is never skipped quietly:
|
|
132
132
|
|
|
@@ -141,8 +141,8 @@ $ readability check src/
|
|
|
141
141
|
Error: Every tool for 1 path(s) is missing, so nothing was verified.
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
-
That second case needs neither the tool nor a runner to be present, which is
|
|
145
|
-
|
|
144
|
+
That second case needs neither the tool nor a runner to be present, which is the
|
|
145
|
+
state a container image is usually in.
|
|
146
146
|
|
|
147
147
|
`check` exits non-zero on findings, tool failures, and when every applicable
|
|
148
148
|
tool is absent, so it can gate CI without a clean exit meaning required tools
|
|
@@ -165,27 +165,28 @@ if report.findings or report.failed or not report.ran:
|
|
|
165
165
|
```
|
|
166
166
|
|
|
167
167
|
The returned `CheckReport` records only whether findings occurred and which
|
|
168
|
-
tools ran, were skipped, or failed. Detailed tool findings are still written
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
tools ran, were skipped, or failed. Detailed tool findings are still written as
|
|
169
|
+
each tool runs. Every path is validated before any tool runs, and a missing one
|
|
170
|
+
raises `FileNotFoundError` rather than being misreported as a finding. Relative
|
|
171
|
+
paths remain relative to the process working directory; `project_root` controls
|
|
172
|
+
configuration discovery only.
|
|
173
173
|
|
|
174
174
|
### Default Configurations
|
|
175
175
|
|
|
176
176
|
Ruff and Pyrefly defaults follow the
|
|
177
177
|
[Google Python style guide](https://google.github.io/styleguide/pyguide.html):
|
|
178
|
-
80-column lines, Google docstrings, import ordering, and full type checking.
|
|
179
|
-
|
|
178
|
+
80-column lines, Google docstrings, import ordering, and full type checking. The
|
|
179
|
+
Biome default applies the 80-column lines and two-space indentation of the
|
|
180
180
|
[Google JavaScript style guide](https://google.github.io/styleguide/jsguide.html)
|
|
181
|
-
and enables Biome's recommended lint rules.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
181
|
+
and enables Biome's recommended lint rules. Prettier wraps prose at 80 columns,
|
|
182
|
+
following the
|
|
183
|
+
[Google Markdown style guide](https://google.github.io/styleguide/docguide/style.html#character-line-limit).
|
|
184
|
+
These defaults apply only when the project does not define its own
|
|
185
|
+
configuration. To override them, add a `[tool.ruff]` or `[tool.pyrefly]` section
|
|
186
|
+
to your `pyproject.toml`, or a dedicated `ruff.toml`, `pyrefly.toml`,
|
|
187
|
+
`biome.json`, `biome.jsonc`, or Prettier configuration — any project-level
|
|
188
|
+
configuration takes full precedence. The bundled Biome file requires Biome 2.5
|
|
189
|
+
or later, matching the version floor used by the fallback runner.
|
|
189
190
|
|
|
190
191
|
## Style Guides
|
|
191
192
|
|
|
@@ -211,17 +212,17 @@ readability guide python --full | grep -i f-string
|
|
|
211
212
|
|
|
212
213
|
A guide can exceed 200 KB, so the outline is what a bare invocation prints:
|
|
213
214
|
listing the sections and fetching the one you need beats reading the lot.
|
|
214
|
-
Nothing is written to disk, which is what a coding agent should do rather
|
|
215
|
-
|
|
216
|
-
|
|
215
|
+
Nothing is written to disk, which is what a coding agent should do rather than
|
|
216
|
+
redirecting a guide into the repository it is working on — use a shell redirect
|
|
217
|
+
if you do want a copy.
|
|
217
218
|
|
|
218
|
-
`REF` and `--full` cannot be combined; that is refused rather than resolved
|
|
219
|
-
|
|
219
|
+
`REF` and `--full` cannot be combined; that is refused rather than resolved by a
|
|
220
|
+
precedence rule you would have to know.
|
|
220
221
|
|
|
221
222
|
### Navigating a Guide
|
|
222
223
|
|
|
223
|
-
The outline gives each section an index to fetch it by, and flags the ones
|
|
224
|
-
|
|
224
|
+
The outline gives each section an index to fetch it by, and flags the ones large
|
|
225
|
+
enough to be worth knowing about first:
|
|
225
226
|
|
|
226
227
|
```bash
|
|
227
228
|
$ readability guide cpp
|
|
@@ -235,28 +236,28 @@ Google C++ Style Guide
|
|
|
235
236
|
# 140 sections · print one: readability guide cpp 4.5.1
|
|
236
237
|
```
|
|
237
238
|
|
|
238
|
-
Sizes appear only at 1200 words and above — the 4% of sections expensive
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
239
|
+
Sizes appear only at 1200 words and above — the 4% of sections expensive enough
|
|
240
|
+
that you would want warning. They include subsections, since that is what the
|
|
241
|
+
reference returns. The trailing line goes to stderr, so it never contaminates a
|
|
242
|
+
piped outline.
|
|
242
243
|
|
|
243
244
|
A section reference can be any of the following:
|
|
244
245
|
|
|
245
|
-
| Reference
|
|
246
|
-
|
|
247
|
-
| Section index, as shown by the outline
|
|
248
|
-
| Heading text, case-insensitive, or its slug | `"function comments"`
|
|
246
|
+
| Reference | Example |
|
|
247
|
+
| ------------------------------------------- | ---------------------- |
|
|
248
|
+
| Section index, as shown by the outline | `2.2.4` |
|
|
249
|
+
| Heading text, case-insensitive, or its slug | `"function comments"` |
|
|
249
250
|
| A parent-scoped path, spaces around the `>` | `"Imports > Decision"` |
|
|
250
251
|
|
|
251
|
-
Whole matches are preferred; a reference that matches nothing in full is
|
|
252
|
-
|
|
252
|
+
Whole matches are preferred; a reference that matches nothing in full is retried
|
|
253
|
+
as a substring of the heading text.
|
|
253
254
|
|
|
254
255
|
Three of the shipped guides — Python, JavaScript, and Java — number their own
|
|
255
256
|
sections, and those numbers are the index. A rule cited from the outline then
|
|
256
|
-
matches the published guide exactly, including where the guide skips a
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
257
|
+
matches the published guide exactly, including where the guide skips a number:
|
|
258
|
+
the Python guide has no 2.15 at all, so its 2.16 is listed as 2.16 rather than
|
|
259
|
+
renumbered. The other eleven guides number nothing, so their index comes from
|
|
260
|
+
each heading's position in the tree.
|
|
260
261
|
|
|
261
262
|
Either way the index is unique, which is what makes a repeated heading
|
|
262
263
|
addressable — `Definition`, `Pros`, `Cons`, and `Decision` appear under every
|
|
@@ -279,8 +280,8 @@ Error: 'Decision' matches 19 headings in the 'python' guide. Repeat with one of:
|
|
|
279
280
|
|
|
280
281
|
A guide discusses plenty that no heading is named after, so a reference that
|
|
281
282
|
matches nothing is usually a vocabulary mismatch rather than a mistake. The
|
|
282
|
-
sections that mention the words are reported, which turns the miss into the
|
|
283
|
-
|
|
283
|
+
sections that mention the words are reported, which turns the miss into the next
|
|
284
|
+
command:
|
|
284
285
|
|
|
285
286
|
```bash
|
|
286
287
|
$ readability guide python f-string
|
|
@@ -290,22 +291,21 @@ It appears in these sections:
|
|
|
290
291
|
3.10.1 Python Style Rules > Strings > Logging
|
|
291
292
|
```
|
|
292
293
|
|
|
293
|
-
This locates a rule; it does not search text. For that, pipe `--full` to
|
|
294
|
-
|
|
295
|
-
the rest:
|
|
294
|
+
This locates a rule; it does not search text. For that, pipe `--full` to `grep`,
|
|
295
|
+
which you already know and which brings its own `-i`, `-A`, `-c` and the rest:
|
|
296
296
|
|
|
297
297
|
```bash
|
|
298
298
|
readability guide python --full | grep -in -A2 "f-string"
|
|
299
299
|
```
|
|
300
300
|
|
|
301
|
-
Content goes to stdout and diagnostics to stderr, so every form is safe to
|
|
302
|
-
|
|
303
|
-
|
|
301
|
+
Content goes to stdout and diagnostics to stderr, so every form is safe to pipe.
|
|
302
|
+
Headings inside fenced code blocks are ignored, which matters for the Shell and
|
|
303
|
+
Python guides where `#` starts a comment.
|
|
304
304
|
|
|
305
305
|
### Supported Languages
|
|
306
306
|
|
|
307
|
-
Run `readability guide` with no language for the full list and which guides
|
|
308
|
-
|
|
307
|
+
Run `readability guide` with no language for the full list and which guides are
|
|
308
|
+
cached:
|
|
309
309
|
|
|
310
310
|
```bash
|
|
311
311
|
$ readability guide
|
|
@@ -338,17 +338,16 @@ readability sync
|
|
|
338
338
|
|
|
339
339
|
### Offline Mode
|
|
340
340
|
|
|
341
|
-
The tool stores local copies of the style guides in the `guides/` directory
|
|
342
|
-
|
|
343
|
-
|
|
341
|
+
The tool stores local copies of the style guides in the `guides/` directory and
|
|
342
|
+
the `guide` command uses these local files when they exist. The bundled copies
|
|
343
|
+
are automatically synchronized weekly from the official
|
|
344
344
|
[Google Style Guides](https://google.github.io/styleguide/) repository via
|
|
345
|
-
GitHub Actions, and you can refresh your local cache at any time with the
|
|
346
|
-
|
|
345
|
+
GitHub Actions, and you can refresh your local cache at any time with the `sync`
|
|
346
|
+
command.
|
|
347
347
|
|
|
348
348
|
You can override the default `guides/` directory by setting the
|
|
349
349
|
`READABILITY_CACHE` environment variable. This is useful if you want to store
|
|
350
|
-
the guides in a specific location or share them across different
|
|
351
|
-
installations:
|
|
350
|
+
the guides in a specific location or share them across different installations:
|
|
352
351
|
|
|
353
352
|
```bash
|
|
354
353
|
export READABILITY_CACHE=/path/to/my/guides
|
|
@@ -3,22 +3,21 @@
|
|
|
3
3
|
A CLI tool that keeps code aligned with Google style conventions. It runs the
|
|
4
4
|
right linters, formatters, and type checkers for your project with sensible
|
|
5
5
|
defaults, and serves the official Google style guides in Markdown format. This
|
|
6
|
-
is ideal for AI agents or developers who want consistent code quality checks
|
|
7
|
-
|
|
6
|
+
is ideal for AI agents or developers who want consistent code quality checks and
|
|
7
|
+
quick access to style conventions without browsing HTML pages.
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
11
|
- **Linting & Formatting**: A `check` command that automatically detects and
|
|
12
12
|
runs relevant tools (Ruff, Pyrefly, Biome, Prettier, gofmt) for your project.
|
|
13
|
-
- **Sensible Defaults**:
|
|
14
|
-
|
|
15
|
-
own.
|
|
13
|
+
- **Sensible Defaults**: Google-style defaults for Ruff, Pyrefly, Biome, and
|
|
14
|
+
Prettier are used automatically when a project does not define its own.
|
|
16
15
|
- **Style Guides**: A `guide` command that fetches the latest Google style
|
|
17
|
-
guides (Python, Shell, C++, Java, JS/TS, Go, etc.) converted to Markdown,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- **Offline Mode**: Local caching of style guides for fast, offline access,
|
|
21
|
-
|
|
16
|
+
guides (Python, Shell, C++, Java, JS/TS, Go, etc.) converted to Markdown, and
|
|
17
|
+
outlines, addresses, and searches them by section rather than serving 200 KB
|
|
18
|
+
to be read whole.
|
|
19
|
+
- **Offline Mode**: Local caching of style guides for fast, offline access, kept
|
|
20
|
+
fresh with a single `sync` command.
|
|
22
21
|
|
|
23
22
|
## Quick Start
|
|
24
23
|
|
|
@@ -81,38 +80,39 @@ readability check . --fix
|
|
|
81
80
|
|
|
82
81
|
### Supported Tools
|
|
83
82
|
|
|
84
|
-
| Tool
|
|
85
|
-
|
|
86
|
-
| **Ruff**
|
|
87
|
-
| **Pyrefly**
|
|
88
|
-
| **Biome**
|
|
89
|
-
| **Prettier** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.css`, `.scss`, `.html`, `.md`, `.yml`, `.yaml` |
|
|
90
|
-
| **gofmt**
|
|
83
|
+
| Tool | Supported Extensions | Config Needed | Fetched By |
|
|
84
|
+
| ------------ | --------------------------------------------------------------------------------------- | --------------------------------- | ---------- |
|
|
85
|
+
| **Ruff** | `.py` | none, bundled | `uvx` |
|
|
86
|
+
| **Pyrefly** | `.py` | none, bundled | `uvx` |
|
|
87
|
+
| **Biome** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.jsonc`, `.css`, `.html` | none, bundled | `npx` |
|
|
88
|
+
| **Prettier** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.css`, `.scss`, `.html`, `.md`, `.yml`, `.yaml` | none for Markdown, YAML, and SCSS | `npx` |
|
|
89
|
+
| **gofmt** | `.go` | `go.mod` | — |
|
|
91
90
|
|
|
92
91
|
**You do not need to install any of these.** Each is resolved in order: a
|
|
93
|
-
project-local install (`node_modules/.bin`, `.venv/bin`) first, then whatever
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
project-local install (`node_modules/.bin`, `.venv/bin`) first, then whatever is
|
|
93
|
+
on your `PATH`, and only then fetched by `uvx` or `npx`. The runners cache what
|
|
94
|
+
they download, so the fetch happens once per machine and later runs are served
|
|
95
|
+
from disk and work offline.
|
|
97
96
|
|
|
98
|
-
That keeps this package at ~4 MB rather than the ~54 MB it would take to
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
That keeps this package at ~4 MB rather than the ~54 MB it would take to carry
|
|
98
|
+
Ruff and Pyrefly itself — a cost that would fall on everyone using only `guide`.
|
|
99
|
+
An installed copy always wins over a fetched one, so a project that pinned a
|
|
100
|
+
version is linted against the rules it chose.
|
|
102
101
|
|
|
103
102
|
Fetched tools carry a minimum version, enough to understand the bundled
|
|
104
103
|
configurations, and no maximum. A ceiling would freeze anyone who installed
|
|
105
|
-
nothing at whatever was current when this package shipped, and tie its
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
nothing at whatever was current when this package shipped, and tie its releases
|
|
105
|
+
to Ruff's — which has published seventeen minor series, roughly one every six
|
|
106
|
+
weeks. If you need a fixed version, install it: an installed tool always wins
|
|
107
|
+
over a fetched one.
|
|
109
108
|
|
|
110
|
-
Set `UV_OFFLINE=1` to forbid fetching. A tool that then cannot be reached
|
|
111
|
-
|
|
109
|
+
Set `UV_OFFLINE=1` to forbid fetching. A tool that then cannot be reached fails
|
|
110
|
+
the run rather than passing it.
|
|
112
111
|
|
|
113
112
|
Ruff, Pyrefly, and Biome ship with bundled configurations, so they run on any
|
|
114
|
-
file they handle without the project arranging anything. Prettier
|
|
115
|
-
|
|
113
|
+
file they handle without the project arranging anything. Prettier does the same
|
|
114
|
+
for Markdown, YAML, and SCSS; a Prettier configuration opts its overlapping web
|
|
115
|
+
formats into Prettier too. Gofmt waits for a `go.mod` file.
|
|
116
116
|
|
|
117
117
|
A tool that could not be reached at all is never skipped quietly:
|
|
118
118
|
|
|
@@ -127,8 +127,8 @@ $ readability check src/
|
|
|
127
127
|
Error: Every tool for 1 path(s) is missing, so nothing was verified.
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
That second case needs neither the tool nor a runner to be present, which is
|
|
131
|
-
|
|
130
|
+
That second case needs neither the tool nor a runner to be present, which is the
|
|
131
|
+
state a container image is usually in.
|
|
132
132
|
|
|
133
133
|
`check` exits non-zero on findings, tool failures, and when every applicable
|
|
134
134
|
tool is absent, so it can gate CI without a clean exit meaning required tools
|
|
@@ -151,27 +151,28 @@ if report.findings or report.failed or not report.ran:
|
|
|
151
151
|
```
|
|
152
152
|
|
|
153
153
|
The returned `CheckReport` records only whether findings occurred and which
|
|
154
|
-
tools ran, were skipped, or failed. Detailed tool findings are still written
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
154
|
+
tools ran, were skipped, or failed. Detailed tool findings are still written as
|
|
155
|
+
each tool runs. Every path is validated before any tool runs, and a missing one
|
|
156
|
+
raises `FileNotFoundError` rather than being misreported as a finding. Relative
|
|
157
|
+
paths remain relative to the process working directory; `project_root` controls
|
|
158
|
+
configuration discovery only.
|
|
159
159
|
|
|
160
160
|
### Default Configurations
|
|
161
161
|
|
|
162
162
|
Ruff and Pyrefly defaults follow the
|
|
163
163
|
[Google Python style guide](https://google.github.io/styleguide/pyguide.html):
|
|
164
|
-
80-column lines, Google docstrings, import ordering, and full type checking.
|
|
165
|
-
|
|
164
|
+
80-column lines, Google docstrings, import ordering, and full type checking. The
|
|
165
|
+
Biome default applies the 80-column lines and two-space indentation of the
|
|
166
166
|
[Google JavaScript style guide](https://google.github.io/styleguide/jsguide.html)
|
|
167
|
-
and enables Biome's recommended lint rules.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
167
|
+
and enables Biome's recommended lint rules. Prettier wraps prose at 80 columns,
|
|
168
|
+
following the
|
|
169
|
+
[Google Markdown style guide](https://google.github.io/styleguide/docguide/style.html#character-line-limit).
|
|
170
|
+
These defaults apply only when the project does not define its own
|
|
171
|
+
configuration. To override them, add a `[tool.ruff]` or `[tool.pyrefly]` section
|
|
172
|
+
to your `pyproject.toml`, or a dedicated `ruff.toml`, `pyrefly.toml`,
|
|
173
|
+
`biome.json`, `biome.jsonc`, or Prettier configuration — any project-level
|
|
174
|
+
configuration takes full precedence. The bundled Biome file requires Biome 2.5
|
|
175
|
+
or later, matching the version floor used by the fallback runner.
|
|
175
176
|
|
|
176
177
|
## Style Guides
|
|
177
178
|
|
|
@@ -197,17 +198,17 @@ readability guide python --full | grep -i f-string
|
|
|
197
198
|
|
|
198
199
|
A guide can exceed 200 KB, so the outline is what a bare invocation prints:
|
|
199
200
|
listing the sections and fetching the one you need beats reading the lot.
|
|
200
|
-
Nothing is written to disk, which is what a coding agent should do rather
|
|
201
|
-
|
|
202
|
-
|
|
201
|
+
Nothing is written to disk, which is what a coding agent should do rather than
|
|
202
|
+
redirecting a guide into the repository it is working on — use a shell redirect
|
|
203
|
+
if you do want a copy.
|
|
203
204
|
|
|
204
|
-
`REF` and `--full` cannot be combined; that is refused rather than resolved
|
|
205
|
-
|
|
205
|
+
`REF` and `--full` cannot be combined; that is refused rather than resolved by a
|
|
206
|
+
precedence rule you would have to know.
|
|
206
207
|
|
|
207
208
|
### Navigating a Guide
|
|
208
209
|
|
|
209
|
-
The outline gives each section an index to fetch it by, and flags the ones
|
|
210
|
-
|
|
210
|
+
The outline gives each section an index to fetch it by, and flags the ones large
|
|
211
|
+
enough to be worth knowing about first:
|
|
211
212
|
|
|
212
213
|
```bash
|
|
213
214
|
$ readability guide cpp
|
|
@@ -221,28 +222,28 @@ Google C++ Style Guide
|
|
|
221
222
|
# 140 sections · print one: readability guide cpp 4.5.1
|
|
222
223
|
```
|
|
223
224
|
|
|
224
|
-
Sizes appear only at 1200 words and above — the 4% of sections expensive
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
Sizes appear only at 1200 words and above — the 4% of sections expensive enough
|
|
226
|
+
that you would want warning. They include subsections, since that is what the
|
|
227
|
+
reference returns. The trailing line goes to stderr, so it never contaminates a
|
|
228
|
+
piped outline.
|
|
228
229
|
|
|
229
230
|
A section reference can be any of the following:
|
|
230
231
|
|
|
231
|
-
| Reference
|
|
232
|
-
|
|
233
|
-
| Section index, as shown by the outline
|
|
234
|
-
| Heading text, case-insensitive, or its slug | `"function comments"`
|
|
232
|
+
| Reference | Example |
|
|
233
|
+
| ------------------------------------------- | ---------------------- |
|
|
234
|
+
| Section index, as shown by the outline | `2.2.4` |
|
|
235
|
+
| Heading text, case-insensitive, or its slug | `"function comments"` |
|
|
235
236
|
| A parent-scoped path, spaces around the `>` | `"Imports > Decision"` |
|
|
236
237
|
|
|
237
|
-
Whole matches are preferred; a reference that matches nothing in full is
|
|
238
|
-
|
|
238
|
+
Whole matches are preferred; a reference that matches nothing in full is retried
|
|
239
|
+
as a substring of the heading text.
|
|
239
240
|
|
|
240
241
|
Three of the shipped guides — Python, JavaScript, and Java — number their own
|
|
241
242
|
sections, and those numbers are the index. A rule cited from the outline then
|
|
242
|
-
matches the published guide exactly, including where the guide skips a
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
243
|
+
matches the published guide exactly, including where the guide skips a number:
|
|
244
|
+
the Python guide has no 2.15 at all, so its 2.16 is listed as 2.16 rather than
|
|
245
|
+
renumbered. The other eleven guides number nothing, so their index comes from
|
|
246
|
+
each heading's position in the tree.
|
|
246
247
|
|
|
247
248
|
Either way the index is unique, which is what makes a repeated heading
|
|
248
249
|
addressable — `Definition`, `Pros`, `Cons`, and `Decision` appear under every
|
|
@@ -265,8 +266,8 @@ Error: 'Decision' matches 19 headings in the 'python' guide. Repeat with one of:
|
|
|
265
266
|
|
|
266
267
|
A guide discusses plenty that no heading is named after, so a reference that
|
|
267
268
|
matches nothing is usually a vocabulary mismatch rather than a mistake. The
|
|
268
|
-
sections that mention the words are reported, which turns the miss into the
|
|
269
|
-
|
|
269
|
+
sections that mention the words are reported, which turns the miss into the next
|
|
270
|
+
command:
|
|
270
271
|
|
|
271
272
|
```bash
|
|
272
273
|
$ readability guide python f-string
|
|
@@ -276,22 +277,21 @@ It appears in these sections:
|
|
|
276
277
|
3.10.1 Python Style Rules > Strings > Logging
|
|
277
278
|
```
|
|
278
279
|
|
|
279
|
-
This locates a rule; it does not search text. For that, pipe `--full` to
|
|
280
|
-
|
|
281
|
-
the rest:
|
|
280
|
+
This locates a rule; it does not search text. For that, pipe `--full` to `grep`,
|
|
281
|
+
which you already know and which brings its own `-i`, `-A`, `-c` and the rest:
|
|
282
282
|
|
|
283
283
|
```bash
|
|
284
284
|
readability guide python --full | grep -in -A2 "f-string"
|
|
285
285
|
```
|
|
286
286
|
|
|
287
|
-
Content goes to stdout and diagnostics to stderr, so every form is safe to
|
|
288
|
-
|
|
289
|
-
|
|
287
|
+
Content goes to stdout and diagnostics to stderr, so every form is safe to pipe.
|
|
288
|
+
Headings inside fenced code blocks are ignored, which matters for the Shell and
|
|
289
|
+
Python guides where `#` starts a comment.
|
|
290
290
|
|
|
291
291
|
### Supported Languages
|
|
292
292
|
|
|
293
|
-
Run `readability guide` with no language for the full list and which guides
|
|
294
|
-
|
|
293
|
+
Run `readability guide` with no language for the full list and which guides are
|
|
294
|
+
cached:
|
|
295
295
|
|
|
296
296
|
```bash
|
|
297
297
|
$ readability guide
|
|
@@ -324,17 +324,16 @@ readability sync
|
|
|
324
324
|
|
|
325
325
|
### Offline Mode
|
|
326
326
|
|
|
327
|
-
The tool stores local copies of the style guides in the `guides/` directory
|
|
328
|
-
|
|
329
|
-
|
|
327
|
+
The tool stores local copies of the style guides in the `guides/` directory and
|
|
328
|
+
the `guide` command uses these local files when they exist. The bundled copies
|
|
329
|
+
are automatically synchronized weekly from the official
|
|
330
330
|
[Google Style Guides](https://google.github.io/styleguide/) repository via
|
|
331
|
-
GitHub Actions, and you can refresh your local cache at any time with the
|
|
332
|
-
|
|
331
|
+
GitHub Actions, and you can refresh your local cache at any time with the `sync`
|
|
332
|
+
command.
|
|
333
333
|
|
|
334
334
|
You can override the default `guides/` directory by setting the
|
|
335
335
|
`READABILITY_CACHE` environment variable. This is useful if you want to store
|
|
336
|
-
the guides in a specific location or share them across different
|
|
337
|
-
installations:
|
|
336
|
+
the guides in a specific location or share them across different installations:
|
|
338
337
|
|
|
339
338
|
```bash
|
|
340
339
|
export READABILITY_CACHE=/path/to/my/guides
|
|
@@ -1288,27 +1288,27 @@ def _should_run_tool(
|
|
|
1288
1288
|
Returns:
|
|
1289
1289
|
True if the tool should run, False otherwise.
|
|
1290
1290
|
"""
|
|
1291
|
-
#
|
|
1292
|
-
#
|
|
1293
|
-
|
|
1294
|
-
# between checking a file and checking nothing. Tools without defaults
|
|
1295
|
-
# still wait to be asked, since there is no sane way to run them.
|
|
1296
|
-
has_trigger = _bundled_config(tool["name"]).exists() or any(
|
|
1291
|
+
# Project configuration opts a tool into every extension it supports;
|
|
1292
|
+
# otherwise it handles only the formats with safe readability defaults.
|
|
1293
|
+
has_project_config = any(
|
|
1297
1294
|
(project_root / t).exists() for t in tool["trigger"]
|
|
1298
1295
|
)
|
|
1296
|
+
extensions = (
|
|
1297
|
+
tool["extensions"] if has_project_config else tool["default_extensions"]
|
|
1298
|
+
)
|
|
1299
1299
|
|
|
1300
1300
|
# Files must match one of the tool's supported extensions.
|
|
1301
1301
|
if path.is_file():
|
|
1302
|
-
return
|
|
1302
|
+
return path.suffix in extensions
|
|
1303
1303
|
|
|
1304
|
-
if not
|
|
1304
|
+
if not extensions:
|
|
1305
1305
|
return False
|
|
1306
1306
|
|
|
1307
1307
|
# A directory trigger alone is not evidence that the tool checked a file.
|
|
1308
1308
|
# Several tools deliberately exit zero when nothing matches, which would
|
|
1309
1309
|
# otherwise turn an unsupported-only tree into a reported clean result.
|
|
1310
1310
|
return any(
|
|
1311
|
-
candidate.is_file() and candidate.suffix in
|
|
1311
|
+
candidate.is_file() and candidate.suffix in extensions
|
|
1312
1312
|
for candidate in path.rglob("*")
|
|
1313
1313
|
)
|
|
1314
1314
|
|
|
@@ -1518,6 +1518,11 @@ def _get_tool_definitions(
|
|
|
1518
1518
|
pyrefly = _tool_command("pyrefly", project_root)
|
|
1519
1519
|
biome = _tool_command("biome", project_root)
|
|
1520
1520
|
prettier = _tool_command("prettier", project_root)
|
|
1521
|
+
prettier_defaults = [
|
|
1522
|
+
"--print-width=80",
|
|
1523
|
+
"--prose-wrap=always",
|
|
1524
|
+
"--config-precedence=prefer-file",
|
|
1525
|
+
]
|
|
1521
1526
|
|
|
1522
1527
|
return [
|
|
1523
1528
|
{
|
|
@@ -1554,6 +1559,7 @@ def _get_tool_definitions(
|
|
|
1554
1559
|
],
|
|
1555
1560
|
"trigger": ["pyproject.toml", "ruff.toml", ".ruff.toml"],
|
|
1556
1561
|
"extensions": [".py"],
|
|
1562
|
+
"default_extensions": [".py"],
|
|
1557
1563
|
},
|
|
1558
1564
|
{
|
|
1559
1565
|
# Type checker only: it reports findings but cannot fix or format
|
|
@@ -1567,6 +1573,7 @@ def _get_tool_definitions(
|
|
|
1567
1573
|
**({"cwd": project_root} if pyrefly_project_mode else {}),
|
|
1568
1574
|
"trigger": ["pyproject.toml", "pyrefly.toml"],
|
|
1569
1575
|
"extensions": [".py"],
|
|
1576
|
+
"default_extensions": [".py"],
|
|
1570
1577
|
},
|
|
1571
1578
|
{
|
|
1572
1579
|
"name": "biome",
|
|
@@ -1611,18 +1618,30 @@ def _get_tool_definitions(
|
|
|
1611
1618
|
".css",
|
|
1612
1619
|
".html",
|
|
1613
1620
|
],
|
|
1621
|
+
"default_extensions": [
|
|
1622
|
+
".js",
|
|
1623
|
+
".ts",
|
|
1624
|
+
".jsx",
|
|
1625
|
+
".tsx",
|
|
1626
|
+
".json",
|
|
1627
|
+
".jsonc",
|
|
1628
|
+
".css",
|
|
1629
|
+
".html",
|
|
1630
|
+
],
|
|
1614
1631
|
},
|
|
1615
1632
|
{
|
|
1616
1633
|
"name": "prettier",
|
|
1617
1634
|
"check_format": [
|
|
1618
1635
|
*prettier,
|
|
1619
1636
|
"--check",
|
|
1637
|
+
*prettier_defaults,
|
|
1620
1638
|
"--no-error-on-unmatched-pattern",
|
|
1621
1639
|
path_str,
|
|
1622
1640
|
],
|
|
1623
1641
|
"format": [
|
|
1624
1642
|
*prettier,
|
|
1625
1643
|
"--write",
|
|
1644
|
+
*prettier_defaults,
|
|
1626
1645
|
"--no-error-on-unmatched-pattern",
|
|
1627
1646
|
path_str,
|
|
1628
1647
|
],
|
|
@@ -1648,6 +1667,7 @@ def _get_tool_definitions(
|
|
|
1648
1667
|
".yml",
|
|
1649
1668
|
".yaml",
|
|
1650
1669
|
],
|
|
1670
|
+
"default_extensions": [".md", ".yml", ".yaml", ".scss"],
|
|
1651
1671
|
},
|
|
1652
1672
|
{
|
|
1653
1673
|
"name": "go fmt",
|
|
@@ -1655,6 +1675,7 @@ def _get_tool_definitions(
|
|
|
1655
1675
|
"format": ["go", "fmt", path_str],
|
|
1656
1676
|
"trigger": ["go.mod"],
|
|
1657
1677
|
"extensions": [".go"],
|
|
1678
|
+
"default_extensions": [],
|
|
1658
1679
|
},
|
|
1659
1680
|
]
|
|
1660
1681
|
|
|
@@ -1741,7 +1762,7 @@ def _tool_checked_files(
|
|
|
1741
1762
|
if tool_name != "biome":
|
|
1742
1763
|
return True
|
|
1743
1764
|
output = f"{result.stdout or ''}\n{result.stderr or ''}"
|
|
1744
|
-
# Biome
|
|
1765
|
+
# Biome 2.x uses these summaries for an unmatched target.
|
|
1745
1766
|
zero_file_summaries = ("Checked 0 files", "Formatted 0 files")
|
|
1746
1767
|
return not any(summary in output for summary in zero_file_summaries)
|
|
1747
1768
|
|
|
@@ -653,6 +653,7 @@ def test_bundled_default_configs_are_valid() -> None:
|
|
|
653
653
|
"lineWidth": 80,
|
|
654
654
|
}
|
|
655
655
|
assert biome_config["linter"]["rules"]["recommended"] is True
|
|
656
|
+
assert biome_config["html"]["parser"]["interpolation"] is True
|
|
656
657
|
|
|
657
658
|
# The ruff defaults follow the Google Python style guide
|
|
658
659
|
ruff_config = tomllib.loads(_bundled_config("ruff").read_text())
|
|
@@ -1978,6 +1979,88 @@ def test_check_runs_biome_without_a_project_config(
|
|
|
1978
1979
|
)
|
|
1979
1980
|
|
|
1980
1981
|
|
|
1982
|
+
@pytest.mark.parametrize("extension", (".md", ".yml", ".yaml", ".scss"))
|
|
1983
|
+
@patch("shutil.which")
|
|
1984
|
+
@patch("subprocess.run")
|
|
1985
|
+
def test_check_runs_prettier_for_unsupported_biome_formats_without_config(
|
|
1986
|
+
mock_run: MagicMock,
|
|
1987
|
+
mock_which: MagicMock,
|
|
1988
|
+
tmp_path: Path,
|
|
1989
|
+
extension: str,
|
|
1990
|
+
) -> None:
|
|
1991
|
+
"""Prettier covers its default formats without project configuration."""
|
|
1992
|
+
mock_which.side_effect = lambda name: name
|
|
1993
|
+
mock_run.return_value = MagicMock(returncode=0, stdout="", stderr="")
|
|
1994
|
+
|
|
1995
|
+
runner = CliRunner()
|
|
1996
|
+
with runner.isolated_filesystem(temp_dir=tmp_path):
|
|
1997
|
+
Path(f"document{extension}").touch()
|
|
1998
|
+
|
|
1999
|
+
result = runner.invoke(cli, ["check", f"document{extension}"])
|
|
2000
|
+
|
|
2001
|
+
assert result.exit_code == 0
|
|
2002
|
+
commands = [invocation.args[0] for invocation in mock_run.call_args_list]
|
|
2003
|
+
assert len(commands) == 1
|
|
2004
|
+
assert commands[0][0] == "prettier"
|
|
2005
|
+
|
|
2006
|
+
|
|
2007
|
+
def test_prettier_uses_google_markdown_defaults(tmp_path: Path) -> None:
|
|
2008
|
+
"""CLI defaults wrap Markdown while deferring to project configuration."""
|
|
2009
|
+
tools = {
|
|
2010
|
+
tool["name"]: tool
|
|
2011
|
+
for tool in _get_tool_definitions(Path("document.md"), tmp_path)
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
for command_name in ("check_format", "format"):
|
|
2015
|
+
command = tools["prettier"][command_name]
|
|
2016
|
+
assert "--print-width=80" in command
|
|
2017
|
+
assert "--prose-wrap=always" in command
|
|
2018
|
+
assert "--config-precedence=prefer-file" in command
|
|
2019
|
+
|
|
2020
|
+
|
|
2021
|
+
@patch("shutil.which")
|
|
2022
|
+
@patch("subprocess.run")
|
|
2023
|
+
def test_check_runs_prettier_for_configless_markdown_directory(
|
|
2024
|
+
mock_run: MagicMock, mock_which: MagicMock, tmp_path: Path
|
|
2025
|
+
) -> None:
|
|
2026
|
+
"""Default applicability also works when checking a directory."""
|
|
2027
|
+
mock_which.side_effect = lambda name: name
|
|
2028
|
+
mock_run.return_value = MagicMock(returncode=0, stdout="", stderr="")
|
|
2029
|
+
|
|
2030
|
+
runner = CliRunner()
|
|
2031
|
+
with runner.isolated_filesystem(temp_dir=tmp_path):
|
|
2032
|
+
Path("docs").mkdir()
|
|
2033
|
+
Path("docs/guide.md").touch()
|
|
2034
|
+
|
|
2035
|
+
result = runner.invoke(cli, ["check", "docs"])
|
|
2036
|
+
|
|
2037
|
+
assert result.exit_code == 0
|
|
2038
|
+
commands = [invocation.args[0] for invocation in mock_run.call_args_list]
|
|
2039
|
+
assert len(commands) == 1
|
|
2040
|
+
assert commands[0][0] == "prettier"
|
|
2041
|
+
|
|
2042
|
+
|
|
2043
|
+
@patch("shutil.which")
|
|
2044
|
+
@patch("subprocess.run")
|
|
2045
|
+
def test_prettier_project_config_opts_in_javascript(
|
|
2046
|
+
mock_run: MagicMock, mock_which: MagicMock, tmp_path: Path
|
|
2047
|
+
) -> None:
|
|
2048
|
+
"""A project configuration retains Prettier's existing broad coverage."""
|
|
2049
|
+
mock_which.side_effect = lambda name: name
|
|
2050
|
+
mock_run.return_value = MagicMock(returncode=0, stdout="", stderr="")
|
|
2051
|
+
|
|
2052
|
+
runner = CliRunner()
|
|
2053
|
+
with runner.isolated_filesystem(temp_dir=tmp_path):
|
|
2054
|
+
Path(".prettierrc").touch()
|
|
2055
|
+
Path("script.js").touch()
|
|
2056
|
+
|
|
2057
|
+
result = runner.invoke(cli, ["check", "script.js"])
|
|
2058
|
+
|
|
2059
|
+
assert result.exit_code == 0
|
|
2060
|
+
commands = [invocation.args[0][0] for invocation in mock_run.call_args_list]
|
|
2061
|
+
assert commands.count("prettier") == 1
|
|
2062
|
+
|
|
2063
|
+
|
|
1981
2064
|
@patch("shutil.which")
|
|
1982
2065
|
@patch("subprocess.run")
|
|
1983
2066
|
def test_bundled_tools_do_not_claim_an_unsupported_directory(
|
|
@@ -1989,7 +2072,7 @@ def test_bundled_tools_do_not_claim_an_unsupported_directory(
|
|
|
1989
2072
|
|
|
1990
2073
|
runner = CliRunner()
|
|
1991
2074
|
with runner.isolated_filesystem(temp_dir=tmp_path):
|
|
1992
|
-
Path("notes.
|
|
2075
|
+
Path("notes.txt").touch()
|
|
1993
2076
|
|
|
1994
2077
|
result = runner.invoke(cli, ["check", "."])
|
|
1995
2078
|
|
|
@@ -2023,7 +2106,7 @@ def test_biome_zero_file_result_is_not_reported_as_clean(
|
|
|
2023
2106
|
Path(".gitignore").write_text("node_modules/\n")
|
|
2024
2107
|
Path("node_modules/example").mkdir(parents=True)
|
|
2025
2108
|
Path("node_modules/example/index.js").touch()
|
|
2026
|
-
Path("README.
|
|
2109
|
+
Path("README.txt").touch()
|
|
2027
2110
|
|
|
2028
2111
|
for extra_args, expected_calls in (([], 2), (["--fix"], 3)):
|
|
2029
2112
|
mock_run.side_effect = (
|
|
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
|
|
File without changes
|
|
File without changes
|