readability-cli 0.8.5__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.5 → readability_cli-0.8.6}/.github/workflows/ci.yml +1 -1
- {readability_cli-0.8.5 → readability_cli-0.8.6}/.github/workflows/publish.yml +2 -2
- {readability_cli-0.8.5 → readability_cli-0.8.6}/.github/workflows/update-guides.yml +2 -2
- readability_cli-0.8.6/.prettierignore +2 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/PKG-INFO +88 -88
- {readability_cli-0.8.5 → readability_cli-0.8.6}/README.md +87 -87
- {readability_cli-0.8.5 → readability_cli-0.8.6}/pyproject.toml +1 -1
- {readability_cli-0.8.5 → readability_cli-0.8.6}/readability.py +30 -9
- {readability_cli-0.8.5 → readability_cli-0.8.6}/test_readability.py +84 -2
- {readability_cli-0.8.5 → readability_cli-0.8.6}/uv.lock +1 -1
- {readability_cli-0.8.5 → readability_cli-0.8.6}/.gitignore +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/.python-version +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/LICENSE +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/configs/biome-default.json +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/configs/pyrefly.toml +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/configs/ruff.toml +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/Rguide.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/cppguide.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/csharp-style.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/docguide-style.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/go-guide.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/htmlcssguide.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/javaguide.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/jsguide.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/jsoncstyleguide.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/objcguide.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/pyguide.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/shellguide.md +0 -0
- {readability_cli-0.8.5 → readability_cli-0.8.6}/guides/tsguide.md +0 -0
- {readability_cli-0.8.5 → 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,26 +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
|
-
|
|
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.
|
|
188
190
|
|
|
189
191
|
## Style Guides
|
|
190
192
|
|
|
@@ -210,17 +212,17 @@ readability guide python --full | grep -i f-string
|
|
|
210
212
|
|
|
211
213
|
A guide can exceed 200 KB, so the outline is what a bare invocation prints:
|
|
212
214
|
listing the sections and fetching the one you need beats reading the lot.
|
|
213
|
-
Nothing is written to disk, which is what a coding agent should do rather
|
|
214
|
-
|
|
215
|
-
|
|
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.
|
|
216
218
|
|
|
217
|
-
`REF` and `--full` cannot be combined; that is refused rather than resolved
|
|
218
|
-
|
|
219
|
+
`REF` and `--full` cannot be combined; that is refused rather than resolved by a
|
|
220
|
+
precedence rule you would have to know.
|
|
219
221
|
|
|
220
222
|
### Navigating a Guide
|
|
221
223
|
|
|
222
|
-
The outline gives each section an index to fetch it by, and flags the ones
|
|
223
|
-
|
|
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:
|
|
224
226
|
|
|
225
227
|
```bash
|
|
226
228
|
$ readability guide cpp
|
|
@@ -234,28 +236,28 @@ Google C++ Style Guide
|
|
|
234
236
|
# 140 sections · print one: readability guide cpp 4.5.1
|
|
235
237
|
```
|
|
236
238
|
|
|
237
|
-
Sizes appear only at 1200 words and above — the 4% of sections expensive
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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.
|
|
241
243
|
|
|
242
244
|
A section reference can be any of the following:
|
|
243
245
|
|
|
244
|
-
| Reference
|
|
245
|
-
|
|
246
|
-
| Section index, as shown by the outline
|
|
247
|
-
| 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"` |
|
|
248
250
|
| A parent-scoped path, spaces around the `>` | `"Imports > Decision"` |
|
|
249
251
|
|
|
250
|
-
Whole matches are preferred; a reference that matches nothing in full is
|
|
251
|
-
|
|
252
|
+
Whole matches are preferred; a reference that matches nothing in full is retried
|
|
253
|
+
as a substring of the heading text.
|
|
252
254
|
|
|
253
255
|
Three of the shipped guides — Python, JavaScript, and Java — number their own
|
|
254
256
|
sections, and those numbers are the index. A rule cited from the outline then
|
|
255
|
-
matches the published guide exactly, including where the guide skips a
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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.
|
|
259
261
|
|
|
260
262
|
Either way the index is unique, which is what makes a repeated heading
|
|
261
263
|
addressable — `Definition`, `Pros`, `Cons`, and `Decision` appear under every
|
|
@@ -278,8 +280,8 @@ Error: 'Decision' matches 19 headings in the 'python' guide. Repeat with one of:
|
|
|
278
280
|
|
|
279
281
|
A guide discusses plenty that no heading is named after, so a reference that
|
|
280
282
|
matches nothing is usually a vocabulary mismatch rather than a mistake. The
|
|
281
|
-
sections that mention the words are reported, which turns the miss into the
|
|
282
|
-
|
|
283
|
+
sections that mention the words are reported, which turns the miss into the next
|
|
284
|
+
command:
|
|
283
285
|
|
|
284
286
|
```bash
|
|
285
287
|
$ readability guide python f-string
|
|
@@ -289,22 +291,21 @@ It appears in these sections:
|
|
|
289
291
|
3.10.1 Python Style Rules > Strings > Logging
|
|
290
292
|
```
|
|
291
293
|
|
|
292
|
-
This locates a rule; it does not search text. For that, pipe `--full` to
|
|
293
|
-
|
|
294
|
-
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:
|
|
295
296
|
|
|
296
297
|
```bash
|
|
297
298
|
readability guide python --full | grep -in -A2 "f-string"
|
|
298
299
|
```
|
|
299
300
|
|
|
300
|
-
Content goes to stdout and diagnostics to stderr, so every form is safe to
|
|
301
|
-
|
|
302
|
-
|
|
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.
|
|
303
304
|
|
|
304
305
|
### Supported Languages
|
|
305
306
|
|
|
306
|
-
Run `readability guide` with no language for the full list and which guides
|
|
307
|
-
|
|
307
|
+
Run `readability guide` with no language for the full list and which guides are
|
|
308
|
+
cached:
|
|
308
309
|
|
|
309
310
|
```bash
|
|
310
311
|
$ readability guide
|
|
@@ -337,17 +338,16 @@ readability sync
|
|
|
337
338
|
|
|
338
339
|
### Offline Mode
|
|
339
340
|
|
|
340
|
-
The tool stores local copies of the style guides in the `guides/` directory
|
|
341
|
-
|
|
342
|
-
|
|
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
|
|
343
344
|
[Google Style Guides](https://google.github.io/styleguide/) repository via
|
|
344
|
-
GitHub Actions, and you can refresh your local cache at any time with the
|
|
345
|
-
|
|
345
|
+
GitHub Actions, and you can refresh your local cache at any time with the `sync`
|
|
346
|
+
command.
|
|
346
347
|
|
|
347
348
|
You can override the default `guides/` directory by setting the
|
|
348
349
|
`READABILITY_CACHE` environment variable. This is useful if you want to store
|
|
349
|
-
the guides in a specific location or share them across different
|
|
350
|
-
installations:
|
|
350
|
+
the guides in a specific location or share them across different installations:
|
|
351
351
|
|
|
352
352
|
```bash
|
|
353
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,26 +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
|
-
|
|
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.
|
|
174
176
|
|
|
175
177
|
## Style Guides
|
|
176
178
|
|
|
@@ -196,17 +198,17 @@ readability guide python --full | grep -i f-string
|
|
|
196
198
|
|
|
197
199
|
A guide can exceed 200 KB, so the outline is what a bare invocation prints:
|
|
198
200
|
listing the sections and fetching the one you need beats reading the lot.
|
|
199
|
-
Nothing is written to disk, which is what a coding agent should do rather
|
|
200
|
-
|
|
201
|
-
|
|
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.
|
|
202
204
|
|
|
203
|
-
`REF` and `--full` cannot be combined; that is refused rather than resolved
|
|
204
|
-
|
|
205
|
+
`REF` and `--full` cannot be combined; that is refused rather than resolved by a
|
|
206
|
+
precedence rule you would have to know.
|
|
205
207
|
|
|
206
208
|
### Navigating a Guide
|
|
207
209
|
|
|
208
|
-
The outline gives each section an index to fetch it by, and flags the ones
|
|
209
|
-
|
|
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:
|
|
210
212
|
|
|
211
213
|
```bash
|
|
212
214
|
$ readability guide cpp
|
|
@@ -220,28 +222,28 @@ Google C++ Style Guide
|
|
|
220
222
|
# 140 sections · print one: readability guide cpp 4.5.1
|
|
221
223
|
```
|
|
222
224
|
|
|
223
|
-
Sizes appear only at 1200 words and above — the 4% of sections expensive
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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.
|
|
227
229
|
|
|
228
230
|
A section reference can be any of the following:
|
|
229
231
|
|
|
230
|
-
| Reference
|
|
231
|
-
|
|
232
|
-
| Section index, as shown by the outline
|
|
233
|
-
| 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"` |
|
|
234
236
|
| A parent-scoped path, spaces around the `>` | `"Imports > Decision"` |
|
|
235
237
|
|
|
236
|
-
Whole matches are preferred; a reference that matches nothing in full is
|
|
237
|
-
|
|
238
|
+
Whole matches are preferred; a reference that matches nothing in full is retried
|
|
239
|
+
as a substring of the heading text.
|
|
238
240
|
|
|
239
241
|
Three of the shipped guides — Python, JavaScript, and Java — number their own
|
|
240
242
|
sections, and those numbers are the index. A rule cited from the outline then
|
|
241
|
-
matches the published guide exactly, including where the guide skips a
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
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.
|
|
245
247
|
|
|
246
248
|
Either way the index is unique, which is what makes a repeated heading
|
|
247
249
|
addressable — `Definition`, `Pros`, `Cons`, and `Decision` appear under every
|
|
@@ -264,8 +266,8 @@ Error: 'Decision' matches 19 headings in the 'python' guide. Repeat with one of:
|
|
|
264
266
|
|
|
265
267
|
A guide discusses plenty that no heading is named after, so a reference that
|
|
266
268
|
matches nothing is usually a vocabulary mismatch rather than a mistake. The
|
|
267
|
-
sections that mention the words are reported, which turns the miss into the
|
|
268
|
-
|
|
269
|
+
sections that mention the words are reported, which turns the miss into the next
|
|
270
|
+
command:
|
|
269
271
|
|
|
270
272
|
```bash
|
|
271
273
|
$ readability guide python f-string
|
|
@@ -275,22 +277,21 @@ It appears in these sections:
|
|
|
275
277
|
3.10.1 Python Style Rules > Strings > Logging
|
|
276
278
|
```
|
|
277
279
|
|
|
278
|
-
This locates a rule; it does not search text. For that, pipe `--full` to
|
|
279
|
-
|
|
280
|
-
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:
|
|
281
282
|
|
|
282
283
|
```bash
|
|
283
284
|
readability guide python --full | grep -in -A2 "f-string"
|
|
284
285
|
```
|
|
285
286
|
|
|
286
|
-
Content goes to stdout and diagnostics to stderr, so every form is safe to
|
|
287
|
-
|
|
288
|
-
|
|
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.
|
|
289
290
|
|
|
290
291
|
### Supported Languages
|
|
291
292
|
|
|
292
|
-
Run `readability guide` with no language for the full list and which guides
|
|
293
|
-
|
|
293
|
+
Run `readability guide` with no language for the full list and which guides are
|
|
294
|
+
cached:
|
|
294
295
|
|
|
295
296
|
```bash
|
|
296
297
|
$ readability guide
|
|
@@ -323,17 +324,16 @@ readability sync
|
|
|
323
324
|
|
|
324
325
|
### Offline Mode
|
|
325
326
|
|
|
326
|
-
The tool stores local copies of the style guides in the `guides/` directory
|
|
327
|
-
|
|
328
|
-
|
|
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
|
|
329
330
|
[Google Style Guides](https://google.github.io/styleguide/) repository via
|
|
330
|
-
GitHub Actions, and you can refresh your local cache at any time with the
|
|
331
|
-
|
|
331
|
+
GitHub Actions, and you can refresh your local cache at any time with the `sync`
|
|
332
|
+
command.
|
|
332
333
|
|
|
333
334
|
You can override the default `guides/` directory by setting the
|
|
334
335
|
`READABILITY_CACHE` environment variable. This is useful if you want to store
|
|
335
|
-
the guides in a specific location or share them across different
|
|
336
|
-
installations:
|
|
336
|
+
the guides in a specific location or share them across different installations:
|
|
337
337
|
|
|
338
338
|
```bash
|
|
339
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
|
|
|
@@ -1979,6 +1979,88 @@ def test_check_runs_biome_without_a_project_config(
|
|
|
1979
1979
|
)
|
|
1980
1980
|
|
|
1981
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
|
+
|
|
1982
2064
|
@patch("shutil.which")
|
|
1983
2065
|
@patch("subprocess.run")
|
|
1984
2066
|
def test_bundled_tools_do_not_claim_an_unsupported_directory(
|
|
@@ -1990,7 +2072,7 @@ def test_bundled_tools_do_not_claim_an_unsupported_directory(
|
|
|
1990
2072
|
|
|
1991
2073
|
runner = CliRunner()
|
|
1992
2074
|
with runner.isolated_filesystem(temp_dir=tmp_path):
|
|
1993
|
-
Path("notes.
|
|
2075
|
+
Path("notes.txt").touch()
|
|
1994
2076
|
|
|
1995
2077
|
result = runner.invoke(cli, ["check", "."])
|
|
1996
2078
|
|
|
@@ -2024,7 +2106,7 @@ def test_biome_zero_file_result_is_not_reported_as_clean(
|
|
|
2024
2106
|
Path(".gitignore").write_text("node_modules/\n")
|
|
2025
2107
|
Path("node_modules/example").mkdir(parents=True)
|
|
2026
2108
|
Path("node_modules/example/index.js").touch()
|
|
2027
|
-
Path("README.
|
|
2109
|
+
Path("README.txt").touch()
|
|
2028
2110
|
|
|
2029
2111
|
for extra_args, expected_calls in (([], 2), (["--fix"], 3)):
|
|
2030
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
|
|
File without changes
|