lintlane 2.5.0 → 3.0.1
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.
- package/LICENSE +21 -0
- package/README.md +223 -97
- package/bin/ci.mjs +82 -76
- package/bin/cli.mjs +102 -180
- package/bin/pre-commit.mjs +55 -0
- package/bin/proc.mjs +113 -0
- package/bin/project.mjs +180 -0
- package/bin/staged.mjs +333 -0
- package/bin/ui-server.mjs +175 -89
- package/package.json +5 -3
- package/templates/pre-commit +5 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Expo2Dev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -8,7 +8,8 @@ checks your CI will run — and see exactly what would fail — before you push.
|
|
|
8
8
|
**What you get**
|
|
9
9
|
|
|
10
10
|
- A shared Biome preset (`base`, `strict`, `next`) with auto-detection.
|
|
11
|
-
- A pre-commit hook that formats and lints staged
|
|
11
|
+
- A pre-commit hook that formats and lints exactly what you staged, and never
|
|
12
|
+
stages anything you didn't.
|
|
12
13
|
- Conventional Commits, enforced and guided: a step-by-step prompt, a
|
|
13
14
|
commit-message check, a pre-push check and a CI check.
|
|
14
15
|
- A GitHub Actions workflow running `biome ci`.
|
|
@@ -21,6 +22,7 @@ checks your CI will run — and see exactly what would fail — before you push.
|
|
|
21
22
|
- [Commands at a glance](#commands-at-a-glance)
|
|
22
23
|
- [Requirements](#requirements)
|
|
23
24
|
- [`init`](#init--one-time-project-setup)
|
|
25
|
+
- [The pre-commit hook](#the-pre-commit-hook)
|
|
24
26
|
- [`check`, `check:fix`, `ci`](#check-checkfix-ci--run-biome)
|
|
25
27
|
- [Commit workflow](#commit-workflow)
|
|
26
28
|
- [`commit`](#commit--guided-conventional-commit)
|
|
@@ -31,6 +33,7 @@ checks your CI will run — and see exactly what would fail — before you push.
|
|
|
31
33
|
- [Dashboard (`ui`)](#dashboard-ui)
|
|
32
34
|
- [Presets](#presets)
|
|
33
35
|
- [Manual setup (without the CLI)](#manual-setup-without-the-cli)
|
|
36
|
+
- [Limitations](#limitations)
|
|
34
37
|
- [Troubleshooting](#troubleshooting)
|
|
35
38
|
- [Reference](#reference)
|
|
36
39
|
- [Developing lintlane](#developing-lintlane)
|
|
@@ -39,22 +42,24 @@ checks your CI will run — and see exactly what would fail — before you push.
|
|
|
39
42
|
|
|
40
43
|
```sh
|
|
41
44
|
# 1. In your React project (a git repository with a package.json):
|
|
42
|
-
|
|
45
|
+
npx lintlane init
|
|
43
46
|
|
|
44
47
|
# 2. Fix what Biome can fix, see what's left:
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
npx lintlane check:fix
|
|
49
|
+
npx lintlane check
|
|
47
50
|
|
|
48
51
|
# 3. Open the dashboard to review issues and run your CI checks locally:
|
|
49
|
-
|
|
52
|
+
npx lintlane ui
|
|
50
53
|
```
|
|
51
54
|
|
|
52
55
|
From then on, `git commit` is guided and checked, and every push is checked
|
|
53
56
|
before it leaves your machine.
|
|
54
57
|
|
|
55
|
-
>
|
|
56
|
-
>
|
|
57
|
-
>
|
|
58
|
+
> Use your package manager's runner for that first command: `npx lintlane init`,
|
|
59
|
+
> `pnpm dlx lintlane init`, `yarn dlx lintlane init` or `bunx lintlane init`. It
|
|
60
|
+
> runs on Node.js, so you don't need Bun. After `init`, lintlane is installed in
|
|
61
|
+
> your project and `npx lintlane …` (or `pnpm exec lintlane …`, `yarn lintlane …`,
|
|
62
|
+
> `bunx lintlane …`) runs your local copy without touching the network.
|
|
58
63
|
|
|
59
64
|
## Commands at a glance
|
|
60
65
|
|
|
@@ -70,41 +75,41 @@ before it leaves your machine.
|
|
|
70
75
|
| `lintlane -h` / `commit -h` / `check-commit -h` | Show help. |
|
|
71
76
|
|
|
72
77
|
Every command except `init` runs from the project root. Examples below use
|
|
73
|
-
`
|
|
74
|
-
`
|
|
78
|
+
`npx lintlane …`; once lintlane is installed, `pnpm exec lintlane …`,
|
|
79
|
+
`yarn lintlane …`, `bunx lintlane …` and `node_modules/.bin/lintlane …` work too.
|
|
75
80
|
|
|
76
81
|
## Requirements
|
|
77
82
|
|
|
78
|
-
- **
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
Bun
|
|
82
|
-
- **
|
|
83
|
-
|
|
83
|
+
- **Node.js 22 or newer.** The CLI and the git hooks are plain Node.js scripts
|
|
84
|
+
with no runtime dependencies. **Bun is not required**, and neither is any
|
|
85
|
+
particular package manager: `npx`, `pnpm dlx`, `yarn dlx` and `bunx` all work
|
|
86
|
+
(Bun users can also run lintlane under the Bun runtime).
|
|
87
|
+
- **Your project can use any package manager.** `init` detects npm, pnpm, Yarn
|
|
88
|
+
or Bun and installs with that one (see [Package manager detection](#package-manager-detection)).
|
|
84
89
|
- **Biome 2.2 up to (not including) 3.** It's a peer dependency; `init` installs it.
|
|
85
|
-
- **Git**, for the commit workflow.
|
|
90
|
+
- **Git**, for the hooks and the commit workflow.
|
|
86
91
|
- **macOS or Linux** for the guided prompt on a plain `git commit` (it reads the
|
|
87
92
|
terminal through `/dev/tty`). Elsewhere that prompt is skipped; messages are
|
|
88
|
-
still validated, and `lintlane commit` still works.
|
|
93
|
+
still validated, and `lintlane commit` still works. Windows isn't tested yet.
|
|
89
94
|
|
|
90
95
|
## `init` — one-time project setup
|
|
91
96
|
|
|
92
97
|
```sh
|
|
93
|
-
|
|
98
|
+
npx lintlane init
|
|
94
99
|
```
|
|
95
100
|
|
|
96
101
|
`init` installs `@biomejs/biome`, `lintlane` and (unless `--no-hooks`)
|
|
97
102
|
`husky`, then writes:
|
|
98
103
|
|
|
99
|
-
| File / change | Purpose
|
|
100
|
-
| ----------------------------- |
|
|
101
|
-
| `biome.json` | Extends the preset. If one exists, it only tells you what to add.
|
|
102
|
-
| `package.json` scripts | `check`, `check:fix`, and `prepare` (runs husky).
|
|
103
|
-
| `.husky/pre-commit` | Biome on staged files, auto-fixing what it can.
|
|
104
|
-
| `.husky/commit-msg` | Rejects messages that aren't Conventional Commits.
|
|
105
|
-
| `.husky/prepare-commit-msg` | Guided prompt when you run a plain `git commit`.
|
|
106
|
-
| `.husky/pre-push` | Checks every commit about to be pushed.
|
|
107
|
-
| `.github/workflows/biome.yml` | `biome ci`, plus a commit-message check on pull requests.
|
|
104
|
+
| File / change | Purpose |
|
|
105
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
106
|
+
| `biome.json` | Extends the preset. If one exists, it only tells you what to add. |
|
|
107
|
+
| `package.json` scripts | `check`, `check:fix`, and `prepare` (runs husky). |
|
|
108
|
+
| `.husky/pre-commit` | Biome on the staged files, auto-fixing what it can (safely: see [the pre-commit hook](#the-pre-commit-hook)). |
|
|
109
|
+
| `.husky/commit-msg` | Rejects messages that aren't Conventional Commits. |
|
|
110
|
+
| `.husky/prepare-commit-msg` | Guided prompt when you run a plain `git commit`. |
|
|
111
|
+
| `.husky/pre-push` | Checks every commit about to be pushed. |
|
|
112
|
+
| `.github/workflows/biome.yml` | `biome ci`, plus a commit-message check on pull requests. |
|
|
108
113
|
|
|
109
114
|
### Flags
|
|
110
115
|
|
|
@@ -118,12 +123,12 @@ bunx lintlane init
|
|
|
118
123
|
| `-h`, `--help` | Show usage. |
|
|
119
124
|
|
|
120
125
|
```sh
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
npx lintlane init # everything, preset auto-detected
|
|
127
|
+
npx lintlane init --preset strict # force a preset
|
|
128
|
+
npx lintlane init --no-commit-lint # lint hook only, no commit rules
|
|
129
|
+
npx lintlane init --no-hooks --no-ci # just biome.json and scripts
|
|
130
|
+
npx lintlane init --skip-install # you install packages yourself
|
|
131
|
+
npx lintlane init --preset next --no-ci
|
|
127
132
|
```
|
|
128
133
|
|
|
129
134
|
### Preset auto-detection
|
|
@@ -145,10 +150,25 @@ changes which preset is used. `init` says what it detected either way.
|
|
|
145
150
|
|
|
146
151
|
### Package manager detection
|
|
147
152
|
|
|
148
|
-
`init`
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
153
|
+
`init` picks the package manager in this order, and tells you which signal it used:
|
|
154
|
+
|
|
155
|
+
1. the `packageManager` field in `package.json` (for example `pnpm@9.1.0`);
|
|
156
|
+
2. a lockfile: `bun.lock` / `bun.lockb`, `package-lock.json` / `npm-shrinkwrap.json`,
|
|
157
|
+
`pnpm-lock.yaml` or `yarn.lock`;
|
|
158
|
+
3. the tool you launched lintlane with (`npx`, `pnpm dlx`, `yarn dlx`, `bunx`);
|
|
159
|
+
4. otherwise **npm**, which ships with Node.js.
|
|
160
|
+
|
|
161
|
+
It then uses that package manager's install command (exact dev dependencies) and
|
|
162
|
+
writes matching setup steps into the CI workflow. If the package manager isn't
|
|
163
|
+
installed, `init` stops with a clear message before writing anything; you can
|
|
164
|
+
re-run with `--skip-install` and install the packages yourself.
|
|
165
|
+
|
|
166
|
+
| Package manager | Install command `init` runs |
|
|
167
|
+
| --------------- | ------------------------------------------------ |
|
|
168
|
+
| npm | `npm install --save-dev --save-exact <packages>` |
|
|
169
|
+
| pnpm | `pnpm add --save-dev --save-exact <packages>` |
|
|
170
|
+
| Yarn | `yarn add --dev --exact <packages>` |
|
|
171
|
+
| Bun | `bun add --dev --exact <packages>` |
|
|
152
172
|
|
|
153
173
|
### Safe to re-run
|
|
154
174
|
|
|
@@ -157,19 +177,25 @@ workflow file; it prints a `!` warning for whatever already exists and writes
|
|
|
157
177
|
only what's missing. That makes it the way to **upgrade**: update the package,
|
|
158
178
|
then run `init` again to pick up hooks added in newer versions.
|
|
159
179
|
|
|
180
|
+
One exception, for safety: an untouched copy of the **old pre-commit hook**
|
|
181
|
+
(the one that ended with `git update-index --again`, written by lintlane up to
|
|
182
|
+
2.5.1) is replaced with the current one, because the old hook could stage changes
|
|
183
|
+
you hadn't staged. If you edited that hook yourself, `init` leaves it alone and
|
|
184
|
+
warns you to replace it.
|
|
185
|
+
|
|
160
186
|
## `check`, `check:fix`, `ci` — run Biome
|
|
161
187
|
|
|
162
188
|
These wrap the Biome binary installed in your project, so you never need
|
|
163
189
|
Biome's own flags:
|
|
164
190
|
|
|
165
191
|
```sh
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
192
|
+
npx lintlane check # biome check . (read-only)
|
|
193
|
+
npx lintlane check:fix # biome check --write . (applies safe fixes)
|
|
194
|
+
npx lintlane ci # biome ci --reporter=github . (CI-formatted output)
|
|
169
195
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
196
|
+
npx lintlane check src/ # limit to paths
|
|
197
|
+
npx lintlane check:fix src/components/Button.tsx
|
|
198
|
+
npx lintlane ci src/ tests/
|
|
173
199
|
```
|
|
174
200
|
|
|
175
201
|
The exit code is Biome's, so they work in scripts and CI. If Biome isn't
|
|
@@ -177,13 +203,53 @@ installed yet they say so and point you to `init`.
|
|
|
177
203
|
|
|
178
204
|
`init` also adds plain `check` and `check:fix` scripts to `package.json` that
|
|
179
205
|
call `biome` directly, so `npm run check` (or `pnpm`/`yarn`/`bun run check`)
|
|
180
|
-
works without
|
|
206
|
+
works without lintlane's own command:
|
|
181
207
|
|
|
182
208
|
```sh
|
|
183
209
|
npm run check
|
|
184
210
|
npm run check:fix
|
|
185
211
|
```
|
|
186
212
|
|
|
213
|
+
## The pre-commit hook
|
|
214
|
+
|
|
215
|
+
`.husky/pre-commit` runs `node_modules/lintlane/bin/pre-commit.mjs`, which runs
|
|
216
|
+
`biome check --write` on the files you staged and puts the result back into your
|
|
217
|
+
commit. It is built so that **it can never stage, discard or rewrite anything you
|
|
218
|
+
didn't stage**:
|
|
219
|
+
|
|
220
|
+
- Only the staged files are touched. Unstaged edits to other files and untracked
|
|
221
|
+
files are never read, formatted or staged.
|
|
222
|
+
- A **partially staged** file (you staged some hunks and kept editing) is handled
|
|
223
|
+
correctly: Biome sees exactly the staged content, the fix is written to the
|
|
224
|
+
index, and Biome's changes are merged back into your working copy with a
|
|
225
|
+
three-way merge, so your unstaged edits survive byte for byte. If your unstaged
|
|
226
|
+
edit overlaps a formatting change, your working copy is left exactly as you
|
|
227
|
+
wrote it (the staged content is still formatted), and you get a notice.
|
|
228
|
+
- Nothing is ever staged with `git add`, `git add -A` or `git update-index --again`.
|
|
229
|
+
Fixed content goes into the index entry of each staged path only.
|
|
230
|
+
- If Biome reports an error it can't fix, the commit is blocked **and every file is
|
|
231
|
+
put back exactly as it was**: the index, the working tree and HEAD are
|
|
232
|
+
unchanged. It is all-or-nothing, so a fixable file isn't modified when another
|
|
233
|
+
staged file fails.
|
|
234
|
+
- Deleted and renamed files, file names with spaces, non-ASCII characters or a
|
|
235
|
+
leading dash, executable bits, symlinks, files Biome ignores and file types it
|
|
236
|
+
doesn't know are all handled.
|
|
237
|
+
- Ctrl+C or a termination signal during the run restores your working files
|
|
238
|
+
before exiting. Your working copy of a partially staged file is saved under
|
|
239
|
+
`.git/lintlane-backup` while the hook runs.
|
|
240
|
+
|
|
241
|
+
If the hook is killed in a way that can't be caught (`kill -9`, a power cut), the
|
|
242
|
+
next commit stops with a message instead of continuing, and you recover with:
|
|
243
|
+
|
|
244
|
+
```sh
|
|
245
|
+
node node_modules/lintlane/bin/pre-commit.mjs --restore
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Why not `lint-staged`? It solves the same problem, but it adds a dependency to
|
|
249
|
+
every project, needs its own configuration, and hides your unstaged changes with
|
|
250
|
+
`git stash` while tasks run. This hook has no dependencies, uses the same Biome
|
|
251
|
+
command and ignore rules as `lintlane check`, and never stashes.
|
|
252
|
+
|
|
187
253
|
## Commit workflow
|
|
188
254
|
|
|
189
255
|
`init` sets up [Conventional Commits](https://www.conventionalcommits.org)
|
|
@@ -217,7 +283,7 @@ BREAKING CHANGE: what breaks and how to migrate
|
|
|
217
283
|
|
|
218
284
|
```sh
|
|
219
285
|
git add <files>
|
|
220
|
-
|
|
286
|
+
npx lintlane commit # alias: npx lintlane c
|
|
221
287
|
```
|
|
222
288
|
|
|
223
289
|
Asks seven questions — **type, scope, subject, body, breaking change, footer,
|
|
@@ -237,19 +303,19 @@ period, an over-long header) are explained and asked again.
|
|
|
237
303
|
| `-- <git args>` | Everything after `--` is passed to `git commit`. |
|
|
238
304
|
|
|
239
305
|
```sh
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
306
|
+
npx lintlane commit # ask, then commit the staged changes
|
|
307
|
+
npx lintlane commit -- -a # stage all tracked changes, then commit
|
|
308
|
+
npx lintlane commit -- -a -S # …and sign the commit
|
|
309
|
+
npx lintlane commit -- -s # add a Signed-off-by line
|
|
310
|
+
npx lintlane commit -- -n # skip git hooks
|
|
311
|
+
npx lintlane commit --dry-run # just print the message
|
|
312
|
+
npx lintlane commit --dry-run --write-message-to-file msg.txt
|
|
313
|
+
npx lintlane commit -l 72 # stricter header limit for this commit
|
|
248
314
|
```
|
|
249
315
|
|
|
250
316
|
**Retrying after a failed commit.** If a hook (for example Biome in pre-commit)
|
|
251
317
|
rejects the commit after you've answered the questions, the message is kept.
|
|
252
|
-
Fix the problem, stage the fix, then run `
|
|
318
|
+
Fix the problem, stage the fix, then run `npx lintlane commit --retry` — no
|
|
253
319
|
re-typing. The saved message is cleared once a commit succeeds. Set
|
|
254
320
|
`retryAfterFailure` (see [Settings](#settings)) to reuse it automatically.
|
|
255
321
|
|
|
@@ -258,11 +324,11 @@ re-typing. The saved message is cleared once a commit succeeds. Set
|
|
|
258
324
|
Give it exactly one thing to check:
|
|
259
325
|
|
|
260
326
|
```sh
|
|
261
|
-
|
|
262
|
-
echo "feat: add login" |
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
327
|
+
npx lintlane check-commit --message "feat: add login" # a message
|
|
328
|
+
echo "feat: add login" | npx lintlane check-commit # …or from stdin
|
|
329
|
+
npx lintlane check-commit --commit-msg-file .git/COMMIT_EDITMSG
|
|
330
|
+
npx lintlane check-commit --rev-range origin/main..HEAD # every commit in a range
|
|
331
|
+
npx lintlane check-commit -d # shorthand for <default branch>..HEAD
|
|
266
332
|
```
|
|
267
333
|
|
|
268
334
|
| Flag | Effect |
|
|
@@ -370,9 +436,9 @@ it to one you already have:
|
|
|
370
436
|
would fail before you push:
|
|
371
437
|
|
|
372
438
|
```sh
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
439
|
+
npx lintlane ui # opens http://127.0.0.1:4321
|
|
440
|
+
npx lintlane ui --port 5000 # use another port
|
|
441
|
+
npx lintlane ui --no-open # print the URL without opening a browser
|
|
376
442
|
```
|
|
377
443
|
|
|
378
444
|
| Flag | Effect |
|
|
@@ -459,8 +525,8 @@ add your own ignores:
|
|
|
459
525
|
To migrate an existing config into Biome first:
|
|
460
526
|
|
|
461
527
|
```sh
|
|
462
|
-
|
|
463
|
-
|
|
528
|
+
npx biome migrate eslint --write
|
|
529
|
+
npx biome migrate prettier --write
|
|
464
530
|
```
|
|
465
531
|
|
|
466
532
|
## Manual setup (without the CLI)
|
|
@@ -491,8 +557,8 @@ Add scripts:
|
|
|
491
557
|
**Git hooks**
|
|
492
558
|
|
|
493
559
|
```sh
|
|
494
|
-
bun add -d husky
|
|
495
|
-
|
|
560
|
+
npm install --save-dev husky # or: pnpm add -D husky / yarn add -D husky / bun add -d husky
|
|
561
|
+
npx husky init
|
|
496
562
|
```
|
|
497
563
|
|
|
498
564
|
Put these in `.husky/`:
|
|
@@ -500,10 +566,16 @@ Put these in `.husky/`:
|
|
|
500
566
|
`.husky/pre-commit`
|
|
501
567
|
|
|
502
568
|
```sh
|
|
503
|
-
|
|
504
|
-
|
|
569
|
+
if [ -f node_modules/lintlane/bin/pre-commit.mjs ]; then
|
|
570
|
+
node node_modules/lintlane/bin/pre-commit.mjs
|
|
571
|
+
else
|
|
572
|
+
echo "lintlane: node_modules/lintlane not found; skipping staged-file checks. Run your package manager's install." >&2
|
|
573
|
+
fi
|
|
505
574
|
```
|
|
506
575
|
|
|
576
|
+
Don't write your own `biome check --write --staged` followed by `git add` or
|
|
577
|
+
`git update-index --again`: that stages unstaged edits in partially staged files.
|
|
578
|
+
|
|
507
579
|
`.husky/commit-msg`
|
|
508
580
|
|
|
509
581
|
```sh
|
|
@@ -527,12 +599,30 @@ node node_modules/lintlane/bin/pre-push-check.mjs "$1" "$2"
|
|
|
527
599
|
|
|
528
600
|
Commits with errors Biome can't fix are blocked until you resolve them.
|
|
529
601
|
|
|
602
|
+
## Limitations
|
|
603
|
+
|
|
604
|
+
- **Windows is untested.** Subprocesses are started through `.cmd` shims there, but
|
|
605
|
+
none of it has been run on Windows. The guided prompt on `git commit` needs
|
|
606
|
+
`/dev/tty` and is skipped on Windows (`lintlane commit` works).
|
|
607
|
+
- **Yarn:** command generation is covered by tests, but a real Yarn install isn't
|
|
608
|
+
part of the automated end-to-end run here, so Yarn is the least exercised.
|
|
609
|
+
- **Line-ending and content filters.** The pre-commit hook compares your working
|
|
610
|
+
files with the raw staged content. If `core.autocrlf`, `.gitattributes` eol rules
|
|
611
|
+
or a filter makes them differ byte for byte, the file is treated as partially
|
|
612
|
+
staged: it's formatted in the index and your working copy is left as it was.
|
|
613
|
+
- **Merges.** During a merge commit, the hook also checks the files the merge staged.
|
|
614
|
+
- **Monorepos.** The hook runs from the repository root and uses the repository's
|
|
615
|
+
`node_modules`; a `package.json` in a subfolder isn't supported yet.
|
|
616
|
+
- **Concurrent edits.** If you save a file in your editor _while_ the hook is
|
|
617
|
+
running, that file is left as saved and the hook says so.
|
|
618
|
+
|
|
530
619
|
## Troubleshooting
|
|
531
620
|
|
|
532
|
-
**`
|
|
533
|
-
Outside a project that has it installed, `
|
|
534
|
-
|
|
535
|
-
|
|
621
|
+
**`npx lintlane …` downloads the package each time, or says "command not found".**
|
|
622
|
+
Outside a project that has it installed, `npx` (or `pnpm dlx`, `yarn dlx`, `bunx`)
|
|
623
|
+
fetches `lintlane` from npm.
|
|
624
|
+
Run `npx lintlane init` in the project first (or install `lintlane` as a dev
|
|
625
|
+
dependency), after which `npx lintlane …` uses the local copy.
|
|
536
626
|
|
|
537
627
|
**Hooks don't run.** Run your package manager's install (the `prepare` script
|
|
538
628
|
runs husky), or run `node_modules/.bin/husky` once. Check
|
|
@@ -541,14 +631,29 @@ runs husky), or run `node_modules/.bin/husky` once. Check
|
|
|
541
631
|
**The guided prompt doesn't appear on `git commit`.** It's skipped when `CI` or
|
|
542
632
|
`LINTLANE_NO_PROMPT` is set, when you pass `-m`/`-F` or amend, when there's no
|
|
543
633
|
terminal (GUI clients, some editors) and on systems without `/dev/tty`. Run
|
|
544
|
-
`
|
|
634
|
+
`npx lintlane commit` for the same steps. The message is validated regardless.
|
|
545
635
|
|
|
546
636
|
**A commit was rejected and I lost my message.** Use
|
|
547
|
-
`
|
|
637
|
+
`npx lintlane commit --retry` if you committed through `lintlane commit`.
|
|
548
638
|
|
|
549
639
|
**The pre-commit hook blocks my commit.** Biome found an error it can't fix.
|
|
550
|
-
Run `
|
|
551
|
-
commit again.
|
|
640
|
+
Run `npx lintlane check` to see it, or open `npx lintlane ui`. Fix it and
|
|
641
|
+
commit again. Your files were left exactly as they were.
|
|
642
|
+
|
|
643
|
+
**"An earlier lintlane run was interrupted".** The hook was killed before it could
|
|
644
|
+
put your working files back. Run
|
|
645
|
+
`node node_modules/lintlane/bin/pre-commit.mjs --restore`, then commit again.
|
|
646
|
+
|
|
647
|
+
**My unstaged edit was reformatted / not reformatted.** The hook only formats what
|
|
648
|
+
you staged. When it formats a partially staged file it merges those changes into
|
|
649
|
+
your working copy without touching your unstaged edit. If your edit overlaps the
|
|
650
|
+
formatting change, your file is left exactly as you wrote it. Stage the file
|
|
651
|
+
fully, or run `npx lintlane check:fix`, to format it.
|
|
652
|
+
|
|
653
|
+
**`npx lintlane init` fails with "pnpm was not found" (or yarn, bun).** The project
|
|
654
|
+
says it uses that package manager (a lockfile or `packageManager`) but it isn't
|
|
655
|
+
installed. Install it, or run `npx lintlane init --skip-install` and install
|
|
656
|
+
`@biomejs/biome`, `lintlane` and `husky` yourself.
|
|
552
657
|
|
|
553
658
|
**Push blocked: "commit message(s) don't follow Conventional Commits".** Reword
|
|
554
659
|
the listed commits with `git rebase -i` (or `git commit --amend` for the latest),
|
|
@@ -568,11 +673,12 @@ scan them.
|
|
|
568
673
|
|
|
569
674
|
**Environment variables**
|
|
570
675
|
|
|
571
|
-
| Variable
|
|
572
|
-
|
|
|
573
|
-
| `LINTLANE_NO_PROMPT`
|
|
574
|
-
| `CI`
|
|
575
|
-
| `NO_COLOR`
|
|
676
|
+
| Variable | Effect |
|
|
677
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
678
|
+
| `LINTLANE_NO_PROMPT` | Set to any value to skip the guided prompt on `git commit`. |
|
|
679
|
+
| `CI` | When set, the guided prompt is skipped. The CI tab sets it for the steps it runs. |
|
|
680
|
+
| `NO_COLOR` | Turns off colors in the prompt. |
|
|
681
|
+
| `LINTLANE_INSTALL_SPEC` | What `init` installs instead of `lintlane@<version>` (a tarball or folder), for testing a local build. |
|
|
576
682
|
|
|
577
683
|
**Exit codes**
|
|
578
684
|
|
|
@@ -585,30 +691,50 @@ scan them.
|
|
|
585
691
|
|
|
586
692
|
**Files lintlane may create or use**
|
|
587
693
|
|
|
588
|
-
| Path | What
|
|
589
|
-
| ------------------------------------------------------------------- |
|
|
590
|
-
| `biome.json` | Biome config extending a preset.
|
|
591
|
-
| `.husky/pre-commit`, `commit-msg`, `prepare-commit-msg`, `pre-push` | Git hooks.
|
|
592
|
-
| `.github/workflows/biome.yml` | CI workflow.
|
|
593
|
-
| `.git/lintlane-commit-msg` | Your last message, kept after a failed commit.
|
|
694
|
+
| Path | What |
|
|
695
|
+
| ------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
696
|
+
| `biome.json` | Biome config extending a preset. |
|
|
697
|
+
| `.husky/pre-commit`, `commit-msg`, `prepare-commit-msg`, `pre-push` | Git hooks. |
|
|
698
|
+
| `.github/workflows/biome.yml` | CI workflow. |
|
|
699
|
+
| `.git/lintlane-commit-msg` | Your last message, kept after a failed commit. |
|
|
700
|
+
| `.git/lintlane-backup/` | Your working copies, only while the pre-commit hook runs (or after it was killed). |
|
|
594
701
|
|
|
595
702
|
## Developing lintlane
|
|
596
703
|
|
|
597
|
-
|
|
704
|
+
Requires Node.js 22 or newer. There are no runtime dependencies; the dev
|
|
705
|
+
dependency is Biome.
|
|
706
|
+
|
|
707
|
+
```sh
|
|
708
|
+
npm test # unit + integration tests (about 15 seconds, no network)
|
|
709
|
+
npm run test:e2e # real npm / pnpm / bun installs against the registry (needs network)
|
|
710
|
+
npm run check # lint and format this repository
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
The tests use Node's built-in test runner and real temporary git repositories:
|
|
714
|
+
|
|
715
|
+
| File | What it covers |
|
|
716
|
+
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
717
|
+
| `test/pre-commit.test.mjs` | The pre-commit hook: partial staging, failures, odd file names, interruption. |
|
|
718
|
+
| `test/package-managers.test.mjs` | Package-manager detection and install/workflow command generation (pure). |
|
|
719
|
+
| `test/cli.test.mjs` | Running on Node without Bun, packaging, `init` for new and existing projects, generated hooks. Package managers are **mocked** here. |
|
|
720
|
+
| `test/ui.test.mjs` | The dashboard: startup, token auth, every API route, Stop killing a run. |
|
|
721
|
+
| `test/e2e.test.mjs` | **Real** package managers, the packed tarball and real husky. Skipped unless `LINTLANE_E2E=1`; a package manager that isn't installed is reported as skipped. |
|
|
722
|
+
|
|
723
|
+
To try a local build in a throwaway app before publishing:
|
|
598
724
|
|
|
599
725
|
```sh
|
|
600
726
|
# In the lintlane repo:
|
|
601
|
-
npm pack --pack-destination /tmp/lintlane-pack
|
|
727
|
+
npm pack --pack-destination /tmp/lintlane-pack # builds lintlane-<version>.tgz
|
|
602
728
|
|
|
603
|
-
# In a throwaway app (a git repo with a package.json):
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
node_modules/.bin/husky
|
|
729
|
+
# In a throwaway app (a git repo with a package.json), from its directory:
|
|
730
|
+
LINTLANE_INSTALL_SPEC=/tmp/lintlane-pack/lintlane-<version>.tgz \
|
|
731
|
+
npx --package=/tmp/lintlane-pack/lintlane-<version>.tgz lintlane init
|
|
607
732
|
```
|
|
608
733
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
734
|
+
`init` then installs your tarball, Biome and husky with the app's package manager
|
|
735
|
+
and does everything a real run does. `npm pack --dry-run` lists what would be
|
|
736
|
+
published. If you rebuild without changing the version, a package manager may
|
|
737
|
+
reuse its cached tarball: bump the version, or clear the cache and reinstall.
|
|
612
738
|
|
|
613
739
|
## License
|
|
614
740
|
|