@utoo/lint 0.1.2 → 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/README.md +8 -2
- package/bin/utoo-lint.js +3 -6
- package/index.cjs +211 -9
- package/index.d.ts +2 -0
- package/index.js +210 -9
- package/lib/binary.cjs +18 -3
- package/lib/binary.js +18 -3
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -18,8 +18,10 @@ Run the linter with:
|
|
|
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
|
|
|
@@ -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/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
|
@@ -465,7 +465,7 @@ class UtooLint {
|
|
|
465
465
|
this.options = { ...options };
|
|
466
466
|
}
|
|
467
467
|
|
|
468
|
-
async lintFiles(patterns
|
|
468
|
+
async lintFiles(patterns, options = {}) {
|
|
469
469
|
const mergedOptions = mergeLintOptions(this.options, options);
|
|
470
470
|
const customRuleConfig = [mergedOptions.baseConfig, mergedOptions.overrideConfig].filter(Boolean);
|
|
471
471
|
const customRuleFilterMap = customRuleMapForConfig(customRuleConfig, new Map());
|
|
@@ -670,6 +670,152 @@ function run(args = [], options = {}) {
|
|
|
670
670
|
});
|
|
671
671
|
}
|
|
672
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
|
+
|
|
673
819
|
function runFishlint(args = [], options = {}) {
|
|
674
820
|
const cliArgs = normalizeStringArray(args, "args");
|
|
675
821
|
const env = options.env ? { ...process.env, ...options.env } : { ...process.env };
|
|
@@ -882,14 +1028,15 @@ function booleanFlagValue(arg) {
|
|
|
882
1028
|
return true;
|
|
883
1029
|
}
|
|
884
1030
|
|
|
885
|
-
function lintFiles(paths
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
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
|
+
}
|
|
892
1038
|
|
|
1039
|
+
return withTemporaryConfig(options, (resolvedOptions) => {
|
|
893
1040
|
const cliArgs = buildLintArgs(lintPaths, resolvedOptions);
|
|
894
1041
|
const result = run(cliArgs, { ...resolvedOptions, stdio: undefined, encoding: "utf8" });
|
|
895
1042
|
|
|
@@ -981,6 +1128,21 @@ function lintText(code, options = {}) {
|
|
|
981
1128
|
}
|
|
982
1129
|
|
|
983
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) {
|
|
984
1146
|
const cliArgs = [];
|
|
985
1147
|
|
|
986
1148
|
if (options.config) {
|
|
@@ -999,7 +1161,9 @@ function buildLintArgs(paths, options) {
|
|
|
999
1161
|
cliArgs.push(`--threads=${options.threads}`);
|
|
1000
1162
|
}
|
|
1001
1163
|
|
|
1002
|
-
|
|
1164
|
+
if (options.format) {
|
|
1165
|
+
cliArgs.push(`--format=${options.format}`);
|
|
1166
|
+
}
|
|
1003
1167
|
|
|
1004
1168
|
if (options.extraArgs) {
|
|
1005
1169
|
cliArgs.push(...normalizeStringArray(options.extraArgs, "extraArgs"));
|
|
@@ -1206,6 +1370,37 @@ function configDataFromFileConfig(options, filePath) {
|
|
|
1206
1370
|
return configDataFromConfig(config, filePath, options.cwd);
|
|
1207
1371
|
}
|
|
1208
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
|
+
|
|
1209
1404
|
function configAppliesToFile(config, filePath, cwd) {
|
|
1210
1405
|
if (!filePath) {
|
|
1211
1406
|
return true;
|
|
@@ -1230,6 +1425,9 @@ function normalizeConfigPatterns(patterns) {
|
|
|
1230
1425
|
if (typeof value === "string") {
|
|
1231
1426
|
return [value];
|
|
1232
1427
|
}
|
|
1428
|
+
if (Array.isArray(value)) {
|
|
1429
|
+
return normalizeConfigPatterns(value);
|
|
1430
|
+
}
|
|
1233
1431
|
return [];
|
|
1234
1432
|
});
|
|
1235
1433
|
}
|
|
@@ -3741,6 +3939,9 @@ function matchesIgnorePattern(target, pattern) {
|
|
|
3741
3939
|
}
|
|
3742
3940
|
|
|
3743
3941
|
function matchesConfigFilePattern(target, pattern) {
|
|
3942
|
+
if (!hasGlobSyntax(pattern)) {
|
|
3943
|
+
return target === pattern || target.startsWith(`${pattern}/`) || target.endsWith(`/${pattern}`);
|
|
3944
|
+
}
|
|
3744
3945
|
const expression = new RegExp(`^${globPatternRegExpSource(pattern)}$`);
|
|
3745
3946
|
return expression.test(target);
|
|
3746
3947
|
}
|
|
@@ -4107,6 +4308,7 @@ module.exports = {
|
|
|
4107
4308
|
platformPackageName,
|
|
4108
4309
|
resolveBinary,
|
|
4109
4310
|
run,
|
|
4311
|
+
runCli,
|
|
4110
4312
|
runFishlint,
|
|
4111
4313
|
translateFishlintArgs,
|
|
4112
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
|
@@ -468,7 +468,7 @@ export class UtooLint {
|
|
|
468
468
|
this.options = { ...options };
|
|
469
469
|
}
|
|
470
470
|
|
|
471
|
-
async lintFiles(patterns
|
|
471
|
+
async lintFiles(patterns, options = {}) {
|
|
472
472
|
const mergedOptions = mergeLintOptions(this.options, options);
|
|
473
473
|
const customRuleConfig = [mergedOptions.baseConfig, mergedOptions.overrideConfig].filter(Boolean);
|
|
474
474
|
const customRuleFilterMap = customRuleMapForConfig(customRuleConfig, new Map());
|
|
@@ -2503,6 +2503,152 @@ export function run(args = [], options = {}) {
|
|
|
2503
2503
|
});
|
|
2504
2504
|
}
|
|
2505
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
|
+
|
|
2506
2652
|
export function runFishlint(args = [], options = {}) {
|
|
2507
2653
|
const cliArgs = normalizeStringArray(args, "args");
|
|
2508
2654
|
const env = options.env ? { ...process.env, ...options.env } : { ...process.env };
|
|
@@ -2715,14 +2861,15 @@ function booleanFlagValue(arg) {
|
|
|
2715
2861
|
return true;
|
|
2716
2862
|
}
|
|
2717
2863
|
|
|
2718
|
-
export function lintFiles(paths
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
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
|
+
}
|
|
2725
2871
|
|
|
2872
|
+
return withTemporaryConfig(options, (resolvedOptions) => {
|
|
2726
2873
|
const cliArgs = buildLintArgs(lintPaths, resolvedOptions);
|
|
2727
2874
|
const result = run(cliArgs, { ...resolvedOptions, stdio: undefined, encoding: "utf8" });
|
|
2728
2875
|
|
|
@@ -2814,6 +2961,21 @@ export function lintText(code, options = {}) {
|
|
|
2814
2961
|
}
|
|
2815
2962
|
|
|
2816
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) {
|
|
2817
2979
|
const cliArgs = [];
|
|
2818
2980
|
|
|
2819
2981
|
if (options.config) {
|
|
@@ -2832,7 +2994,9 @@ function buildLintArgs(paths, options) {
|
|
|
2832
2994
|
cliArgs.push(`--threads=${options.threads}`);
|
|
2833
2995
|
}
|
|
2834
2996
|
|
|
2835
|
-
|
|
2997
|
+
if (options.format) {
|
|
2998
|
+
cliArgs.push(`--format=${options.format}`);
|
|
2999
|
+
}
|
|
2836
3000
|
|
|
2837
3001
|
if (options.extraArgs) {
|
|
2838
3002
|
cliArgs.push(...normalizeStringArray(options.extraArgs, "extraArgs"));
|
|
@@ -3039,6 +3203,37 @@ function configDataFromFileConfig(options, filePath) {
|
|
|
3039
3203
|
return configDataFromConfig(config, filePath, options.cwd);
|
|
3040
3204
|
}
|
|
3041
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
|
+
|
|
3042
3237
|
function configAppliesToFile(config, filePath, cwd) {
|
|
3043
3238
|
if (!filePath) {
|
|
3044
3239
|
return true;
|
|
@@ -3063,6 +3258,9 @@ function normalizeConfigPatterns(patterns) {
|
|
|
3063
3258
|
if (typeof value === "string") {
|
|
3064
3259
|
return [value];
|
|
3065
3260
|
}
|
|
3261
|
+
if (Array.isArray(value)) {
|
|
3262
|
+
return normalizeConfigPatterns(value);
|
|
3263
|
+
}
|
|
3066
3264
|
return [];
|
|
3067
3265
|
});
|
|
3068
3266
|
}
|
|
@@ -3744,6 +3942,9 @@ function matchesIgnorePattern(target, pattern) {
|
|
|
3744
3942
|
}
|
|
3745
3943
|
|
|
3746
3944
|
function matchesConfigFilePattern(target, pattern) {
|
|
3945
|
+
if (!hasGlobSyntax(pattern)) {
|
|
3946
|
+
return target === pattern || target.startsWith(`${pattern}/`) || target.endsWith(`/${pattern}`);
|
|
3947
|
+
}
|
|
3747
3948
|
const expression = new RegExp(`^${globPatternRegExpSource(pattern)}$`);
|
|
3748
3949
|
return expression.test(target);
|
|
3749
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.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Experimental JavaScript and TypeScript linter powered by Yuku",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -70,11 +70,11 @@
|
|
|
70
70
|
"use-at-your-own-risk.js"
|
|
71
71
|
],
|
|
72
72
|
"optionalDependencies": {
|
|
73
|
-
"@utoo/lint-darwin-arm64": "0.1.
|
|
74
|
-
"@utoo/lint-darwin-x64": "0.1.
|
|
75
|
-
"@utoo/lint-linux-arm64": "0.1.
|
|
76
|
-
"@utoo/lint-linux-x64": "0.1.
|
|
77
|
-
"@utoo/lint-win32-x64": "0.1.
|
|
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",
|