lintcn 0.5.0 → 0.7.0
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/CHANGELOG.md +108 -0
- package/README.md +123 -23
- package/dist/cache.d.ts +1 -1
- package/dist/cache.js +1 -1
- package/dist/cli.js +19 -5
- package/dist/codegen.js +20 -3
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +223 -77
- package/dist/commands/clean.d.ts +2 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +44 -0
- package/dist/commands/lint.d.ts +2 -1
- package/dist/commands/lint.d.ts.map +1 -1
- package/dist/commands/lint.js +93 -7
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +5 -2
- package/dist/commands/remove.d.ts.map +1 -1
- package/dist/commands/remove.js +6 -14
- package/dist/discover.d.ts +13 -3
- package/dist/discover.d.ts.map +1 -1
- package/dist/discover.js +49 -23
- package/dist/hash.d.ts +7 -1
- package/dist/hash.d.ts.map +1 -1
- package/dist/hash.js +28 -25
- package/package.json +3 -2
- package/src/cache.ts +1 -1
- package/src/cli.ts +20 -5
- package/src/codegen.ts +22 -3
- package/src/commands/add.ts +270 -73
- package/src/commands/clean.ts +48 -0
- package/src/commands/lint.ts +100 -7
- package/src/commands/list.ts +5 -2
- package/src/commands/remove.ts +6 -16
- package/src/discover.ts +66 -31
- package/src/hash.ts +33 -27
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,111 @@
|
|
|
1
|
+
## 0.7.0
|
|
2
|
+
|
|
3
|
+
1. **`lintcn lint --fix`** — automatically apply fixes in-place. Collects diagnostics per file, applies fixes via the Go runner, and only reports what couldn't be auto-fixed:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
lintcn lint --fix
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
2. **Warning severity system** — rules can now declare `// lintcn:severity warn`. Warnings don't fail CI (exit 0) and are filtered to git-changed files by default so they don't flood large codebases:
|
|
10
|
+
|
|
11
|
+
```go
|
|
12
|
+
// lintcn:severity warn
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Two new flags:
|
|
16
|
+
- `--all-warnings` — show warnings for all files, not just changed ones
|
|
17
|
+
- `lintcn list` now shows a `(warn)` suffix on warning-severity rules
|
|
18
|
+
|
|
19
|
+
3. **New rule: `no-type-assertion` (warn)** — flags every `as X` / `<X>expr` and includes the actual expression type so agents know what they're working with:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
warning: Type assertion to `User ({ name: string; age: number })` from `unknown`
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
User-defined types show their structural form in parentheses. Standard library types (Array, Map, Promise, etc.) are not expanded. Assertion chains (`x as unknown as Foo`) walk back to the original source type. Casting from `any` is silently allowed (standard untyped-API pattern).
|
|
26
|
+
|
|
27
|
+
4. **New rule: `no-in-operator` (warn)** — warns on every `in` expression and shows the expanded type of the right-hand operand. When the right side is a union and the property exists in some members but not others, it names which members have it and suggests using a discriminant property instead:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
warning: Avoid the `in` operator on `Cat | Dog`. Property `meow` exists in Cat but not Dog.
|
|
31
|
+
Consider using a discriminant property (e.g. `kind`) instead of `in`.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
5. **New rule: `no-redundant-in-check` (error)** — flags `"y" in x` when the type already has `y` as a required non-optional property in all union members. The check can never be false — it's dead code:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
interface User { name: string; age: number }
|
|
38
|
+
if ('name' in user) { ... } // error: redundant — User always has 'name'
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
6. **New built-in rules**: `jsx-no-leaked-render`, `no-unhandled-error`, `no-useless-coalescing` — available via `lintcn add` or by pointing at the `.lintcn/` folder URL.
|
|
42
|
+
|
|
43
|
+
7. **`lintcn add` with whole repo URL** — download all rules from a repo's `.lintcn/` folder in one shot. Merge semantics: remote rule folders overwrite local ones; local-only rules are preserved:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# bare repo URL — fetches all rules from .lintcn/ at repo root
|
|
47
|
+
lintcn add https://github.com/remorses/lintcn
|
|
48
|
+
|
|
49
|
+
# tree URL pointing at a .lintcn collection
|
|
50
|
+
lintcn add https://github.com/remorses/lintcn/tree/main/.lintcn
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
8. **Fixed `await-thenable` false positive on overloaded functions** — when a function has multiple call signatures (overloads or intersection-of-callable-types), the rule now checks if any overload returns a thenable before reporting. Fixes false positives like `await extract({...})` from the `tar` package.
|
|
54
|
+
|
|
55
|
+
9. **Brighter error underline** — error highlights changed from ANSI 256-color 160 (muted red) to 196 (pure bright red). Run `lintcn clean` to clear the old cached binary.
|
|
56
|
+
|
|
57
|
+
## 0.6.0
|
|
58
|
+
|
|
59
|
+
1. **Rules now live in subfolders** — each rule is its own Go package under `.lintcn/{rule_name}/`, replacing the old flat `.lintcn/*.go` layout. This eliminates the need to rename `options.go` and `schema.json` companions — they stay in the subfolder with their original names, and the Go package name matches the folder. `lintcn add` now fetches the entire rule folder automatically.
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
.lintcn/
|
|
63
|
+
no_floating_promises/
|
|
64
|
+
no_floating_promises.go
|
|
65
|
+
no_floating_promises_test.go
|
|
66
|
+
options.go ← original name, no renaming
|
|
67
|
+
schema.json
|
|
68
|
+
my_custom_rule/
|
|
69
|
+
my_custom_rule.go
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
2. **`lintcn add` fetches whole folders** — both folder URLs (`/tree/`) and file URLs (`/blob/`) now fetch every `.go` and `.json` file in the rule's directory. Passing a file URL auto-detects the parent folder:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# folder URL
|
|
76
|
+
lintcn add https://github.com/oxc-project/tsgolint/tree/main/internal/rules/no_floating_promises
|
|
77
|
+
|
|
78
|
+
# file URL — auto-fetches the whole folder
|
|
79
|
+
lintcn add https://github.com/oxc-project/tsgolint/blob/main/internal/rules/await_thenable/await_thenable.go
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
3. **Error for flat `.go` files in `.lintcn/`** — if leftover flat files from older versions are detected, lintcn now prints a clear migration error with instructions instead of silently ignoring them.
|
|
83
|
+
|
|
84
|
+
4. **Reproducible builds with `-trimpath`** — the Go binary is now built with `-trimpath`, stripping absolute paths from the output. Binaries are identical across machines for the same rule content + tsgolint version + platform.
|
|
85
|
+
|
|
86
|
+
5. **Faster cache hits** — Go version removed from the content hash. The compiled binary is a standalone executable with no Go runtime dependency, so the Go version used to build it doesn't affect correctness. Also excludes `_test.go` files from the hash since tests don't affect the binary.
|
|
87
|
+
|
|
88
|
+
6. **Go compilation output is live** — `go build` now inherits stdio, so compilation progress and errors stream directly to the terminal instead of being silently captured.
|
|
89
|
+
|
|
90
|
+
7. **First-build guidance** — on first compile (cold Go cache), lintcn explains the one-time 30s cost and shows which directories to cache in CI:
|
|
91
|
+
```
|
|
92
|
+
Compiling custom tsgolint binary (first build — may take 30s+ to compile dependencies)...
|
|
93
|
+
Subsequent builds will be fast (~1s). In CI, cache ~/.cache/lintcn/ and GOCACHE (run `go env GOCACHE`).
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
8. **GitHub Actions example** — README now includes a copy-paste workflow that caches the compiled binary. Subsequent CI runs take ~12s (vs ~4min cold):
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
- name: Cache lintcn binary + Go build cache
|
|
100
|
+
uses: actions/cache@v4
|
|
101
|
+
with:
|
|
102
|
+
path: |
|
|
103
|
+
~/.cache/lintcn
|
|
104
|
+
~/go/pkg
|
|
105
|
+
key: lintcn-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.lintcn/**/*.go') }}
|
|
106
|
+
restore-keys: lintcn-${{ runner.os }}-${{ runner.arch }}-
|
|
107
|
+
```
|
|
108
|
+
|
|
1
109
|
## 0.5.0
|
|
2
110
|
|
|
3
111
|
1. **Security fix — path traversal in `--tsgolint-version`** — the version flag is now validated against a strict pattern. Previously a value like `../../etc` could escape the cache directory.
|
package/README.md
CHANGED
|
@@ -13,8 +13,11 @@ npm install -D lintcn
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
# Add a rule
|
|
17
|
-
npx lintcn add https://github.com/
|
|
16
|
+
# Add a rule folder from tsgolint
|
|
17
|
+
npx lintcn add https://github.com/oxc-project/tsgolint/tree/main/internal/rules/no_floating_promises
|
|
18
|
+
|
|
19
|
+
# Add by file URL (auto-fetches the whole folder)
|
|
20
|
+
npx lintcn add https://github.com/oxc-project/tsgolint/blob/main/internal/rules/await_thenable/await_thenable.go
|
|
18
21
|
|
|
19
22
|
# Lint your project
|
|
20
23
|
npx lintcn lint
|
|
@@ -26,21 +29,32 @@ npx lintcn lint --tsconfig tsconfig.build.json
|
|
|
26
29
|
npx lintcn list
|
|
27
30
|
|
|
28
31
|
# Remove a rule
|
|
29
|
-
npx lintcn remove no-
|
|
32
|
+
npx lintcn remove no-floating-promises
|
|
33
|
+
|
|
34
|
+
# Clean cached tsgolint source + binaries
|
|
35
|
+
npx lintcn clean
|
|
30
36
|
```
|
|
31
37
|
|
|
38
|
+
Browse all 50+ available built-in rules in the [tsgolint rules directory](https://github.com/oxc-project/tsgolint/tree/main/internal/rules).
|
|
39
|
+
|
|
32
40
|
## How it works
|
|
33
41
|
|
|
34
|
-
|
|
42
|
+
Each rule lives in its own subfolder under `.lintcn/`. You own the source — edit, customize, delete.
|
|
35
43
|
|
|
36
44
|
```
|
|
37
45
|
my-project/
|
|
38
46
|
├── .lintcn/
|
|
39
|
-
│ ├── .gitignore
|
|
40
|
-
│ ├──
|
|
41
|
-
│
|
|
47
|
+
│ ├── .gitignore ← ignores generated Go files
|
|
48
|
+
│ ├── no_floating_promises/
|
|
49
|
+
│ │ ├── no_floating_promises.go ← rule source (committed)
|
|
50
|
+
│ │ ├── no_floating_promises_test.go ← tests (committed)
|
|
51
|
+
│ │ └── options.go ← rule options struct
|
|
52
|
+
│ ├── await_thenable/
|
|
53
|
+
│ │ ├── await_thenable.go
|
|
54
|
+
│ │ └── await_thenable_test.go
|
|
55
|
+
│ └── my_custom_rule/
|
|
56
|
+
│ └── my_custom_rule.go
|
|
42
57
|
├── src/
|
|
43
|
-
│ ├── index.ts
|
|
44
58
|
│ └── ...
|
|
45
59
|
├── tsconfig.json
|
|
46
60
|
└── package.json
|
|
@@ -48,24 +62,32 @@ my-project/
|
|
|
48
62
|
|
|
49
63
|
When you run `npx lintcn lint`, the CLI:
|
|
50
64
|
|
|
51
|
-
1. Scans `.lintcn
|
|
65
|
+
1. Scans `.lintcn/*/` subfolders for rule definitions
|
|
52
66
|
2. Generates a Go workspace with your custom rules
|
|
53
67
|
3. Compiles a custom binary (cached — rebuilds only when rules change)
|
|
54
68
|
4. Runs the binary against your project
|
|
55
69
|
|
|
56
70
|
You can run `lintcn lint` from any subdirectory — it walks up to find `.lintcn/` and lints the cwd project.
|
|
57
71
|
|
|
58
|
-
## Writing
|
|
72
|
+
## Writing custom rules
|
|
59
73
|
|
|
60
|
-
|
|
74
|
+
To help AI agents write and modify rules, install the lintcn skill:
|
|
61
75
|
|
|
62
|
-
|
|
76
|
+
```bash
|
|
77
|
+
npx skills add remorses/lintcn
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This gives your AI agent the full tsgolint rule API reference — AST visitors, type checker, reporting, fixes, and testing patterns.
|
|
81
|
+
|
|
82
|
+
Every rule lives in a subfolder under `.lintcn/` with the package name matching the folder:
|
|
63
83
|
|
|
64
84
|
```go
|
|
85
|
+
// .lintcn/no_unhandled_error/no_unhandled_error.go
|
|
86
|
+
|
|
65
87
|
// lintcn:name no-unhandled-error
|
|
66
88
|
// lintcn:description Disallow discarding Error-typed return values
|
|
67
89
|
|
|
68
|
-
package
|
|
90
|
+
package no_unhandled_error
|
|
69
91
|
|
|
70
92
|
import (
|
|
71
93
|
"github.com/microsoft/typescript-go/shim/ast"
|
|
@@ -118,17 +140,66 @@ This catches code like:
|
|
|
118
140
|
|
|
119
141
|
```typescript
|
|
120
142
|
// error — result discarded, Error not handled
|
|
121
|
-
getUser("id")
|
|
122
|
-
await fetchData("/api") // returns Promise<Error | Data>
|
|
143
|
+
getUser("id"); // returns Error | User
|
|
144
|
+
await fetchData("/api"); // returns Promise<Error | Data>
|
|
123
145
|
|
|
124
146
|
// ok — result is checked
|
|
125
|
-
const user = getUser("id")
|
|
126
|
-
if (user instanceof Error) return user
|
|
147
|
+
const user = getUser("id");
|
|
148
|
+
if (user instanceof Error) return user;
|
|
127
149
|
|
|
128
150
|
// ok — explicitly discarded
|
|
129
|
-
void getUser("id")
|
|
151
|
+
void getUser("id");
|
|
130
152
|
```
|
|
131
153
|
|
|
154
|
+
## Warning severity
|
|
155
|
+
|
|
156
|
+
Rules can be configured as **warnings** instead of errors:
|
|
157
|
+
|
|
158
|
+
- **Don't fail CI** — warnings produce exit code 0
|
|
159
|
+
- **Only shown for git-changed files** — warnings for unchanged files are silently skipped
|
|
160
|
+
|
|
161
|
+
This lets you adopt new rules gradually. In a large codebase, enabling a rule as an error means hundreds of violations at once. As a warning, you only see violations in files you're actively changing — fixing issues in new code without blocking the build.
|
|
162
|
+
|
|
163
|
+
### Configuring a rule as a warning
|
|
164
|
+
|
|
165
|
+
Add `// lintcn:severity warn` to the rule's Go file:
|
|
166
|
+
|
|
167
|
+
```go
|
|
168
|
+
// lintcn:name no-unhandled-error
|
|
169
|
+
// lintcn:severity warn
|
|
170
|
+
// lintcn:description Disallow discarding Error-typed return values
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Rules without `// lintcn:severity` default to `error`.
|
|
174
|
+
|
|
175
|
+
### When warnings are shown
|
|
176
|
+
|
|
177
|
+
By default, `lintcn lint` runs `git diff` to find changed and untracked files. Warnings are only printed for files in that list:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# Warnings only for files in git diff (default)
|
|
181
|
+
npx lintcn lint
|
|
182
|
+
|
|
183
|
+
# Warnings for ALL files, ignoring git diff
|
|
184
|
+
npx lintcn lint --all-warnings
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
| Scenario | Warnings shown? |
|
|
188
|
+
| ---------------------------------- | ----------------- |
|
|
189
|
+
| File is in `git diff` or untracked | Yes |
|
|
190
|
+
| File is committed and unchanged | No |
|
|
191
|
+
| `--all-warnings` flag is passed | Yes, all files |
|
|
192
|
+
| Git is not installed or not a repo | No warnings shown |
|
|
193
|
+
| Clean git tree (no changes) | No warnings shown |
|
|
194
|
+
|
|
195
|
+
### Workflow
|
|
196
|
+
|
|
197
|
+
1. Add a new rule with `lintcn add`
|
|
198
|
+
2. Set it to `// lintcn:severity warn` in the Go source
|
|
199
|
+
3. Run `lintcn lint` — only see warnings in files you're currently editing
|
|
200
|
+
4. Fix warnings as you touch files naturally
|
|
201
|
+
5. Once the codebase is clean, change to `// lintcn:severity error` (or remove the directive) to enforce it
|
|
202
|
+
|
|
132
203
|
## Version pinning
|
|
133
204
|
|
|
134
205
|
**Pin lintcn in your `package.json`** — do not use `^` or `~`:
|
|
@@ -136,7 +207,7 @@ void getUser("id")
|
|
|
136
207
|
```json
|
|
137
208
|
{
|
|
138
209
|
"devDependencies": {
|
|
139
|
-
"lintcn": "0.
|
|
210
|
+
"lintcn": "0.5.0"
|
|
140
211
|
}
|
|
141
212
|
}
|
|
142
213
|
```
|
|
@@ -147,12 +218,41 @@ Each lintcn release bundles a specific tsgolint version. Updating lintcn can cha
|
|
|
147
218
|
2. Run `npx lintcn build` after updating to verify your rules still compile
|
|
148
219
|
3. Fix any compilation errors before committing
|
|
149
220
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
221
|
+
## CI Setup
|
|
222
|
+
|
|
223
|
+
The first `lintcn lint` compiles a custom Go binary (~30s). Subsequent runs use the cached binary (<1s). Cache `~/.cache/lintcn/` and Go's build cache to keep CI fast.
|
|
224
|
+
|
|
225
|
+
```yaml
|
|
226
|
+
# .github/workflows/lint.yml
|
|
227
|
+
name: Lint
|
|
228
|
+
on: [push, pull_request]
|
|
229
|
+
|
|
230
|
+
jobs:
|
|
231
|
+
lint:
|
|
232
|
+
runs-on: ubuntu-latest
|
|
233
|
+
steps:
|
|
234
|
+
- uses: actions/checkout@v4
|
|
235
|
+
|
|
236
|
+
- uses: actions/setup-node@v4
|
|
237
|
+
with:
|
|
238
|
+
node-version: 22
|
|
239
|
+
|
|
240
|
+
- name: Cache lintcn binary + Go build cache
|
|
241
|
+
uses: actions/cache@v4
|
|
242
|
+
with:
|
|
243
|
+
path: |
|
|
244
|
+
~/.cache/lintcn
|
|
245
|
+
~/go/pkg
|
|
246
|
+
key: lintcn-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.lintcn/**/*.go') }}
|
|
247
|
+
restore-keys: |
|
|
248
|
+
lintcn-${{ runner.os }}-${{ runner.arch }}-
|
|
249
|
+
|
|
250
|
+
- run: npm ci
|
|
251
|
+
- run: npx lintcn lint
|
|
154
252
|
```
|
|
155
253
|
|
|
254
|
+
The cache key includes a hash of your rule files — when rules change, the binary is recompiled. The `restore-keys` fallback ensures Go's build cache is still used even when rules change, so recompilation takes ~1s instead of 30s.
|
|
255
|
+
|
|
156
256
|
## Prerequisites
|
|
157
257
|
|
|
158
258
|
- **Node.js** — for the CLI
|
package/dist/cache.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const DEFAULT_TSGOLINT_VERSION = "
|
|
1
|
+
export declare const DEFAULT_TSGOLINT_VERSION = "23190a08a6315eba8ef11818fc1c38d7b01c9e10";
|
|
2
2
|
/** Validate version string to prevent path traversal attacks.
|
|
3
3
|
* Only allows alphanumeric chars, dots, underscores, and hyphens. */
|
|
4
4
|
export declare function validateVersion(version: string): void;
|
package/dist/cache.js
CHANGED
|
@@ -16,7 +16,7 @@ import { execAsync } from "./exec.js";
|
|
|
16
16
|
// Pinned tsgolint fork commit — updated with each lintcn release.
|
|
17
17
|
// Uses remorses/tsgolint fork which adds internal/runner.Run().
|
|
18
18
|
// Only 1 commit on top of upstream — zero modifications to existing files.
|
|
19
|
-
export const DEFAULT_TSGOLINT_VERSION = '
|
|
19
|
+
export const DEFAULT_TSGOLINT_VERSION = '23190a08a6315eba8ef11818fc1c38d7b01c9e10';
|
|
20
20
|
// Pinned typescript-go base commit from microsoft/typescript-go (before patches).
|
|
21
21
|
// Patches from tsgolint/patches/ are applied on top during setup.
|
|
22
22
|
// Must be updated when DEFAULT_TSGOLINT_VERSION changes.
|
package/dist/cli.js
CHANGED
|
@@ -7,16 +7,19 @@ import { addRule } from "./commands/add.js";
|
|
|
7
7
|
import { lint, buildBinary } from "./commands/lint.js";
|
|
8
8
|
import { listRules } from "./commands/list.js";
|
|
9
9
|
import { removeRule } from "./commands/remove.js";
|
|
10
|
+
import { clean } from "./commands/clean.js";
|
|
10
11
|
import { DEFAULT_TSGOLINT_VERSION } from "./cache.js";
|
|
11
12
|
const require = createRequire(import.meta.url);
|
|
12
13
|
const packageJson = require('../package.json');
|
|
13
14
|
const cli = goke('lintcn');
|
|
14
15
|
cli
|
|
15
|
-
.command('add <url>', 'Add
|
|
16
|
-
.example('# Add a rule
|
|
17
|
-
.example('lintcn add https://github.com/
|
|
18
|
-
.example('# Add
|
|
19
|
-
.example('lintcn add https://
|
|
16
|
+
.command('add <url>', 'Add rules by GitHub URL. Supports single rule folders, .lintcn/ directories, or full repo URLs.')
|
|
17
|
+
.example('# Add a single rule folder')
|
|
18
|
+
.example('lintcn add https://github.com/oxc-project/tsgolint/tree/main/internal/rules/no_floating_promises')
|
|
19
|
+
.example('# Add by file URL (auto-fetches the whole folder)')
|
|
20
|
+
.example('lintcn add https://github.com/oxc-project/tsgolint/blob/main/internal/rules/await_thenable/await_thenable.go')
|
|
21
|
+
.example('# Add all rules from a repo (downloads .lintcn/ folder)')
|
|
22
|
+
.example('lintcn add https://github.com/someone/their-project')
|
|
20
23
|
.action(async (url) => {
|
|
21
24
|
await addRule(url);
|
|
22
25
|
});
|
|
@@ -34,12 +37,17 @@ cli
|
|
|
34
37
|
cli
|
|
35
38
|
.command('lint', 'Build custom tsgolint binary and run it against the project')
|
|
36
39
|
.option('--rebuild', 'Force rebuild even if cached binary exists')
|
|
40
|
+
.option('--fix', 'Automatically fix violations')
|
|
37
41
|
.option('--tsconfig <path>', 'Path to tsconfig.json')
|
|
38
42
|
.option('--list-files', 'List matched files')
|
|
43
|
+
.option('--all-warnings', 'Show warnings for all files, not just git-changed ones')
|
|
39
44
|
.option('--tsgolint-version [version]', 'Override the pinned tsgolint version (tag or commit). For testing unreleased tsgolint versions.')
|
|
40
45
|
.action(async (options) => {
|
|
41
46
|
const tsgolintVersion = options.tsgolintVersion || DEFAULT_TSGOLINT_VERSION;
|
|
42
47
|
const passthroughArgs = [];
|
|
48
|
+
if (options.fix) {
|
|
49
|
+
passthroughArgs.push('--fix');
|
|
50
|
+
}
|
|
43
51
|
if (options.tsconfig) {
|
|
44
52
|
passthroughArgs.push('--tsconfig', options.tsconfig);
|
|
45
53
|
}
|
|
@@ -55,6 +63,7 @@ cli
|
|
|
55
63
|
rebuild: !!options.rebuild,
|
|
56
64
|
tsgolintVersion,
|
|
57
65
|
passthroughArgs,
|
|
66
|
+
allWarnings: !!options.allWarnings,
|
|
58
67
|
});
|
|
59
68
|
process.exit(exitCode);
|
|
60
69
|
});
|
|
@@ -67,6 +76,11 @@ cli
|
|
|
67
76
|
const binaryPath = await buildBinary({ rebuild: !!options.rebuild, tsgolintVersion });
|
|
68
77
|
console.log(binaryPath);
|
|
69
78
|
});
|
|
79
|
+
cli
|
|
80
|
+
.command('clean', 'Remove cached tsgolint source and compiled binaries to free disk space')
|
|
81
|
+
.action(() => {
|
|
82
|
+
clean();
|
|
83
|
+
});
|
|
70
84
|
cli.help();
|
|
71
85
|
cli.version(packageJson.version);
|
|
72
86
|
cli.parse();
|
package/dist/codegen.js
CHANGED
|
@@ -102,10 +102,27 @@ go 1.26
|
|
|
102
102
|
const mainGo = generateMainGo(rules);
|
|
103
103
|
fs.writeFileSync(path.join(buildDir, 'wrapper', 'main.go'), mainGo);
|
|
104
104
|
}
|
|
105
|
-
/**
|
|
105
|
+
/** Sanitize a package name into a valid Go identifier for use as an import alias.
|
|
106
|
+
* Replaces hyphens/dots with underscores, prepends _ if starts with a digit. */
|
|
107
|
+
function toGoAlias(pkg) {
|
|
108
|
+
let alias = pkg.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
109
|
+
if (/^[0-9]/.test(alias)) {
|
|
110
|
+
alias = '_' + alias;
|
|
111
|
+
}
|
|
112
|
+
return alias;
|
|
113
|
+
}
|
|
114
|
+
/** Generate main.go that imports user rules and calls internal/runner.Run().
|
|
115
|
+
* Each rule subfolder is its own Go package, imported by package name. */
|
|
106
116
|
function generateMainGo(rules) {
|
|
117
|
+
// Deduplicate imports by package name (in case a subfolder has multiple rules)
|
|
118
|
+
const uniquePackages = [...new Set(rules.map((r) => { return r.packageName; }))];
|
|
119
|
+
const imports = uniquePackages.map((pkg) => {
|
|
120
|
+
const alias = toGoAlias(pkg);
|
|
121
|
+
return `\t${alias} "${TSGOLINT_MODULE}/lintcn-rules/${pkg}"`;
|
|
122
|
+
}).join('\n');
|
|
107
123
|
const ruleEntries = rules.map((r) => {
|
|
108
|
-
|
|
124
|
+
const alias = toGoAlias(r.packageName);
|
|
125
|
+
return `\t\t${alias}.${r.varName},`;
|
|
109
126
|
}).join('\n');
|
|
110
127
|
return `// Code generated by lintcn. DO NOT EDIT.
|
|
111
128
|
package main
|
|
@@ -115,7 +132,7 @@ import (
|
|
|
115
132
|
|
|
116
133
|
\t"${TSGOLINT_MODULE}/internal/rule"
|
|
117
134
|
\t"${TSGOLINT_MODULE}/internal/runner"
|
|
118
|
-
|
|
135
|
+
${imports}
|
|
119
136
|
)
|
|
120
137
|
|
|
121
138
|
func main() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAqQA,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0ExD"}
|