@utoo/lint 0.0.9 → 0.1.3
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 +16 -10
- package/bin/eslint.js +0 -0
- package/bin/migrate.js +4 -11
- package/bin/utoo-lint.js +3 -6
- package/index.cjs +290 -9
- package/index.d.ts +2 -0
- package/index.js +289 -9
- package/lib/binary.cjs +18 -3
- package/lib/binary.js +18 -3
- package/package.json +7 -7
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 utoo-lint contributors
|
|
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
|
@@ -7,7 +7,7 @@ High performance linter for JavaScript and TypeScript written by Zig.
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
pnpm add -D @utoo/lint
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
## CLI
|
|
@@ -15,28 +15,30 @@ npm install -D @utoo/lint
|
|
|
15
15
|
Run the linter with:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
|
|
18
|
+
pnpm exec utoo-lint src
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
If no target is provided, `utoo-lint`
|
|
22
|
-
`.
|
|
21
|
+
If no target is provided, `utoo-lint` uses `files` from `utoo.json` or
|
|
22
|
+
`utoo-lint.json`. When no config file or `files` entry exists, it scans the
|
|
23
|
+
current directory. It skips `.git`, `.zig-cache`, `node_modules`, `vendor`, and
|
|
24
|
+
`zig-out`.
|
|
23
25
|
|
|
24
26
|
Use a config file:
|
|
25
27
|
|
|
26
28
|
```bash
|
|
27
|
-
|
|
29
|
+
pnpm exec utoo-lint --config=utoo.json src
|
|
28
30
|
```
|
|
29
31
|
|
|
30
32
|
Run a focused rule set:
|
|
31
33
|
|
|
32
34
|
```bash
|
|
33
|
-
|
|
35
|
+
pnpm exec utoo-lint --rules=no-debugger,no-console src
|
|
34
36
|
```
|
|
35
37
|
|
|
36
38
|
Use machine-readable output:
|
|
37
39
|
|
|
38
40
|
```bash
|
|
39
|
-
|
|
41
|
+
pnpm exec utoo-lint --format=json src
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
## Configuration
|
|
@@ -66,14 +68,14 @@ cp node_modules/@utoo/lint/configs/frontend.json utoo.json
|
|
|
66
68
|
Convert an existing ESLint config into the native utoo format:
|
|
67
69
|
|
|
68
70
|
```bash
|
|
69
|
-
|
|
71
|
+
pnpm exec utoo-lint migrate eslint --from eslint.config.js --output utoo.json
|
|
70
72
|
```
|
|
71
73
|
|
|
72
74
|
The package also provides compatibility bins for common replacement flows:
|
|
73
75
|
|
|
74
76
|
```bash
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
pnpm exec eslint --config utoo.json src
|
|
78
|
+
pnpm exec fishlint eslint --disable-setup --config utoo.json --glob src
|
|
77
79
|
```
|
|
78
80
|
|
|
79
81
|
## JavaScript API
|
|
@@ -89,6 +91,10 @@ const report = lintFiles(["src"], {
|
|
|
89
91
|
console.log(report.diagnostics);
|
|
90
92
|
```
|
|
91
93
|
|
|
94
|
+
Calling `lintFiles()` without patterns follows the same default target behavior
|
|
95
|
+
as the CLI, so migration scripts usually do not need to expand config `files`
|
|
96
|
+
manually.
|
|
97
|
+
|
|
92
98
|
CommonJS is supported through `require("@utoo/lint")`.
|
|
93
99
|
|
|
94
100
|
## Binary Resolution
|
package/bin/eslint.js
CHANGED
|
File without changes
|
package/bin/migrate.js
CHANGED
|
@@ -183,7 +183,6 @@ function migrateEslintConfig(options) {
|
|
|
183
183
|
const supportedRules = [];
|
|
184
184
|
const unsupportedRules = [];
|
|
185
185
|
const ignoredRules = [];
|
|
186
|
-
const optionDroppedRules = [];
|
|
187
186
|
|
|
188
187
|
for (const entry of entries) {
|
|
189
188
|
addPatterns(files, entry.files);
|
|
@@ -200,11 +199,8 @@ function migrateEslintConfig(options) {
|
|
|
200
199
|
unsupportedRules.push(ruleId);
|
|
201
200
|
continue;
|
|
202
201
|
}
|
|
203
|
-
rules[ruleId] =
|
|
202
|
+
rules[ruleId] = migratableRuleConfig(ruleConfig);
|
|
204
203
|
supportedRules.push(ruleId);
|
|
205
|
-
if (Array.isArray(ruleConfig) && ruleConfig.length > 1) {
|
|
206
|
-
optionDroppedRules.push(ruleId);
|
|
207
|
-
}
|
|
208
204
|
}
|
|
209
205
|
}
|
|
210
206
|
|
|
@@ -227,7 +223,7 @@ function migrateEslintConfig(options) {
|
|
|
227
223
|
supportedRules: uniqueSorted(supportedRules),
|
|
228
224
|
unsupportedRules: uniqueSorted(unsupportedRules),
|
|
229
225
|
ignoredRules: uniqueByRuleId(ignoredRules),
|
|
230
|
-
optionDroppedRules:
|
|
226
|
+
optionDroppedRules: []
|
|
231
227
|
}
|
|
232
228
|
};
|
|
233
229
|
}
|
|
@@ -295,8 +291,8 @@ function addPatterns(target, value) {
|
|
|
295
291
|
}
|
|
296
292
|
}
|
|
297
293
|
|
|
298
|
-
function
|
|
299
|
-
return Array.isArray(ruleConfig) ? ruleConfig
|
|
294
|
+
function migratableRuleConfig(ruleConfig) {
|
|
295
|
+
return Array.isArray(ruleConfig) ? [...ruleConfig] : ruleConfig;
|
|
300
296
|
}
|
|
301
297
|
|
|
302
298
|
function sortObjectByKey(object) {
|
|
@@ -326,9 +322,6 @@ function writeReport(report, options, stream) {
|
|
|
326
322
|
stream.write(`utoo-lint migrate eslint: wrote ${report.output}\n`);
|
|
327
323
|
}
|
|
328
324
|
stream.write(`utoo-lint migrate eslint: migrated ${report.supportedRules.length} supported rule(s)\n`);
|
|
329
|
-
if (report.optionDroppedRules.length > 0) {
|
|
330
|
-
stream.write(`utoo-lint migrate eslint: dropped options for ${report.optionDroppedRules.length} rule(s): ${report.optionDroppedRules.join(", ")}\n`);
|
|
331
|
-
}
|
|
332
325
|
if (report.ignoredRules.length > 0) {
|
|
333
326
|
stream.write(`utoo-lint migrate eslint: ignored ${report.ignoredRules.length} rule(s): ${report.ignoredRules.map((rule) => rule.ruleId).join(", ")}\n`);
|
|
334
327
|
}
|
package/bin/utoo-lint.js
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { spawnSync } from "node:child_process";
|
|
3
2
|
|
|
4
|
-
import {
|
|
3
|
+
import { runCli } from "../index.js";
|
|
5
4
|
|
|
6
5
|
if (process.argv[2] === "migrate") {
|
|
7
6
|
const { runMigrate } = await import("./migrate.js");
|
|
8
7
|
process.exit(await runMigrate(process.argv.slice(3)));
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
let
|
|
10
|
+
let result;
|
|
12
11
|
try {
|
|
13
|
-
|
|
12
|
+
result = runCli(process.argv.slice(2), { stdio: "inherit" });
|
|
14
13
|
} catch (error) {
|
|
15
14
|
console.error(error.message);
|
|
16
15
|
process.exit(1);
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
const result = spawnSync(binary, process.argv.slice(2), { stdio: "inherit" });
|
|
20
|
-
|
|
21
18
|
if (result.error) {
|
|
22
19
|
console.error(`utoo-lint: failed to run native binary: ${result.error.message}`);
|
|
23
20
|
process.exit(1);
|
package/index.cjs
CHANGED
|
@@ -83,9 +83,13 @@ process.stdout.write(json);
|
|
|
83
83
|
const BUILTIN_RULE_IDS = [
|
|
84
84
|
"accessor-pairs",
|
|
85
85
|
"array-callback-return",
|
|
86
|
+
"arrow-body-style",
|
|
86
87
|
"block-scoped-var",
|
|
88
|
+
"camelcase",
|
|
87
89
|
"capitalized-comments",
|
|
90
|
+
"complexity",
|
|
88
91
|
"consistent-return",
|
|
92
|
+
"consistent-this",
|
|
89
93
|
"constructor-super",
|
|
90
94
|
"curly",
|
|
91
95
|
"default-case",
|
|
@@ -97,11 +101,23 @@ const BUILTIN_RULE_IDS = [
|
|
|
97
101
|
"for-direction",
|
|
98
102
|
"func-name-matching",
|
|
99
103
|
"func-names",
|
|
104
|
+
"func-style",
|
|
100
105
|
"getter-return",
|
|
101
106
|
"grouped-accessor-pairs",
|
|
102
107
|
"guard-for-in",
|
|
108
|
+
"id-denylist",
|
|
109
|
+
"id-length",
|
|
110
|
+
"id-match",
|
|
111
|
+
"init-declarations",
|
|
103
112
|
"linebreak-style",
|
|
104
113
|
"logical-assignment-operators",
|
|
114
|
+
"max-classes-per-file",
|
|
115
|
+
"max-depth",
|
|
116
|
+
"max-lines",
|
|
117
|
+
"max-lines-per-function",
|
|
118
|
+
"max-nested-callbacks",
|
|
119
|
+
"max-params",
|
|
120
|
+
"max-statements",
|
|
105
121
|
"new-cap",
|
|
106
122
|
"new-parens",
|
|
107
123
|
"no-alert",
|
|
@@ -119,6 +135,7 @@ const BUILTIN_RULE_IDS = [
|
|
|
119
135
|
"no-cond-assign",
|
|
120
136
|
"no-console",
|
|
121
137
|
"no-const-assign",
|
|
138
|
+
"no-constant-binary-expression",
|
|
122
139
|
"no-constant-condition",
|
|
123
140
|
"no-constructor-return",
|
|
124
141
|
"no-continue",
|
|
@@ -155,6 +172,7 @@ const BUILTIN_RULE_IDS = [
|
|
|
155
172
|
"no-global-is-finite",
|
|
156
173
|
"no-global-is-nan",
|
|
157
174
|
"no-implicit-coercion",
|
|
175
|
+
"no-implicit-globals",
|
|
158
176
|
"no-implied-eval",
|
|
159
177
|
"no-import-assign",
|
|
160
178
|
"no-inline-comments",
|
|
@@ -196,6 +214,13 @@ const BUILTIN_RULE_IDS = [
|
|
|
196
214
|
"no-promise-executor-return",
|
|
197
215
|
"no-proto",
|
|
198
216
|
"no-prototype-builtins",
|
|
217
|
+
"no-redeclare",
|
|
218
|
+
"no-restricted-exports",
|
|
219
|
+
"no-restricted-globals",
|
|
220
|
+
"no-restricted-imports",
|
|
221
|
+
"no-restricted-modules",
|
|
222
|
+
"no-restricted-properties",
|
|
223
|
+
"no-restricted-syntax",
|
|
199
224
|
"no-regex-spaces",
|
|
200
225
|
"no-return-assign",
|
|
201
226
|
"no-return-await",
|
|
@@ -204,6 +229,7 @@ const BUILTIN_RULE_IDS = [
|
|
|
204
229
|
"no-self-compare",
|
|
205
230
|
"no-sequences",
|
|
206
231
|
"no-setter-return",
|
|
232
|
+
"no-shadow",
|
|
207
233
|
"no-shadow-restricted-names",
|
|
208
234
|
"no-sparse-arrays",
|
|
209
235
|
"no-tabs",
|
|
@@ -214,15 +240,21 @@ const BUILTIN_RULE_IDS = [
|
|
|
214
240
|
"no-trailing-spaces",
|
|
215
241
|
"no-undef",
|
|
216
242
|
"no-undef-init",
|
|
243
|
+
"no-unassigned-vars",
|
|
217
244
|
"no-underscore-dangle",
|
|
218
245
|
"no-undefined",
|
|
219
246
|
"no-unneeded-ternary",
|
|
220
247
|
"no-unreachable",
|
|
248
|
+
"no-unreachable-loop",
|
|
221
249
|
"no-unsafe-finally",
|
|
222
250
|
"no-unsafe-negation",
|
|
251
|
+
"no-unsafe-optional-chaining",
|
|
223
252
|
"no-unused-expressions",
|
|
224
253
|
"no-unused-labels",
|
|
254
|
+
"no-unused-private-class-members",
|
|
225
255
|
"no-unused-vars",
|
|
256
|
+
"no-use-before-define",
|
|
257
|
+
"no-useless-backreference",
|
|
226
258
|
"no-useless-call",
|
|
227
259
|
"no-useless-catch",
|
|
228
260
|
"no-useless-computed-key",
|
|
@@ -238,13 +270,16 @@ const BUILTIN_RULE_IDS = [
|
|
|
238
270
|
"object-shorthand",
|
|
239
271
|
"one-var",
|
|
240
272
|
"operator-assignment",
|
|
273
|
+
"prefer-arrow-callback",
|
|
241
274
|
"prefer-const",
|
|
242
275
|
"prefer-destructuring",
|
|
243
276
|
"prefer-exponentiation-operator",
|
|
277
|
+
"prefer-named-capture-group",
|
|
244
278
|
"prefer-numeric-literals",
|
|
245
279
|
"prefer-object-has-own",
|
|
246
280
|
"prefer-object-spread",
|
|
247
281
|
"prefer-promise-reject-errors",
|
|
282
|
+
"preserve-caught-error",
|
|
248
283
|
"prefer-regex-literals",
|
|
249
284
|
"prefer-rest-params",
|
|
250
285
|
"prefer-spread",
|
|
@@ -252,8 +287,13 @@ const BUILTIN_RULE_IDS = [
|
|
|
252
287
|
"radix",
|
|
253
288
|
"require-await",
|
|
254
289
|
"require-atomic-updates",
|
|
290
|
+
"require-unicode-regexp",
|
|
255
291
|
"require-yield",
|
|
292
|
+
"sort-imports",
|
|
293
|
+
"sort-keys",
|
|
294
|
+
"sort-vars",
|
|
256
295
|
"spaced-comment",
|
|
296
|
+
"strict",
|
|
257
297
|
"symbol-description",
|
|
258
298
|
"unicode-bom",
|
|
259
299
|
"use-isnan",
|
|
@@ -261,6 +301,7 @@ const BUILTIN_RULE_IDS = [
|
|
|
261
301
|
"vars-on-top",
|
|
262
302
|
"wrap-iife",
|
|
263
303
|
"yoda",
|
|
304
|
+
"eslint-comments/no-restricted-disable",
|
|
264
305
|
"import/default",
|
|
265
306
|
"import/export",
|
|
266
307
|
"import/first",
|
|
@@ -274,22 +315,59 @@ const BUILTIN_RULE_IDS = [
|
|
|
274
315
|
"import/no-named-as-default-member",
|
|
275
316
|
"import/no-unresolved",
|
|
276
317
|
"import/no-self-import",
|
|
318
|
+
"jsx-a11y/alt-text",
|
|
319
|
+
"jsx-a11y/anchor-has-content",
|
|
277
320
|
"jsx-a11y/aria-props",
|
|
321
|
+
"jsx-a11y/aria-proptypes",
|
|
322
|
+
"jsx-a11y/aria-role",
|
|
323
|
+
"jsx-a11y/aria-unsupported-elements",
|
|
278
324
|
"jsx-a11y/iframe-has-title",
|
|
279
325
|
"jsx-a11y/img-redundant-alt",
|
|
280
326
|
"jsx-a11y/no-access-key",
|
|
327
|
+
"jsx-a11y/no-distracting-elements",
|
|
328
|
+
"jsx-a11y/role-has-required-aria-props",
|
|
329
|
+
"jsx-a11y/role-supports-aria-props",
|
|
330
|
+
"jsx-a11y/scope",
|
|
331
|
+
"react/button-has-type",
|
|
332
|
+
"react/default-props-match-prop-types",
|
|
333
|
+
"react/display-name",
|
|
334
|
+
"react/forbid-prop-types",
|
|
281
335
|
"react/jsx-boolean-value",
|
|
336
|
+
"react/jsx-filename-extension",
|
|
337
|
+
"react/jsx-key",
|
|
338
|
+
"react/jsx-no-bind",
|
|
282
339
|
"react/jsx-no-comment-textnodes",
|
|
283
340
|
"react/jsx-no-duplicate-props",
|
|
341
|
+
"react/jsx-no-undef",
|
|
342
|
+
"react/jsx-uses-react",
|
|
343
|
+
"react/jsx-uses-vars",
|
|
284
344
|
"react/jsx-no-target-blank",
|
|
285
345
|
"react/jsx-pascal-case",
|
|
346
|
+
"react/no-access-state-in-setstate",
|
|
347
|
+
"react/no-array-index-key",
|
|
348
|
+
"react/no-children-prop",
|
|
286
349
|
"react/no-danger",
|
|
350
|
+
"react/no-danger-with-children",
|
|
351
|
+
"react/no-deprecated",
|
|
287
352
|
"react/no-find-dom-node",
|
|
288
353
|
"react/no-is-mounted",
|
|
354
|
+
"react/no-multi-comp",
|
|
355
|
+
"react/no-redundant-should-component-update",
|
|
289
356
|
"react/no-render-return-value",
|
|
357
|
+
"react/no-string-refs",
|
|
358
|
+
"react/no-this-in-sfc",
|
|
359
|
+
"react/no-typos",
|
|
290
360
|
"react/no-unescaped-entities",
|
|
361
|
+
"react/no-unknown-property",
|
|
291
362
|
"react/no-unused-prop-types",
|
|
363
|
+
"react/no-unused-state",
|
|
364
|
+
"react/no-will-update-set-state",
|
|
365
|
+
"react/prefer-es6-class",
|
|
292
366
|
"react/prop-types",
|
|
367
|
+
"react/require-render-return",
|
|
368
|
+
"react/self-closing-comp",
|
|
369
|
+
"react/style-prop-object",
|
|
370
|
+
"react/void-dom-elements-no-children",
|
|
293
371
|
"react-hooks/rules-of-hooks",
|
|
294
372
|
"@typescript-eslint/adjacent-overload-signatures",
|
|
295
373
|
"@typescript-eslint/array-type",
|
|
@@ -313,6 +391,7 @@ const BUILTIN_RULE_IDS = [
|
|
|
313
391
|
"@typescript-eslint/no-extra-non-null-assertion",
|
|
314
392
|
"@typescript-eslint/no-inferrable-types",
|
|
315
393
|
"@typescript-eslint/no-invalid-void-type",
|
|
394
|
+
"@typescript-eslint/no-loop-func",
|
|
316
395
|
"@typescript-eslint/no-loss-of-precision",
|
|
317
396
|
"@typescript-eslint/no-misused-new",
|
|
318
397
|
"@typescript-eslint/no-namespace",
|
|
@@ -386,7 +465,7 @@ class UtooLint {
|
|
|
386
465
|
this.options = { ...options };
|
|
387
466
|
}
|
|
388
467
|
|
|
389
|
-
async lintFiles(patterns
|
|
468
|
+
async lintFiles(patterns, options = {}) {
|
|
390
469
|
const mergedOptions = mergeLintOptions(this.options, options);
|
|
391
470
|
const customRuleConfig = [mergedOptions.baseConfig, mergedOptions.overrideConfig].filter(Boolean);
|
|
392
471
|
const customRuleFilterMap = customRuleMapForConfig(customRuleConfig, new Map());
|
|
@@ -591,6 +670,152 @@ function run(args = [], options = {}) {
|
|
|
591
670
|
});
|
|
592
671
|
}
|
|
593
672
|
|
|
673
|
+
const UTOO_LINT_CLI_VALUE_FLAGS = new Set(["--config", "-c", "--format", "-f", "--rules", "--threads"]);
|
|
674
|
+
|
|
675
|
+
function parseUtooLintCliArgs(args = []) {
|
|
676
|
+
const values = normalizeStringArray(args, "args");
|
|
677
|
+
const passthroughArgs = [];
|
|
678
|
+
const targets = [];
|
|
679
|
+
const options = {};
|
|
680
|
+
let help = false;
|
|
681
|
+
let versionFlag = false;
|
|
682
|
+
|
|
683
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
684
|
+
const arg = values[index];
|
|
685
|
+
if (arg === "--") {
|
|
686
|
+
targets.push(...values.slice(index + 1));
|
|
687
|
+
break;
|
|
688
|
+
}
|
|
689
|
+
if (arg === "--help" || arg === "-h") {
|
|
690
|
+
help = true;
|
|
691
|
+
passthroughArgs.push(arg);
|
|
692
|
+
continue;
|
|
693
|
+
}
|
|
694
|
+
if (arg === "--version" || arg === "-v") {
|
|
695
|
+
versionFlag = true;
|
|
696
|
+
continue;
|
|
697
|
+
}
|
|
698
|
+
if (UTOO_LINT_CLI_VALUE_FLAGS.has(arg)) {
|
|
699
|
+
const value = values[index + 1];
|
|
700
|
+
if (!value) {
|
|
701
|
+
throw new Error(`utoo-lint: ${arg} requires a value`);
|
|
702
|
+
}
|
|
703
|
+
appendCliOption(passthroughArgs, options, arg, value);
|
|
704
|
+
index += 1;
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
707
|
+
if (arg.startsWith("--config=")) {
|
|
708
|
+
appendCliOption(passthroughArgs, options, "--config", arg.slice("--config=".length));
|
|
709
|
+
continue;
|
|
710
|
+
}
|
|
711
|
+
if (arg.startsWith("--format=")) {
|
|
712
|
+
appendCliOption(passthroughArgs, options, "--format", arg.slice("--format=".length));
|
|
713
|
+
continue;
|
|
714
|
+
}
|
|
715
|
+
if (arg.startsWith("--rules=")) {
|
|
716
|
+
appendCliOption(passthroughArgs, options, "--rules", arg.slice("--rules=".length));
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
if (arg.startsWith("--threads=")) {
|
|
720
|
+
appendCliOption(passthroughArgs, options, "--threads", arg.slice("--threads=".length));
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
723
|
+
if (arg === "--no-config") {
|
|
724
|
+
options.noConfig = true;
|
|
725
|
+
delete options.config;
|
|
726
|
+
continue;
|
|
727
|
+
}
|
|
728
|
+
if (arg === "--json") {
|
|
729
|
+
passthroughArgs.push(arg);
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
if (arg.startsWith("-")) {
|
|
733
|
+
passthroughArgs.push(arg);
|
|
734
|
+
continue;
|
|
735
|
+
}
|
|
736
|
+
targets.push(arg);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
return { help, options, passthroughArgs, targets, version: versionFlag };
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
function appendCliOption(passthroughArgs, options, flag, value) {
|
|
743
|
+
if (value == null || value === "") {
|
|
744
|
+
throw new Error(`utoo-lint: ${flag} requires a value`);
|
|
745
|
+
}
|
|
746
|
+
switch (flag) {
|
|
747
|
+
case "--config":
|
|
748
|
+
case "-c":
|
|
749
|
+
options.config = value;
|
|
750
|
+
delete options.noConfig;
|
|
751
|
+
return;
|
|
752
|
+
case "--format":
|
|
753
|
+
case "-f":
|
|
754
|
+
options.format = value;
|
|
755
|
+
return;
|
|
756
|
+
case "--rules":
|
|
757
|
+
options.rules = value;
|
|
758
|
+
return;
|
|
759
|
+
case "--threads":
|
|
760
|
+
options.threads = value;
|
|
761
|
+
return;
|
|
762
|
+
default:
|
|
763
|
+
passthroughArgs.push(`${flag}=${value}`);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
function completedRunResult(status, stdout, stderr, options = {}) {
|
|
768
|
+
const inherited = options.stdio === "inherit";
|
|
769
|
+
if (inherited) {
|
|
770
|
+
if (stdout) {
|
|
771
|
+
process.stdout.write(stdout);
|
|
772
|
+
}
|
|
773
|
+
if (stderr) {
|
|
774
|
+
process.stderr.write(stderr);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
return {
|
|
778
|
+
status,
|
|
779
|
+
signal: null,
|
|
780
|
+
error: undefined,
|
|
781
|
+
stdout: inherited ? null : stdout,
|
|
782
|
+
stderr: inherited ? null : stderr,
|
|
783
|
+
output: [null, inherited ? null : stdout, inherited ? null : stderr],
|
|
784
|
+
pid: 0
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
function runCli(args = [], options = {}) {
|
|
789
|
+
const parsed = parseUtooLintCliArgs(args);
|
|
790
|
+
if (parsed.version) {
|
|
791
|
+
return completedRunResult(0, `v${version}\n`, "", options);
|
|
792
|
+
}
|
|
793
|
+
if (parsed.help) {
|
|
794
|
+
return run(parsed.passthroughArgs, options);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
const cliOptions = {
|
|
798
|
+
...options,
|
|
799
|
+
...parsed.options
|
|
800
|
+
};
|
|
801
|
+
const targets = parsed.targets.length > 0 ? parsed.targets : defaultLintTargets(cliOptions);
|
|
802
|
+
const ignoredDiagnostics = ignoredLintPathDiagnostics(targets, cliOptions);
|
|
803
|
+
const lintPaths = filteredLintPaths(targets, cliOptions);
|
|
804
|
+
if (lintPaths.length === 0) {
|
|
805
|
+
return completedRunResult(ignoredDiagnostics.length > 0 ? 1 : 0, "", "", options);
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
return withTemporaryConfig(cliOptions, (resolvedOptions) => {
|
|
809
|
+
const cliArgs = buildRunCliArgs(lintPaths, resolvedOptions, parsed.passthroughArgs);
|
|
810
|
+
return run(cliArgs, {
|
|
811
|
+
...resolvedOptions,
|
|
812
|
+
stdio: options.stdio,
|
|
813
|
+
encoding: options.encoding,
|
|
814
|
+
input: options.input
|
|
815
|
+
});
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
|
|
594
819
|
function runFishlint(args = [], options = {}) {
|
|
595
820
|
const cliArgs = normalizeStringArray(args, "args");
|
|
596
821
|
const env = options.env ? { ...process.env, ...options.env } : { ...process.env };
|
|
@@ -803,14 +1028,15 @@ function booleanFlagValue(arg) {
|
|
|
803
1028
|
return true;
|
|
804
1029
|
}
|
|
805
1030
|
|
|
806
|
-
function lintFiles(paths
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
1031
|
+
function lintFiles(paths, options = {}) {
|
|
1032
|
+
const targets = lintTargetsForInput(paths, options);
|
|
1033
|
+
const ignoredDiagnostics = ignoredLintPathDiagnostics(targets, options);
|
|
1034
|
+
const lintPaths = filteredLintPaths(targets, options);
|
|
1035
|
+
if (lintPaths.length === 0) {
|
|
1036
|
+
return { files: 0, filePaths: [], diagnostics: ignoredDiagnostics, exitCode: ignoredDiagnostics.length > 0 ? 1 : 0 };
|
|
1037
|
+
}
|
|
813
1038
|
|
|
1039
|
+
return withTemporaryConfig(options, (resolvedOptions) => {
|
|
814
1040
|
const cliArgs = buildLintArgs(lintPaths, resolvedOptions);
|
|
815
1041
|
const result = run(cliArgs, { ...resolvedOptions, stdio: undefined, encoding: "utf8" });
|
|
816
1042
|
|
|
@@ -902,6 +1128,21 @@ function lintText(code, options = {}) {
|
|
|
902
1128
|
}
|
|
903
1129
|
|
|
904
1130
|
function buildLintArgs(paths, options) {
|
|
1131
|
+
return buildNativeLintArgs(paths, {
|
|
1132
|
+
...options,
|
|
1133
|
+
format: "json",
|
|
1134
|
+
extraArgs: options.extraArgs
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
function buildRunCliArgs(paths, options, passthroughArgs) {
|
|
1139
|
+
return buildNativeLintArgs(paths, {
|
|
1140
|
+
...options,
|
|
1141
|
+
extraArgs: passthroughArgs
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
function buildNativeLintArgs(paths, options) {
|
|
905
1146
|
const cliArgs = [];
|
|
906
1147
|
|
|
907
1148
|
if (options.config) {
|
|
@@ -920,7 +1161,9 @@ function buildLintArgs(paths, options) {
|
|
|
920
1161
|
cliArgs.push(`--threads=${options.threads}`);
|
|
921
1162
|
}
|
|
922
1163
|
|
|
923
|
-
|
|
1164
|
+
if (options.format) {
|
|
1165
|
+
cliArgs.push(`--format=${options.format}`);
|
|
1166
|
+
}
|
|
924
1167
|
|
|
925
1168
|
if (options.extraArgs) {
|
|
926
1169
|
cliArgs.push(...normalizeStringArray(options.extraArgs, "extraArgs"));
|
|
@@ -1127,6 +1370,37 @@ function configDataFromFileConfig(options, filePath) {
|
|
|
1127
1370
|
return configDataFromConfig(config, filePath, options.cwd);
|
|
1128
1371
|
}
|
|
1129
1372
|
|
|
1373
|
+
function lintTargetsForInput(paths, options = {}) {
|
|
1374
|
+
if (paths == null) {
|
|
1375
|
+
return defaultLintTargets(options);
|
|
1376
|
+
}
|
|
1377
|
+
return normalizeStringArray(Array.isArray(paths) ? paths : [paths], "paths");
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
function defaultLintTargets(options = {}) {
|
|
1381
|
+
if (options.noConfig) {
|
|
1382
|
+
return ["."];
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
const configPath = configPathForOptions(options);
|
|
1386
|
+
if (!configPath) {
|
|
1387
|
+
return ["."];
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
const targets = filePatternsFromConfig(readConfig(configPath, options.cwd));
|
|
1391
|
+
return targets.length > 0 ? targets : ["."];
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
function filePatternsFromConfig(config) {
|
|
1395
|
+
if (!config) {
|
|
1396
|
+
return [];
|
|
1397
|
+
}
|
|
1398
|
+
if (Array.isArray(config)) {
|
|
1399
|
+
return config.flatMap((entry) => filePatternsFromConfig(entry));
|
|
1400
|
+
}
|
|
1401
|
+
return normalizeConfigPatterns(config.files);
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1130
1404
|
function configAppliesToFile(config, filePath, cwd) {
|
|
1131
1405
|
if (!filePath) {
|
|
1132
1406
|
return true;
|
|
@@ -1151,6 +1425,9 @@ function normalizeConfigPatterns(patterns) {
|
|
|
1151
1425
|
if (typeof value === "string") {
|
|
1152
1426
|
return [value];
|
|
1153
1427
|
}
|
|
1428
|
+
if (Array.isArray(value)) {
|
|
1429
|
+
return normalizeConfigPatterns(value);
|
|
1430
|
+
}
|
|
1154
1431
|
return [];
|
|
1155
1432
|
});
|
|
1156
1433
|
}
|
|
@@ -3662,6 +3939,9 @@ function matchesIgnorePattern(target, pattern) {
|
|
|
3662
3939
|
}
|
|
3663
3940
|
|
|
3664
3941
|
function matchesConfigFilePattern(target, pattern) {
|
|
3942
|
+
if (!hasGlobSyntax(pattern)) {
|
|
3943
|
+
return target === pattern || target.startsWith(`${pattern}/`) || target.endsWith(`/${pattern}`);
|
|
3944
|
+
}
|
|
3665
3945
|
const expression = new RegExp(`^${globPatternRegExpSource(pattern)}$`);
|
|
3666
3946
|
return expression.test(target);
|
|
3667
3947
|
}
|
|
@@ -4028,6 +4308,7 @@ module.exports = {
|
|
|
4028
4308
|
platformPackageName,
|
|
4029
4309
|
resolveBinary,
|
|
4030
4310
|
run,
|
|
4311
|
+
runCli,
|
|
4031
4312
|
runFishlint,
|
|
4032
4313
|
translateFishlintArgs,
|
|
4033
4314
|
version
|
package/index.d.ts
CHANGED
|
@@ -82,6 +82,7 @@ export interface LintOptions {
|
|
|
82
82
|
env?: Record<string, string | undefined>;
|
|
83
83
|
threads?: number;
|
|
84
84
|
rules?: string[] | string;
|
|
85
|
+
format?: "text" | "json" | string;
|
|
85
86
|
config?: string;
|
|
86
87
|
configFile?: string;
|
|
87
88
|
noConfig?: boolean;
|
|
@@ -309,6 +310,7 @@ export function loadESLint(options?: { useFlatConfig?: boolean; cwd?: string }):
|
|
|
309
310
|
export function lintFiles(patterns?: string | string[], options?: LintOptions): LintReport;
|
|
310
311
|
export function lintText(code: string, options?: TextLintOptions): LintReport;
|
|
311
312
|
export function run(args?: string[], options?: LintOptions): unknown;
|
|
313
|
+
export function runCli(args?: string[], options?: LintOptions): unknown;
|
|
312
314
|
export function runFishlint(args?: string[], options?: LintOptions): unknown;
|
|
313
315
|
export function translateFishlintArgs(args?: string[], options?: { command?: string; warn?: (message: string) => void }): string[];
|
|
314
316
|
export function resolveBinary(options?: { env?: Record<string, string | undefined>; platform?: string; arch?: string }): string;
|
package/index.js
CHANGED
|
@@ -86,9 +86,13 @@ process.stdout.write(json);
|
|
|
86
86
|
const BUILTIN_RULE_IDS = [
|
|
87
87
|
"accessor-pairs",
|
|
88
88
|
"array-callback-return",
|
|
89
|
+
"arrow-body-style",
|
|
89
90
|
"block-scoped-var",
|
|
91
|
+
"camelcase",
|
|
90
92
|
"capitalized-comments",
|
|
93
|
+
"complexity",
|
|
91
94
|
"consistent-return",
|
|
95
|
+
"consistent-this",
|
|
92
96
|
"constructor-super",
|
|
93
97
|
"curly",
|
|
94
98
|
"default-case",
|
|
@@ -100,11 +104,23 @@ const BUILTIN_RULE_IDS = [
|
|
|
100
104
|
"for-direction",
|
|
101
105
|
"func-name-matching",
|
|
102
106
|
"func-names",
|
|
107
|
+
"func-style",
|
|
103
108
|
"getter-return",
|
|
104
109
|
"grouped-accessor-pairs",
|
|
105
110
|
"guard-for-in",
|
|
111
|
+
"id-denylist",
|
|
112
|
+
"id-length",
|
|
113
|
+
"id-match",
|
|
114
|
+
"init-declarations",
|
|
106
115
|
"linebreak-style",
|
|
107
116
|
"logical-assignment-operators",
|
|
117
|
+
"max-classes-per-file",
|
|
118
|
+
"max-depth",
|
|
119
|
+
"max-lines",
|
|
120
|
+
"max-lines-per-function",
|
|
121
|
+
"max-nested-callbacks",
|
|
122
|
+
"max-params",
|
|
123
|
+
"max-statements",
|
|
108
124
|
"new-cap",
|
|
109
125
|
"new-parens",
|
|
110
126
|
"no-alert",
|
|
@@ -122,6 +138,7 @@ const BUILTIN_RULE_IDS = [
|
|
|
122
138
|
"no-cond-assign",
|
|
123
139
|
"no-console",
|
|
124
140
|
"no-const-assign",
|
|
141
|
+
"no-constant-binary-expression",
|
|
125
142
|
"no-constant-condition",
|
|
126
143
|
"no-constructor-return",
|
|
127
144
|
"no-continue",
|
|
@@ -158,6 +175,7 @@ const BUILTIN_RULE_IDS = [
|
|
|
158
175
|
"no-global-is-finite",
|
|
159
176
|
"no-global-is-nan",
|
|
160
177
|
"no-implicit-coercion",
|
|
178
|
+
"no-implicit-globals",
|
|
161
179
|
"no-implied-eval",
|
|
162
180
|
"no-import-assign",
|
|
163
181
|
"no-inline-comments",
|
|
@@ -199,6 +217,13 @@ const BUILTIN_RULE_IDS = [
|
|
|
199
217
|
"no-promise-executor-return",
|
|
200
218
|
"no-proto",
|
|
201
219
|
"no-prototype-builtins",
|
|
220
|
+
"no-redeclare",
|
|
221
|
+
"no-restricted-exports",
|
|
222
|
+
"no-restricted-globals",
|
|
223
|
+
"no-restricted-imports",
|
|
224
|
+
"no-restricted-modules",
|
|
225
|
+
"no-restricted-properties",
|
|
226
|
+
"no-restricted-syntax",
|
|
202
227
|
"no-regex-spaces",
|
|
203
228
|
"no-return-assign",
|
|
204
229
|
"no-return-await",
|
|
@@ -207,6 +232,7 @@ const BUILTIN_RULE_IDS = [
|
|
|
207
232
|
"no-self-compare",
|
|
208
233
|
"no-sequences",
|
|
209
234
|
"no-setter-return",
|
|
235
|
+
"no-shadow",
|
|
210
236
|
"no-shadow-restricted-names",
|
|
211
237
|
"no-sparse-arrays",
|
|
212
238
|
"no-tabs",
|
|
@@ -217,15 +243,21 @@ const BUILTIN_RULE_IDS = [
|
|
|
217
243
|
"no-trailing-spaces",
|
|
218
244
|
"no-undef",
|
|
219
245
|
"no-undef-init",
|
|
246
|
+
"no-unassigned-vars",
|
|
220
247
|
"no-underscore-dangle",
|
|
221
248
|
"no-undefined",
|
|
222
249
|
"no-unneeded-ternary",
|
|
223
250
|
"no-unreachable",
|
|
251
|
+
"no-unreachable-loop",
|
|
224
252
|
"no-unsafe-finally",
|
|
225
253
|
"no-unsafe-negation",
|
|
254
|
+
"no-unsafe-optional-chaining",
|
|
226
255
|
"no-unused-expressions",
|
|
227
256
|
"no-unused-labels",
|
|
257
|
+
"no-unused-private-class-members",
|
|
228
258
|
"no-unused-vars",
|
|
259
|
+
"no-use-before-define",
|
|
260
|
+
"no-useless-backreference",
|
|
229
261
|
"no-useless-call",
|
|
230
262
|
"no-useless-catch",
|
|
231
263
|
"no-useless-computed-key",
|
|
@@ -241,13 +273,16 @@ const BUILTIN_RULE_IDS = [
|
|
|
241
273
|
"object-shorthand",
|
|
242
274
|
"one-var",
|
|
243
275
|
"operator-assignment",
|
|
276
|
+
"prefer-arrow-callback",
|
|
244
277
|
"prefer-const",
|
|
245
278
|
"prefer-destructuring",
|
|
246
279
|
"prefer-exponentiation-operator",
|
|
280
|
+
"prefer-named-capture-group",
|
|
247
281
|
"prefer-numeric-literals",
|
|
248
282
|
"prefer-object-has-own",
|
|
249
283
|
"prefer-object-spread",
|
|
250
284
|
"prefer-promise-reject-errors",
|
|
285
|
+
"preserve-caught-error",
|
|
251
286
|
"prefer-regex-literals",
|
|
252
287
|
"prefer-rest-params",
|
|
253
288
|
"prefer-spread",
|
|
@@ -255,8 +290,13 @@ const BUILTIN_RULE_IDS = [
|
|
|
255
290
|
"radix",
|
|
256
291
|
"require-await",
|
|
257
292
|
"require-atomic-updates",
|
|
293
|
+
"require-unicode-regexp",
|
|
258
294
|
"require-yield",
|
|
295
|
+
"sort-imports",
|
|
296
|
+
"sort-keys",
|
|
297
|
+
"sort-vars",
|
|
259
298
|
"spaced-comment",
|
|
299
|
+
"strict",
|
|
260
300
|
"symbol-description",
|
|
261
301
|
"unicode-bom",
|
|
262
302
|
"use-isnan",
|
|
@@ -264,6 +304,7 @@ const BUILTIN_RULE_IDS = [
|
|
|
264
304
|
"vars-on-top",
|
|
265
305
|
"wrap-iife",
|
|
266
306
|
"yoda",
|
|
307
|
+
"eslint-comments/no-restricted-disable",
|
|
267
308
|
"import/default",
|
|
268
309
|
"import/export",
|
|
269
310
|
"import/first",
|
|
@@ -277,22 +318,59 @@ const BUILTIN_RULE_IDS = [
|
|
|
277
318
|
"import/no-named-as-default-member",
|
|
278
319
|
"import/no-unresolved",
|
|
279
320
|
"import/no-self-import",
|
|
321
|
+
"jsx-a11y/alt-text",
|
|
322
|
+
"jsx-a11y/anchor-has-content",
|
|
280
323
|
"jsx-a11y/aria-props",
|
|
324
|
+
"jsx-a11y/aria-proptypes",
|
|
325
|
+
"jsx-a11y/aria-role",
|
|
326
|
+
"jsx-a11y/aria-unsupported-elements",
|
|
281
327
|
"jsx-a11y/iframe-has-title",
|
|
282
328
|
"jsx-a11y/img-redundant-alt",
|
|
283
329
|
"jsx-a11y/no-access-key",
|
|
330
|
+
"jsx-a11y/no-distracting-elements",
|
|
331
|
+
"jsx-a11y/role-has-required-aria-props",
|
|
332
|
+
"jsx-a11y/role-supports-aria-props",
|
|
333
|
+
"jsx-a11y/scope",
|
|
334
|
+
"react/button-has-type",
|
|
335
|
+
"react/default-props-match-prop-types",
|
|
336
|
+
"react/display-name",
|
|
337
|
+
"react/forbid-prop-types",
|
|
284
338
|
"react/jsx-boolean-value",
|
|
339
|
+
"react/jsx-filename-extension",
|
|
340
|
+
"react/jsx-key",
|
|
341
|
+
"react/jsx-no-bind",
|
|
285
342
|
"react/jsx-no-comment-textnodes",
|
|
286
343
|
"react/jsx-no-duplicate-props",
|
|
344
|
+
"react/jsx-no-undef",
|
|
345
|
+
"react/jsx-uses-react",
|
|
346
|
+
"react/jsx-uses-vars",
|
|
287
347
|
"react/jsx-no-target-blank",
|
|
288
348
|
"react/jsx-pascal-case",
|
|
349
|
+
"react/no-access-state-in-setstate",
|
|
350
|
+
"react/no-array-index-key",
|
|
351
|
+
"react/no-children-prop",
|
|
289
352
|
"react/no-danger",
|
|
353
|
+
"react/no-danger-with-children",
|
|
354
|
+
"react/no-deprecated",
|
|
290
355
|
"react/no-find-dom-node",
|
|
291
356
|
"react/no-is-mounted",
|
|
357
|
+
"react/no-multi-comp",
|
|
358
|
+
"react/no-redundant-should-component-update",
|
|
292
359
|
"react/no-render-return-value",
|
|
360
|
+
"react/no-string-refs",
|
|
361
|
+
"react/no-this-in-sfc",
|
|
362
|
+
"react/no-typos",
|
|
293
363
|
"react/no-unescaped-entities",
|
|
364
|
+
"react/no-unknown-property",
|
|
294
365
|
"react/no-unused-prop-types",
|
|
366
|
+
"react/no-unused-state",
|
|
367
|
+
"react/no-will-update-set-state",
|
|
368
|
+
"react/prefer-es6-class",
|
|
295
369
|
"react/prop-types",
|
|
370
|
+
"react/require-render-return",
|
|
371
|
+
"react/self-closing-comp",
|
|
372
|
+
"react/style-prop-object",
|
|
373
|
+
"react/void-dom-elements-no-children",
|
|
296
374
|
"react-hooks/rules-of-hooks",
|
|
297
375
|
"@typescript-eslint/adjacent-overload-signatures",
|
|
298
376
|
"@typescript-eslint/array-type",
|
|
@@ -316,6 +394,7 @@ const BUILTIN_RULE_IDS = [
|
|
|
316
394
|
"@typescript-eslint/no-extra-non-null-assertion",
|
|
317
395
|
"@typescript-eslint/no-inferrable-types",
|
|
318
396
|
"@typescript-eslint/no-invalid-void-type",
|
|
397
|
+
"@typescript-eslint/no-loop-func",
|
|
319
398
|
"@typescript-eslint/no-loss-of-precision",
|
|
320
399
|
"@typescript-eslint/no-misused-new",
|
|
321
400
|
"@typescript-eslint/no-namespace",
|
|
@@ -389,7 +468,7 @@ export class UtooLint {
|
|
|
389
468
|
this.options = { ...options };
|
|
390
469
|
}
|
|
391
470
|
|
|
392
|
-
async lintFiles(patterns
|
|
471
|
+
async lintFiles(patterns, options = {}) {
|
|
393
472
|
const mergedOptions = mergeLintOptions(this.options, options);
|
|
394
473
|
const customRuleConfig = [mergedOptions.baseConfig, mergedOptions.overrideConfig].filter(Boolean);
|
|
395
474
|
const customRuleFilterMap = customRuleMapForConfig(customRuleConfig, new Map());
|
|
@@ -2424,6 +2503,152 @@ export function run(args = [], options = {}) {
|
|
|
2424
2503
|
});
|
|
2425
2504
|
}
|
|
2426
2505
|
|
|
2506
|
+
const UTOO_LINT_CLI_VALUE_FLAGS = new Set(["--config", "-c", "--format", "-f", "--rules", "--threads"]);
|
|
2507
|
+
|
|
2508
|
+
function parseUtooLintCliArgs(args = []) {
|
|
2509
|
+
const values = normalizeStringArray(args, "args");
|
|
2510
|
+
const passthroughArgs = [];
|
|
2511
|
+
const targets = [];
|
|
2512
|
+
const options = {};
|
|
2513
|
+
let help = false;
|
|
2514
|
+
let versionFlag = false;
|
|
2515
|
+
|
|
2516
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
2517
|
+
const arg = values[index];
|
|
2518
|
+
if (arg === "--") {
|
|
2519
|
+
targets.push(...values.slice(index + 1));
|
|
2520
|
+
break;
|
|
2521
|
+
}
|
|
2522
|
+
if (arg === "--help" || arg === "-h") {
|
|
2523
|
+
help = true;
|
|
2524
|
+
passthroughArgs.push(arg);
|
|
2525
|
+
continue;
|
|
2526
|
+
}
|
|
2527
|
+
if (arg === "--version" || arg === "-v") {
|
|
2528
|
+
versionFlag = true;
|
|
2529
|
+
continue;
|
|
2530
|
+
}
|
|
2531
|
+
if (UTOO_LINT_CLI_VALUE_FLAGS.has(arg)) {
|
|
2532
|
+
const value = values[index + 1];
|
|
2533
|
+
if (!value) {
|
|
2534
|
+
throw new Error(`utoo-lint: ${arg} requires a value`);
|
|
2535
|
+
}
|
|
2536
|
+
appendCliOption(passthroughArgs, options, arg, value);
|
|
2537
|
+
index += 1;
|
|
2538
|
+
continue;
|
|
2539
|
+
}
|
|
2540
|
+
if (arg.startsWith("--config=")) {
|
|
2541
|
+
appendCliOption(passthroughArgs, options, "--config", arg.slice("--config=".length));
|
|
2542
|
+
continue;
|
|
2543
|
+
}
|
|
2544
|
+
if (arg.startsWith("--format=")) {
|
|
2545
|
+
appendCliOption(passthroughArgs, options, "--format", arg.slice("--format=".length));
|
|
2546
|
+
continue;
|
|
2547
|
+
}
|
|
2548
|
+
if (arg.startsWith("--rules=")) {
|
|
2549
|
+
appendCliOption(passthroughArgs, options, "--rules", arg.slice("--rules=".length));
|
|
2550
|
+
continue;
|
|
2551
|
+
}
|
|
2552
|
+
if (arg.startsWith("--threads=")) {
|
|
2553
|
+
appendCliOption(passthroughArgs, options, "--threads", arg.slice("--threads=".length));
|
|
2554
|
+
continue;
|
|
2555
|
+
}
|
|
2556
|
+
if (arg === "--no-config") {
|
|
2557
|
+
options.noConfig = true;
|
|
2558
|
+
delete options.config;
|
|
2559
|
+
continue;
|
|
2560
|
+
}
|
|
2561
|
+
if (arg === "--json") {
|
|
2562
|
+
passthroughArgs.push(arg);
|
|
2563
|
+
continue;
|
|
2564
|
+
}
|
|
2565
|
+
if (arg.startsWith("-")) {
|
|
2566
|
+
passthroughArgs.push(arg);
|
|
2567
|
+
continue;
|
|
2568
|
+
}
|
|
2569
|
+
targets.push(arg);
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
return { help, options, passthroughArgs, targets, version: versionFlag };
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
function appendCliOption(passthroughArgs, options, flag, value) {
|
|
2576
|
+
if (value == null || value === "") {
|
|
2577
|
+
throw new Error(`utoo-lint: ${flag} requires a value`);
|
|
2578
|
+
}
|
|
2579
|
+
switch (flag) {
|
|
2580
|
+
case "--config":
|
|
2581
|
+
case "-c":
|
|
2582
|
+
options.config = value;
|
|
2583
|
+
delete options.noConfig;
|
|
2584
|
+
return;
|
|
2585
|
+
case "--format":
|
|
2586
|
+
case "-f":
|
|
2587
|
+
options.format = value;
|
|
2588
|
+
return;
|
|
2589
|
+
case "--rules":
|
|
2590
|
+
options.rules = value;
|
|
2591
|
+
return;
|
|
2592
|
+
case "--threads":
|
|
2593
|
+
options.threads = value;
|
|
2594
|
+
return;
|
|
2595
|
+
default:
|
|
2596
|
+
passthroughArgs.push(`${flag}=${value}`);
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
function completedRunResult(status, stdout, stderr, options = {}) {
|
|
2601
|
+
const inherited = options.stdio === "inherit";
|
|
2602
|
+
if (inherited) {
|
|
2603
|
+
if (stdout) {
|
|
2604
|
+
process.stdout.write(stdout);
|
|
2605
|
+
}
|
|
2606
|
+
if (stderr) {
|
|
2607
|
+
process.stderr.write(stderr);
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2610
|
+
return {
|
|
2611
|
+
status,
|
|
2612
|
+
signal: null,
|
|
2613
|
+
error: undefined,
|
|
2614
|
+
stdout: inherited ? null : stdout,
|
|
2615
|
+
stderr: inherited ? null : stderr,
|
|
2616
|
+
output: [null, inherited ? null : stdout, inherited ? null : stderr],
|
|
2617
|
+
pid: 0
|
|
2618
|
+
};
|
|
2619
|
+
}
|
|
2620
|
+
|
|
2621
|
+
export function runCli(args = [], options = {}) {
|
|
2622
|
+
const parsed = parseUtooLintCliArgs(args);
|
|
2623
|
+
if (parsed.version) {
|
|
2624
|
+
return completedRunResult(0, `v${version}\n`, "", options);
|
|
2625
|
+
}
|
|
2626
|
+
if (parsed.help) {
|
|
2627
|
+
return run(parsed.passthroughArgs, options);
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
const cliOptions = {
|
|
2631
|
+
...options,
|
|
2632
|
+
...parsed.options
|
|
2633
|
+
};
|
|
2634
|
+
const targets = parsed.targets.length > 0 ? parsed.targets : defaultLintTargets(cliOptions);
|
|
2635
|
+
const ignoredDiagnostics = ignoredLintPathDiagnostics(targets, cliOptions);
|
|
2636
|
+
const lintPaths = filteredLintPaths(targets, cliOptions);
|
|
2637
|
+
if (lintPaths.length === 0) {
|
|
2638
|
+
return completedRunResult(ignoredDiagnostics.length > 0 ? 1 : 0, "", "", options);
|
|
2639
|
+
}
|
|
2640
|
+
|
|
2641
|
+
return withTemporaryConfig(cliOptions, (resolvedOptions) => {
|
|
2642
|
+
const cliArgs = buildRunCliArgs(lintPaths, resolvedOptions, parsed.passthroughArgs);
|
|
2643
|
+
return run(cliArgs, {
|
|
2644
|
+
...resolvedOptions,
|
|
2645
|
+
stdio: options.stdio,
|
|
2646
|
+
encoding: options.encoding,
|
|
2647
|
+
input: options.input
|
|
2648
|
+
});
|
|
2649
|
+
});
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2427
2652
|
export function runFishlint(args = [], options = {}) {
|
|
2428
2653
|
const cliArgs = normalizeStringArray(args, "args");
|
|
2429
2654
|
const env = options.env ? { ...process.env, ...options.env } : { ...process.env };
|
|
@@ -2636,14 +2861,15 @@ function booleanFlagValue(arg) {
|
|
|
2636
2861
|
return true;
|
|
2637
2862
|
}
|
|
2638
2863
|
|
|
2639
|
-
export function lintFiles(paths
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2864
|
+
export function lintFiles(paths, options = {}) {
|
|
2865
|
+
const targets = lintTargetsForInput(paths, options);
|
|
2866
|
+
const ignoredDiagnostics = ignoredLintPathDiagnostics(targets, options);
|
|
2867
|
+
const lintPaths = filteredLintPaths(targets, options);
|
|
2868
|
+
if (lintPaths.length === 0) {
|
|
2869
|
+
return { files: 0, filePaths: [], diagnostics: ignoredDiagnostics, exitCode: ignoredDiagnostics.length > 0 ? 1 : 0 };
|
|
2870
|
+
}
|
|
2646
2871
|
|
|
2872
|
+
return withTemporaryConfig(options, (resolvedOptions) => {
|
|
2647
2873
|
const cliArgs = buildLintArgs(lintPaths, resolvedOptions);
|
|
2648
2874
|
const result = run(cliArgs, { ...resolvedOptions, stdio: undefined, encoding: "utf8" });
|
|
2649
2875
|
|
|
@@ -2735,6 +2961,21 @@ export function lintText(code, options = {}) {
|
|
|
2735
2961
|
}
|
|
2736
2962
|
|
|
2737
2963
|
function buildLintArgs(paths, options) {
|
|
2964
|
+
return buildNativeLintArgs(paths, {
|
|
2965
|
+
...options,
|
|
2966
|
+
format: "json",
|
|
2967
|
+
extraArgs: options.extraArgs
|
|
2968
|
+
});
|
|
2969
|
+
}
|
|
2970
|
+
|
|
2971
|
+
function buildRunCliArgs(paths, options, passthroughArgs) {
|
|
2972
|
+
return buildNativeLintArgs(paths, {
|
|
2973
|
+
...options,
|
|
2974
|
+
extraArgs: passthroughArgs
|
|
2975
|
+
});
|
|
2976
|
+
}
|
|
2977
|
+
|
|
2978
|
+
function buildNativeLintArgs(paths, options) {
|
|
2738
2979
|
const cliArgs = [];
|
|
2739
2980
|
|
|
2740
2981
|
if (options.config) {
|
|
@@ -2753,7 +2994,9 @@ function buildLintArgs(paths, options) {
|
|
|
2753
2994
|
cliArgs.push(`--threads=${options.threads}`);
|
|
2754
2995
|
}
|
|
2755
2996
|
|
|
2756
|
-
|
|
2997
|
+
if (options.format) {
|
|
2998
|
+
cliArgs.push(`--format=${options.format}`);
|
|
2999
|
+
}
|
|
2757
3000
|
|
|
2758
3001
|
if (options.extraArgs) {
|
|
2759
3002
|
cliArgs.push(...normalizeStringArray(options.extraArgs, "extraArgs"));
|
|
@@ -2960,6 +3203,37 @@ function configDataFromFileConfig(options, filePath) {
|
|
|
2960
3203
|
return configDataFromConfig(config, filePath, options.cwd);
|
|
2961
3204
|
}
|
|
2962
3205
|
|
|
3206
|
+
function lintTargetsForInput(paths, options = {}) {
|
|
3207
|
+
if (paths == null) {
|
|
3208
|
+
return defaultLintTargets(options);
|
|
3209
|
+
}
|
|
3210
|
+
return normalizeStringArray(Array.isArray(paths) ? paths : [paths], "paths");
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3213
|
+
function defaultLintTargets(options = {}) {
|
|
3214
|
+
if (options.noConfig) {
|
|
3215
|
+
return ["."];
|
|
3216
|
+
}
|
|
3217
|
+
|
|
3218
|
+
const configPath = configPathForOptions(options);
|
|
3219
|
+
if (!configPath) {
|
|
3220
|
+
return ["."];
|
|
3221
|
+
}
|
|
3222
|
+
|
|
3223
|
+
const targets = filePatternsFromConfig(readConfig(configPath, options.cwd));
|
|
3224
|
+
return targets.length > 0 ? targets : ["."];
|
|
3225
|
+
}
|
|
3226
|
+
|
|
3227
|
+
function filePatternsFromConfig(config) {
|
|
3228
|
+
if (!config) {
|
|
3229
|
+
return [];
|
|
3230
|
+
}
|
|
3231
|
+
if (Array.isArray(config)) {
|
|
3232
|
+
return config.flatMap((entry) => filePatternsFromConfig(entry));
|
|
3233
|
+
}
|
|
3234
|
+
return normalizeConfigPatterns(config.files);
|
|
3235
|
+
}
|
|
3236
|
+
|
|
2963
3237
|
function configAppliesToFile(config, filePath, cwd) {
|
|
2964
3238
|
if (!filePath) {
|
|
2965
3239
|
return true;
|
|
@@ -2984,6 +3258,9 @@ function normalizeConfigPatterns(patterns) {
|
|
|
2984
3258
|
if (typeof value === "string") {
|
|
2985
3259
|
return [value];
|
|
2986
3260
|
}
|
|
3261
|
+
if (Array.isArray(value)) {
|
|
3262
|
+
return normalizeConfigPatterns(value);
|
|
3263
|
+
}
|
|
2987
3264
|
return [];
|
|
2988
3265
|
});
|
|
2989
3266
|
}
|
|
@@ -3665,6 +3942,9 @@ function matchesIgnorePattern(target, pattern) {
|
|
|
3665
3942
|
}
|
|
3666
3943
|
|
|
3667
3944
|
function matchesConfigFilePattern(target, pattern) {
|
|
3945
|
+
if (!hasGlobSyntax(pattern)) {
|
|
3946
|
+
return target === pattern || target.startsWith(`${pattern}/`) || target.endsWith(`/${pattern}`);
|
|
3947
|
+
}
|
|
3668
3948
|
const expression = new RegExp(`^${globPatternRegExpSource(pattern)}$`);
|
|
3669
3949
|
return expression.test(target);
|
|
3670
3950
|
}
|
package/lib/binary.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { existsSync } = require("node:fs");
|
|
1
|
+
const { chmodSync, existsSync, statSync } = require("node:fs");
|
|
2
2
|
const { join } = require("node:path");
|
|
3
3
|
|
|
4
4
|
const here = __dirname;
|
|
@@ -26,7 +26,7 @@ function resolveBinary(options = {}) {
|
|
|
26
26
|
|
|
27
27
|
if (env.UTOO_LINT_BIN) {
|
|
28
28
|
if (existsSync(env.UTOO_LINT_BIN)) {
|
|
29
|
-
return env.UTOO_LINT_BIN;
|
|
29
|
+
return ensureExecutable(env.UTOO_LINT_BIN, platform);
|
|
30
30
|
}
|
|
31
31
|
throw new Error(`utoo-lint: UTOO_LINT_BIN does not exist: ${env.UTOO_LINT_BIN}`);
|
|
32
32
|
}
|
|
@@ -47,7 +47,7 @@ function resolveBinary(options = {}) {
|
|
|
47
47
|
try {
|
|
48
48
|
const resolved = candidate();
|
|
49
49
|
if (existsSync(resolved)) {
|
|
50
|
-
return resolved;
|
|
50
|
+
return ensureExecutable(resolved, platform);
|
|
51
51
|
}
|
|
52
52
|
} catch {}
|
|
53
53
|
}
|
|
@@ -58,6 +58,21 @@ function resolveBinary(options = {}) {
|
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
function ensureExecutable(path, platform) {
|
|
62
|
+
if (platform === "win32") {
|
|
63
|
+
return path;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const mode = statSync(path).mode;
|
|
67
|
+
if ((mode & 0o111) === 0) {
|
|
68
|
+
chmodSync(path, mode | 0o755);
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
// Let spawn surface the actual filesystem error if chmod is not permitted.
|
|
72
|
+
}
|
|
73
|
+
return path;
|
|
74
|
+
}
|
|
75
|
+
|
|
61
76
|
module.exports = {
|
|
62
77
|
platformPackageName,
|
|
63
78
|
resolveBinary
|
package/lib/binary.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
1
|
+
import { chmodSync, existsSync, statSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -29,7 +29,7 @@ export function resolveBinary(options = {}) {
|
|
|
29
29
|
|
|
30
30
|
if (env.UTOO_LINT_BIN) {
|
|
31
31
|
if (existsSync(env.UTOO_LINT_BIN)) {
|
|
32
|
-
return env.UTOO_LINT_BIN;
|
|
32
|
+
return ensureExecutable(env.UTOO_LINT_BIN, platform);
|
|
33
33
|
}
|
|
34
34
|
throw new Error(`utoo-lint: UTOO_LINT_BIN does not exist: ${env.UTOO_LINT_BIN}`);
|
|
35
35
|
}
|
|
@@ -50,7 +50,7 @@ export function resolveBinary(options = {}) {
|
|
|
50
50
|
try {
|
|
51
51
|
const resolved = candidate();
|
|
52
52
|
if (existsSync(resolved)) {
|
|
53
|
-
return resolved;
|
|
53
|
+
return ensureExecutable(resolved, platform);
|
|
54
54
|
}
|
|
55
55
|
} catch {}
|
|
56
56
|
}
|
|
@@ -60,3 +60,18 @@ export function resolveBinary(options = {}) {
|
|
|
60
60
|
"Run `./scripts/package-npm.sh` from the repository root, or install the matching optional dependency."
|
|
61
61
|
);
|
|
62
62
|
}
|
|
63
|
+
|
|
64
|
+
function ensureExecutable(path, platform) {
|
|
65
|
+
if (platform === "win32") {
|
|
66
|
+
return path;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const mode = statSync(path).mode;
|
|
70
|
+
if ((mode & 0o111) === 0) {
|
|
71
|
+
chmodSync(path, mode | 0o755);
|
|
72
|
+
}
|
|
73
|
+
} catch {
|
|
74
|
+
// Let spawn surface the actual filesystem error if chmod is not permitted.
|
|
75
|
+
}
|
|
76
|
+
return path;
|
|
77
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utoo/lint",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Experimental JavaScript and TypeScript linter powered by Yuku",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -70,14 +70,14 @@
|
|
|
70
70
|
"use-at-your-own-risk.js"
|
|
71
71
|
],
|
|
72
72
|
"optionalDependencies": {
|
|
73
|
-
"@utoo/lint-darwin-arm64": "0.
|
|
74
|
-
"@utoo/lint-darwin-x64": "0.
|
|
75
|
-
"@utoo/lint-linux-arm64": "0.
|
|
76
|
-
"@utoo/lint-linux-x64": "0.
|
|
77
|
-
"@utoo/lint-win32-x64": "0.
|
|
73
|
+
"@utoo/lint-darwin-arm64": "0.1.3",
|
|
74
|
+
"@utoo/lint-darwin-x64": "0.1.3",
|
|
75
|
+
"@utoo/lint-linux-arm64": "0.1.3",
|
|
76
|
+
"@utoo/lint-linux-x64": "0.1.3",
|
|
77
|
+
"@utoo/lint-win32-x64": "0.1.3"
|
|
78
78
|
},
|
|
79
79
|
"publishConfig": {
|
|
80
80
|
"access": "public",
|
|
81
81
|
"registry": "https://registry.npmjs.org/"
|
|
82
82
|
}
|
|
83
|
-
}
|
|
83
|
+
}
|