@eslint-config-snapshot/cli 0.4.0 → 0.6.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 +22 -0
- package/dist/index.cjs +283 -52
- package/dist/index.js +284 -52
- package/package.json +2 -2
- package/src/index.ts +334 -55
- package/test/cli.integration.test.ts +8 -0
- package/test/cli.npm-isolated.integration.test.ts +27 -6
- package/test/cli.pnpm-isolated.integration.test.ts +27 -10
- package/test/cli.terminal.integration.test.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @eslint-config-snapshot/cli
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Release minor version with improved interactive CLI logging tone and richer runtime context reporting.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @eslint-config-snapshot/api@0.6.0
|
|
13
|
+
|
|
14
|
+
## 0.5.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- Add ESLint runtime version reporting by group in CLI summaries and improve pnpm/corepack isolated test resilience.
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
- @eslint-config-snapshot/api@0.5.0
|
|
24
|
+
|
|
3
25
|
## 0.4.0
|
|
4
26
|
|
|
5
27
|
### Minor Changes
|
package/dist/index.cjs
CHANGED
|
@@ -39,39 +39,53 @@ module.exports = __toCommonJS(index_exports);
|
|
|
39
39
|
var import_api = require("@eslint-config-snapshot/api");
|
|
40
40
|
var import_commander = require("commander");
|
|
41
41
|
var import_fast_glob = __toESM(require("fast-glob"), 1);
|
|
42
|
+
var import_node_fs = require("fs");
|
|
42
43
|
var import_promises = require("fs/promises");
|
|
43
44
|
var import_node_path = __toESM(require("path"), 1);
|
|
44
45
|
var import_node_readline = require("readline");
|
|
45
46
|
var SNAPSHOT_DIR = ".eslint-config-snapshot";
|
|
46
47
|
var UPDATE_HINT = "Tip: when you intentionally accept changes, run `eslint-config-snapshot --update` to refresh the baseline.\n";
|
|
48
|
+
var activeRunTimer;
|
|
49
|
+
var cachedCliVersion;
|
|
47
50
|
async function runCli(command, cwd, flags = []) {
|
|
48
51
|
const argv = command ? [command, ...flags] : [...flags];
|
|
49
52
|
return runArgv(argv, cwd);
|
|
50
53
|
}
|
|
51
54
|
async function runArgv(argv, cwd) {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
let actionCode;
|
|
57
|
-
const program = createProgram(cwd, (code) => {
|
|
58
|
-
actionCode = code;
|
|
59
|
-
});
|
|
55
|
+
const invocationLabel = resolveInvocationLabel(argv);
|
|
56
|
+
beginRunTimer(invocationLabel);
|
|
57
|
+
let exitCode = 1;
|
|
60
58
|
try {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return 0;
|
|
66
|
-
}
|
|
67
|
-
return error.exitCode;
|
|
59
|
+
const hasCommandToken = argv.some((token) => !token.startsWith("-"));
|
|
60
|
+
if (!hasCommandToken) {
|
|
61
|
+
exitCode = await runDefaultInvocation(argv, cwd);
|
|
62
|
+
return exitCode;
|
|
68
63
|
}
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
let actionCode;
|
|
65
|
+
const program = createProgram(cwd, (code) => {
|
|
66
|
+
actionCode = code;
|
|
67
|
+
});
|
|
68
|
+
try {
|
|
69
|
+
await program.parseAsync(argv, { from: "user" });
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (error instanceof import_commander.CommanderError) {
|
|
72
|
+
if (error.code === "commander.helpDisplayed") {
|
|
73
|
+
exitCode = 0;
|
|
74
|
+
return exitCode;
|
|
75
|
+
}
|
|
76
|
+
exitCode = error.exitCode;
|
|
77
|
+
return exitCode;
|
|
78
|
+
}
|
|
79
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
80
|
+
process.stderr.write(`${message}
|
|
71
81
|
`);
|
|
72
|
-
|
|
82
|
+
return 1;
|
|
83
|
+
}
|
|
84
|
+
exitCode = actionCode ?? 0;
|
|
85
|
+
return exitCode;
|
|
86
|
+
} finally {
|
|
87
|
+
endRunTimer(exitCode);
|
|
73
88
|
}
|
|
74
|
-
return actionCode ?? 0;
|
|
75
89
|
}
|
|
76
90
|
async function runDefaultInvocation(argv, cwd) {
|
|
77
91
|
const known = /* @__PURE__ */ new Set(["-u", "--update", "-h", "--help"]);
|
|
@@ -177,6 +191,13 @@ function parseInitPreset(value) {
|
|
|
177
191
|
}
|
|
178
192
|
async function executeCheck(cwd, format, defaultInvocation = false) {
|
|
179
193
|
const foundConfig = await (0, import_api.findConfigPath)(cwd);
|
|
194
|
+
const storedSnapshots = await loadStoredSnapshots(cwd);
|
|
195
|
+
if (format !== "status") {
|
|
196
|
+
writeRunContextHeader(cwd, defaultInvocation ? "check" : `check:${format}`, foundConfig?.path, storedSnapshots);
|
|
197
|
+
if (shouldShowRunLogs()) {
|
|
198
|
+
writeSubtleInfo("\u{1F50E} Checking current ESLint configuration...\n");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
180
201
|
if (!foundConfig) {
|
|
181
202
|
writeSubtleInfo(
|
|
182
203
|
"Tip: no explicit config found. Using safe built-in defaults. Run `eslint-config-snapshot init` to customize when needed.\n"
|
|
@@ -194,7 +215,6 @@ async function executeCheck(cwd, format, defaultInvocation = false) {
|
|
|
194
215
|
}
|
|
195
216
|
throw error;
|
|
196
217
|
}
|
|
197
|
-
const storedSnapshots = await loadStoredSnapshots(cwd);
|
|
198
218
|
if (storedSnapshots.size === 0) {
|
|
199
219
|
const summary = summarizeSnapshots(currentSnapshots);
|
|
200
220
|
process.stdout.write(
|
|
@@ -221,6 +241,7 @@ async function executeCheck(cwd, format, defaultInvocation = false) {
|
|
|
221
241
|
return 1;
|
|
222
242
|
}
|
|
223
243
|
const changes = compareSnapshotMaps(storedSnapshots, currentSnapshots);
|
|
244
|
+
const eslintVersionsByGroup = shouldShowRunLogs() ? await resolveGroupEslintVersions(cwd) : /* @__PURE__ */ new Map();
|
|
224
245
|
if (format === "status") {
|
|
225
246
|
if (changes.length === 0) {
|
|
226
247
|
process.stdout.write("clean\n");
|
|
@@ -233,6 +254,7 @@ async function executeCheck(cwd, format, defaultInvocation = false) {
|
|
|
233
254
|
if (format === "diff") {
|
|
234
255
|
if (changes.length === 0) {
|
|
235
256
|
process.stdout.write("Great news: no snapshot changes detected.\n");
|
|
257
|
+
writeEslintVersionSummary(eslintVersionsByGroup);
|
|
236
258
|
return 0;
|
|
237
259
|
}
|
|
238
260
|
for (const change of changes) {
|
|
@@ -242,10 +264,15 @@ async function executeCheck(cwd, format, defaultInvocation = false) {
|
|
|
242
264
|
writeSubtleInfo(UPDATE_HINT);
|
|
243
265
|
return 1;
|
|
244
266
|
}
|
|
245
|
-
return printWhatChanged(changes, currentSnapshots);
|
|
267
|
+
return printWhatChanged(changes, currentSnapshots, eslintVersionsByGroup);
|
|
246
268
|
}
|
|
247
269
|
async function executeUpdate(cwd, printSummary) {
|
|
248
270
|
const foundConfig = await (0, import_api.findConfigPath)(cwd);
|
|
271
|
+
const storedSnapshots = await loadStoredSnapshots(cwd);
|
|
272
|
+
writeRunContextHeader(cwd, "update", foundConfig?.path, storedSnapshots);
|
|
273
|
+
if (shouldShowRunLogs()) {
|
|
274
|
+
writeSubtleInfo("\u{1F50E} Checking current ESLint configuration...\n");
|
|
275
|
+
}
|
|
249
276
|
if (!foundConfig) {
|
|
250
277
|
writeSubtleInfo(
|
|
251
278
|
"Tip: no explicit config found. Using safe built-in defaults. Run `eslint-config-snapshot init` to customize when needed.\n"
|
|
@@ -267,16 +294,24 @@ async function executeUpdate(cwd, printSummary) {
|
|
|
267
294
|
if (printSummary) {
|
|
268
295
|
const summary = summarizeSnapshots(currentSnapshots);
|
|
269
296
|
const color = createColorizer();
|
|
297
|
+
const eslintVersionsByGroup = shouldShowRunLogs() ? await resolveGroupEslintVersions(cwd) : /* @__PURE__ */ new Map();
|
|
270
298
|
writeSectionTitle("Summary", color);
|
|
271
299
|
process.stdout.write(
|
|
272
300
|
`Baseline updated: ${summary.groups} groups, ${summary.rules} rules.
|
|
273
301
|
Severity mix: ${summary.error} errors, ${summary.warn} warnings, ${summary.off} off.
|
|
274
302
|
`
|
|
275
303
|
);
|
|
304
|
+
writeEslintVersionSummary(eslintVersionsByGroup);
|
|
276
305
|
}
|
|
277
306
|
return 0;
|
|
278
307
|
}
|
|
279
308
|
async function executePrint(cwd, format) {
|
|
309
|
+
const foundConfig = await (0, import_api.findConfigPath)(cwd);
|
|
310
|
+
const storedSnapshots = await loadStoredSnapshots(cwd);
|
|
311
|
+
writeRunContextHeader(cwd, `print:${format}`, foundConfig?.path, storedSnapshots);
|
|
312
|
+
if (shouldShowRunLogs()) {
|
|
313
|
+
writeSubtleInfo("\u{1F50E} Checking current ESLint configuration...\n");
|
|
314
|
+
}
|
|
280
315
|
const currentSnapshots = await computeCurrentSnapshots(cwd);
|
|
281
316
|
if (format === "short") {
|
|
282
317
|
process.stdout.write(formatShortPrint([...currentSnapshots.values()]));
|
|
@@ -291,6 +326,11 @@ async function executePrint(cwd, format) {
|
|
|
291
326
|
}
|
|
292
327
|
async function executeConfig(cwd, format) {
|
|
293
328
|
const foundConfig = await (0, import_api.findConfigPath)(cwd);
|
|
329
|
+
const storedSnapshots = await loadStoredSnapshots(cwd);
|
|
330
|
+
writeRunContextHeader(cwd, `config:${format}`, foundConfig?.path, storedSnapshots);
|
|
331
|
+
if (shouldShowRunLogs()) {
|
|
332
|
+
writeSubtleInfo("\u{1F50E} Resolving effective runtime configuration...\n");
|
|
333
|
+
}
|
|
294
334
|
const config = await (0, import_api.loadConfig)(cwd);
|
|
295
335
|
const resolved = await resolveWorkspaceAssignments(cwd, config);
|
|
296
336
|
const payload = {
|
|
@@ -476,8 +516,8 @@ ${JSON.stringify(configObject, null, 2)}
|
|
|
476
516
|
}
|
|
477
517
|
async function askInitPreferences() {
|
|
478
518
|
const { select } = await import("@inquirer/prompts");
|
|
479
|
-
const target = await askInitTarget(select);
|
|
480
|
-
const preset = await askInitPreset(select);
|
|
519
|
+
const target = await runPromptWithPausedTimer(() => askInitTarget(select));
|
|
520
|
+
const preset = await runPromptWithPausedTimer(() => askInitPreset(select));
|
|
481
521
|
return { target, preset };
|
|
482
522
|
}
|
|
483
523
|
async function askInitTarget(selectPrompt) {
|
|
@@ -500,8 +540,10 @@ async function askInitPreset(selectPrompt) {
|
|
|
500
540
|
});
|
|
501
541
|
}
|
|
502
542
|
function askQuestion(rl, prompt) {
|
|
543
|
+
pauseRunTimer();
|
|
503
544
|
return new Promise((resolve) => {
|
|
504
545
|
rl.question(prompt, (answer) => {
|
|
546
|
+
resumeRunTimer();
|
|
505
547
|
resolve(answer);
|
|
506
548
|
});
|
|
507
549
|
});
|
|
@@ -647,11 +689,13 @@ async function askRecommendedGroupAssignments(workspaces) {
|
|
|
647
689
|
'Recommended setup: default group "*" is a dynamic catch-all for every discovered workspace.\n'
|
|
648
690
|
);
|
|
649
691
|
process.stdout.write("Select only workspaces that should move to explicit static groups.\n");
|
|
650
|
-
const overrides = await
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
692
|
+
const overrides = await runPromptWithPausedTimer(
|
|
693
|
+
() => checkbox({
|
|
694
|
+
message: 'Choose exception workspaces (leave empty to keep all in default "*"):',
|
|
695
|
+
choices: workspaces.map((workspace) => ({ name: workspace, value: workspace })),
|
|
696
|
+
pageSize: Math.min(12, Math.max(4, workspaces.length))
|
|
697
|
+
})
|
|
698
|
+
);
|
|
655
699
|
const assignments = /* @__PURE__ */ new Map();
|
|
656
700
|
let nextGroup = 1;
|
|
657
701
|
for (const workspace of overrides) {
|
|
@@ -659,13 +703,15 @@ async function askRecommendedGroupAssignments(workspaces) {
|
|
|
659
703
|
while (usedGroups.includes(nextGroup)) {
|
|
660
704
|
nextGroup += 1;
|
|
661
705
|
}
|
|
662
|
-
const selected = await
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
706
|
+
const selected = await runPromptWithPausedTimer(
|
|
707
|
+
() => select({
|
|
708
|
+
message: `Select group for ${workspace}`,
|
|
709
|
+
choices: [
|
|
710
|
+
...usedGroups.map((group) => ({ name: `group-${group}`, value: group })),
|
|
711
|
+
{ name: `create new group (group-${nextGroup})`, value: "new" }
|
|
712
|
+
]
|
|
713
|
+
})
|
|
714
|
+
);
|
|
669
715
|
const groupNumber = selected === "new" ? nextGroup : selected;
|
|
670
716
|
assignments.set(workspace, groupNumber);
|
|
671
717
|
}
|
|
@@ -708,7 +754,7 @@ function isDirectCliExecution() {
|
|
|
708
754
|
if (isDirectCliExecution()) {
|
|
709
755
|
void main();
|
|
710
756
|
}
|
|
711
|
-
function printWhatChanged(changes, currentSnapshots) {
|
|
757
|
+
function printWhatChanged(changes, currentSnapshots, eslintVersionsByGroup) {
|
|
712
758
|
const color = createColorizer();
|
|
713
759
|
const currentSummary = summarizeSnapshots(currentSnapshots);
|
|
714
760
|
const changeSummary = summarizeChanges(changes);
|
|
@@ -720,6 +766,7 @@ function printWhatChanged(changes, currentSnapshots) {
|
|
|
720
766
|
- severity mix: ${currentSummary.error} errors, ${currentSummary.warn} warnings, ${currentSummary.off} off
|
|
721
767
|
`
|
|
722
768
|
);
|
|
769
|
+
writeEslintVersionSummary(eslintVersionsByGroup);
|
|
723
770
|
return 0;
|
|
724
771
|
}
|
|
725
772
|
process.stdout.write(color.red("Heads up: snapshot drift detected.\n"));
|
|
@@ -736,6 +783,8 @@ function printWhatChanged(changes, currentSnapshots) {
|
|
|
736
783
|
|
|
737
784
|
`
|
|
738
785
|
);
|
|
786
|
+
writeEslintVersionSummary(eslintVersionsByGroup);
|
|
787
|
+
process.stdout.write("\n");
|
|
739
788
|
writeSectionTitle("Changes", color);
|
|
740
789
|
for (const change of changes) {
|
|
741
790
|
process.stdout.write(color.bold(`group ${change.groupId}
|
|
@@ -771,22 +820,7 @@ function summarizeChanges(changes) {
|
|
|
771
820
|
return { introduced, removed, severity, options, workspace };
|
|
772
821
|
}
|
|
773
822
|
function summarizeSnapshots(snapshots) {
|
|
774
|
-
|
|
775
|
-
let error = 0;
|
|
776
|
-
let warn = 0;
|
|
777
|
-
let off = 0;
|
|
778
|
-
for (const snapshot of snapshots.values()) {
|
|
779
|
-
for (const entry of Object.values(snapshot.rules)) {
|
|
780
|
-
rules += 1;
|
|
781
|
-
if (entry[0] === "error") {
|
|
782
|
-
error += 1;
|
|
783
|
-
} else if (entry[0] === "warn") {
|
|
784
|
-
warn += 1;
|
|
785
|
-
} else {
|
|
786
|
-
off += 1;
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
}
|
|
823
|
+
const { rules, error, warn, off } = countRuleSeverities([...snapshots.values()].map((snapshot) => snapshot.rules));
|
|
790
824
|
return { groups: snapshots.size, rules, error, warn, off };
|
|
791
825
|
}
|
|
792
826
|
function decorateDiffLine(line, color) {
|
|
@@ -816,6 +850,203 @@ function writeSubtleInfo(text) {
|
|
|
816
850
|
const color = createColorizer();
|
|
817
851
|
process.stdout.write(color.dim(text));
|
|
818
852
|
}
|
|
853
|
+
function resolveInvocationLabel(argv) {
|
|
854
|
+
const commandToken = argv.find((entry) => !entry.startsWith("-"));
|
|
855
|
+
if (commandToken) {
|
|
856
|
+
return commandToken;
|
|
857
|
+
}
|
|
858
|
+
if (argv.includes("-u") || argv.includes("--update")) {
|
|
859
|
+
return "update";
|
|
860
|
+
}
|
|
861
|
+
if (argv.includes("-h") || argv.includes("--help")) {
|
|
862
|
+
return "help";
|
|
863
|
+
}
|
|
864
|
+
return "check";
|
|
865
|
+
}
|
|
866
|
+
function shouldShowRunLogs() {
|
|
867
|
+
if (process.env.ESLINT_CONFIG_SNAPSHOT_NO_PROGRESS === "1") {
|
|
868
|
+
return false;
|
|
869
|
+
}
|
|
870
|
+
return process.stdout.isTTY === true;
|
|
871
|
+
}
|
|
872
|
+
function beginRunTimer(label) {
|
|
873
|
+
if (!shouldShowRunLogs()) {
|
|
874
|
+
activeRunTimer = void 0;
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
activeRunTimer = {
|
|
878
|
+
label,
|
|
879
|
+
startedAtMs: Date.now(),
|
|
880
|
+
pausedMs: 0,
|
|
881
|
+
pauseStartedAtMs: void 0
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
function endRunTimer(exitCode) {
|
|
885
|
+
if (!activeRunTimer || !shouldShowRunLogs()) {
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
if (activeRunTimer.pauseStartedAtMs !== void 0) {
|
|
889
|
+
activeRunTimer.pausedMs += Date.now() - activeRunTimer.pauseStartedAtMs;
|
|
890
|
+
activeRunTimer.pauseStartedAtMs = void 0;
|
|
891
|
+
}
|
|
892
|
+
const elapsedMs = Math.max(0, Date.now() - activeRunTimer.startedAtMs - activeRunTimer.pausedMs);
|
|
893
|
+
const color = createColorizer();
|
|
894
|
+
const seconds = (elapsedMs / 1e3).toFixed(2);
|
|
895
|
+
if (exitCode === 0) {
|
|
896
|
+
writeSubtleInfo(`${color.green("\u2705")} Finished in ${seconds}s
|
|
897
|
+
`);
|
|
898
|
+
} else {
|
|
899
|
+
writeSubtleInfo(`${color.red("\u274C")} Finished in ${seconds}s
|
|
900
|
+
`);
|
|
901
|
+
}
|
|
902
|
+
activeRunTimer = void 0;
|
|
903
|
+
}
|
|
904
|
+
function pauseRunTimer() {
|
|
905
|
+
if (!activeRunTimer || activeRunTimer.pauseStartedAtMs !== void 0) {
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
activeRunTimer.pauseStartedAtMs = Date.now();
|
|
909
|
+
}
|
|
910
|
+
function resumeRunTimer() {
|
|
911
|
+
if (!activeRunTimer || activeRunTimer.pauseStartedAtMs === void 0) {
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
activeRunTimer.pausedMs += Date.now() - activeRunTimer.pauseStartedAtMs;
|
|
915
|
+
activeRunTimer.pauseStartedAtMs = void 0;
|
|
916
|
+
}
|
|
917
|
+
async function runPromptWithPausedTimer(prompt) {
|
|
918
|
+
pauseRunTimer();
|
|
919
|
+
try {
|
|
920
|
+
return await prompt();
|
|
921
|
+
} finally {
|
|
922
|
+
resumeRunTimer();
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
function readCliVersion() {
|
|
926
|
+
if (cachedCliVersion !== void 0) {
|
|
927
|
+
return cachedCliVersion;
|
|
928
|
+
}
|
|
929
|
+
const scriptPath = process.argv[1];
|
|
930
|
+
if (!scriptPath) {
|
|
931
|
+
cachedCliVersion = "unknown";
|
|
932
|
+
return cachedCliVersion;
|
|
933
|
+
}
|
|
934
|
+
let current = import_node_path.default.resolve(import_node_path.default.dirname(scriptPath));
|
|
935
|
+
while (true) {
|
|
936
|
+
const packageJsonPath = import_node_path.default.join(current, "package.json");
|
|
937
|
+
if ((0, import_node_fs.existsSync)(packageJsonPath)) {
|
|
938
|
+
try {
|
|
939
|
+
const raw = (0, import_node_fs.readFileSync)(packageJsonPath, "utf8");
|
|
940
|
+
const parsed = JSON.parse(raw);
|
|
941
|
+
cachedCliVersion = parsed.version ?? "unknown";
|
|
942
|
+
return cachedCliVersion;
|
|
943
|
+
} catch {
|
|
944
|
+
break;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
const parent = import_node_path.default.dirname(current);
|
|
948
|
+
if (parent === current) {
|
|
949
|
+
break;
|
|
950
|
+
}
|
|
951
|
+
current = parent;
|
|
952
|
+
}
|
|
953
|
+
cachedCliVersion = "unknown";
|
|
954
|
+
return cachedCliVersion;
|
|
955
|
+
}
|
|
956
|
+
function writeRunContextHeader(cwd, commandLabel, configPath, storedSnapshots) {
|
|
957
|
+
if (!shouldShowRunLogs()) {
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
const color = createColorizer();
|
|
961
|
+
process.stdout.write(color.bold(`\u2728 eslint-config-snapshot v${readCliVersion()}
|
|
962
|
+
`));
|
|
963
|
+
process.stdout.write(`\u{1F9ED} Command: ${commandLabel}
|
|
964
|
+
`);
|
|
965
|
+
process.stdout.write(`\u{1F4C1} Repository: ${cwd}
|
|
966
|
+
`);
|
|
967
|
+
process.stdout.write(`\u2699\uFE0F Config source: ${formatConfigSource(cwd, configPath)}
|
|
968
|
+
`);
|
|
969
|
+
process.stdout.write(`\u{1F5C2}\uFE0F Baseline: ${formatStoredSnapshotSummary(storedSnapshots)}
|
|
970
|
+
|
|
971
|
+
`);
|
|
972
|
+
}
|
|
973
|
+
function formatConfigSource(cwd, configPath) {
|
|
974
|
+
if (!configPath) {
|
|
975
|
+
return "built-in defaults";
|
|
976
|
+
}
|
|
977
|
+
const rel = (0, import_api.normalizePath)(import_node_path.default.relative(cwd, configPath));
|
|
978
|
+
if (import_node_path.default.basename(configPath) === "package.json") {
|
|
979
|
+
return `${rel} (eslint-config-snapshot field)`;
|
|
980
|
+
}
|
|
981
|
+
return rel;
|
|
982
|
+
}
|
|
983
|
+
function formatStoredSnapshotSummary(storedSnapshots) {
|
|
984
|
+
if (storedSnapshots.size === 0) {
|
|
985
|
+
return "none";
|
|
986
|
+
}
|
|
987
|
+
const summary = summarizeStoredSnapshots(storedSnapshots);
|
|
988
|
+
return `${summary.groups} groups, ${summary.rules} rules (severity mix: ${summary.error} errors, ${summary.warn} warnings, ${summary.off} off)`;
|
|
989
|
+
}
|
|
990
|
+
async function resolveGroupEslintVersions(cwd) {
|
|
991
|
+
const config = await (0, import_api.loadConfig)(cwd);
|
|
992
|
+
const { discovery, assignments } = await resolveWorkspaceAssignments(cwd, config);
|
|
993
|
+
const result = /* @__PURE__ */ new Map();
|
|
994
|
+
for (const group of assignments) {
|
|
995
|
+
const versions = /* @__PURE__ */ new Set();
|
|
996
|
+
for (const workspaceRel of group.workspaces) {
|
|
997
|
+
const workspaceAbs = import_node_path.default.resolve(discovery.rootAbs, workspaceRel);
|
|
998
|
+
versions.add((0, import_api.resolveEslintVersionForWorkspace)(workspaceAbs));
|
|
999
|
+
}
|
|
1000
|
+
result.set(group.name, [...versions].sort((a, b) => a.localeCompare(b)));
|
|
1001
|
+
}
|
|
1002
|
+
return result;
|
|
1003
|
+
}
|
|
1004
|
+
function writeEslintVersionSummary(eslintVersionsByGroup) {
|
|
1005
|
+
if (!shouldShowRunLogs() || eslintVersionsByGroup.size === 0) {
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
1008
|
+
const allVersions = /* @__PURE__ */ new Set();
|
|
1009
|
+
for (const versions of eslintVersionsByGroup.values()) {
|
|
1010
|
+
for (const version of versions) {
|
|
1011
|
+
allVersions.add(version);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
const sortedAllVersions = [...allVersions].sort((a, b) => a.localeCompare(b));
|
|
1015
|
+
if (sortedAllVersions.length === 1) {
|
|
1016
|
+
process.stdout.write(`- eslint runtime: ${sortedAllVersions[0]} (all groups)
|
|
1017
|
+
`);
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
process.stdout.write("- eslint runtime by group:\n");
|
|
1021
|
+
const sortedEntries = [...eslintVersionsByGroup.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
1022
|
+
for (const [groupName, versions] of sortedEntries) {
|
|
1023
|
+
process.stdout.write(` - ${groupName}: ${versions.join(", ")}
|
|
1024
|
+
`);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
function summarizeStoredSnapshots(snapshots) {
|
|
1028
|
+
const { rules, error, warn, off } = countRuleSeverities([...snapshots.values()].map((snapshot) => snapshot.rules));
|
|
1029
|
+
return { groups: snapshots.size, rules, error, warn, off };
|
|
1030
|
+
}
|
|
1031
|
+
function countRuleSeverities(ruleObjects) {
|
|
1032
|
+
let rules = 0;
|
|
1033
|
+
let error = 0;
|
|
1034
|
+
let warn = 0;
|
|
1035
|
+
let off = 0;
|
|
1036
|
+
for (const rulesObject of ruleObjects) {
|
|
1037
|
+
for (const entry of Object.values(rulesObject)) {
|
|
1038
|
+
rules += 1;
|
|
1039
|
+
if (entry[0] === "error") {
|
|
1040
|
+
error += 1;
|
|
1041
|
+
} else if (entry[0] === "warn") {
|
|
1042
|
+
warn += 1;
|
|
1043
|
+
} else {
|
|
1044
|
+
off += 1;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
return { rules, error, warn, off };
|
|
1049
|
+
}
|
|
819
1050
|
function formatShortPrint(snapshots) {
|
|
820
1051
|
const lines = [];
|
|
821
1052
|
const sorted = [...snapshots].sort((a, b) => a.groupId.localeCompare(b.groupId));
|