@eslint-config-snapshot/cli 0.3.2 → 0.4.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 +11 -0
- package/dist/index.cjs +39 -19
- package/dist/index.js +40 -20
- package/package.json +2 -2
- package/src/index.ts +39 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @eslint-config-snapshot/cli
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Minor release with improved CLI output consistency and faster workspace extraction using ESLint API fallback strategy.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @eslint-config-snapshot/api@0.4.0
|
|
13
|
+
|
|
3
14
|
## 0.3.2
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -266,8 +266,13 @@ async function executeUpdate(cwd, printSummary) {
|
|
|
266
266
|
await writeSnapshots(cwd, currentSnapshots);
|
|
267
267
|
if (printSummary) {
|
|
268
268
|
const summary = summarizeSnapshots(currentSnapshots);
|
|
269
|
-
|
|
270
|
-
|
|
269
|
+
const color = createColorizer();
|
|
270
|
+
writeSectionTitle("Summary", color);
|
|
271
|
+
process.stdout.write(
|
|
272
|
+
`Baseline updated: ${summary.groups} groups, ${summary.rules} rules.
|
|
273
|
+
Severity mix: ${summary.error} errors, ${summary.warn} warnings, ${summary.off} off.
|
|
274
|
+
`
|
|
275
|
+
);
|
|
271
276
|
}
|
|
272
277
|
return 0;
|
|
273
278
|
}
|
|
@@ -317,19 +322,20 @@ async function computeCurrentSnapshots(cwd) {
|
|
|
317
322
|
const sampled = await (0, import_api.sampleWorkspaceFiles)(workspaceAbs, config.sampling);
|
|
318
323
|
let extractedCount = 0;
|
|
319
324
|
let lastExtractionError;
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
325
|
+
const sampledAbs = sampled.map((sampledRel) => import_node_path.default.resolve(workspaceAbs, sampledRel));
|
|
326
|
+
const results = await (0, import_api.extractRulesForWorkspaceSamples)(workspaceAbs, sampledAbs);
|
|
327
|
+
for (const result of results) {
|
|
328
|
+
if (result.rules) {
|
|
329
|
+
extractedForGroup.push(result.rules);
|
|
324
330
|
extractedCount += 1;
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
throw error;
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
const message = result.error instanceof Error ? result.error.message : String(result.error);
|
|
334
|
+
if (isRecoverableExtractionError(message)) {
|
|
335
|
+
lastExtractionError = message;
|
|
336
|
+
continue;
|
|
332
337
|
}
|
|
338
|
+
throw result.error ?? new Error(message);
|
|
333
339
|
}
|
|
334
340
|
if (extractedCount === 0) {
|
|
335
341
|
const context = lastExtractionError ? ` Last error: ${lastExtractionError}` : "";
|
|
@@ -343,6 +349,9 @@ async function computeCurrentSnapshots(cwd) {
|
|
|
343
349
|
}
|
|
344
350
|
return snapshots;
|
|
345
351
|
}
|
|
352
|
+
function isRecoverableExtractionError(message) {
|
|
353
|
+
return message.startsWith("Invalid JSON from eslint --print-config") || message.startsWith("Empty ESLint print-config output") || message.includes("File ignored because of a matching ignore pattern") || message.includes("File ignored by default");
|
|
354
|
+
}
|
|
346
355
|
async function resolveWorkspaceAssignments(cwd, config) {
|
|
347
356
|
const discovery = await (0, import_api.discoverWorkspaces)({ cwd, workspaceInput: config.workspaceInput });
|
|
348
357
|
const assignments = config.grouping.mode === "standalone" ? discovery.workspacesRel.map((workspace) => ({ name: workspace, workspaces: [workspace] })) : (0, import_api.assignGroupsByMatch)(discovery.workspacesRel, config.grouping.groups ?? [{ name: "default", match: ["**/*"] }]);
|
|
@@ -705,22 +714,29 @@ function printWhatChanged(changes, currentSnapshots) {
|
|
|
705
714
|
const changeSummary = summarizeChanges(changes);
|
|
706
715
|
if (changes.length === 0) {
|
|
707
716
|
process.stdout.write(color.green("Great news: no snapshot drift detected.\n"));
|
|
717
|
+
writeSectionTitle("Summary", color);
|
|
708
718
|
process.stdout.write(
|
|
709
|
-
|
|
719
|
+
`- baseline: ${currentSummary.groups} groups, ${currentSummary.rules} rules
|
|
720
|
+
- severity mix: ${currentSummary.error} errors, ${currentSummary.warn} warnings, ${currentSummary.off} off
|
|
710
721
|
`
|
|
711
722
|
);
|
|
712
723
|
return 0;
|
|
713
724
|
}
|
|
714
725
|
process.stdout.write(color.red("Heads up: snapshot drift detected.\n"));
|
|
726
|
+
writeSectionTitle("Summary", color);
|
|
715
727
|
process.stdout.write(
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
728
|
+
`- changed groups: ${changes.length}
|
|
729
|
+
- introduced rules: ${changeSummary.introduced}
|
|
730
|
+
- removed rules: ${changeSummary.removed}
|
|
731
|
+
- severity changes: ${changeSummary.severity}
|
|
732
|
+
- options changes: ${changeSummary.options}
|
|
733
|
+
- workspace membership changes: ${changeSummary.workspace}
|
|
734
|
+
- current baseline: ${currentSummary.groups} groups, ${currentSummary.rules} rules
|
|
735
|
+
- current severity mix: ${currentSummary.error} errors, ${currentSummary.warn} warnings, ${currentSummary.off} off
|
|
721
736
|
|
|
722
737
|
`
|
|
723
738
|
);
|
|
739
|
+
writeSectionTitle("Changes", color);
|
|
724
740
|
for (const change of changes) {
|
|
725
741
|
process.stdout.write(color.bold(`group ${change.groupId}
|
|
726
742
|
`));
|
|
@@ -735,6 +751,10 @@ function printWhatChanged(changes, currentSnapshots) {
|
|
|
735
751
|
writeSubtleInfo(UPDATE_HINT);
|
|
736
752
|
return 1;
|
|
737
753
|
}
|
|
754
|
+
function writeSectionTitle(title, color) {
|
|
755
|
+
process.stdout.write(`${color.bold(title)}
|
|
756
|
+
`);
|
|
757
|
+
}
|
|
738
758
|
function summarizeChanges(changes) {
|
|
739
759
|
let introduced = 0;
|
|
740
760
|
let removed = 0;
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
buildSnapshot,
|
|
8
8
|
diffSnapshots,
|
|
9
9
|
discoverWorkspaces,
|
|
10
|
-
|
|
10
|
+
extractRulesForWorkspaceSamples,
|
|
11
11
|
findConfigPath,
|
|
12
12
|
getConfigScaffold,
|
|
13
13
|
hasDiff,
|
|
@@ -246,8 +246,13 @@ async function executeUpdate(cwd, printSummary) {
|
|
|
246
246
|
await writeSnapshots(cwd, currentSnapshots);
|
|
247
247
|
if (printSummary) {
|
|
248
248
|
const summary = summarizeSnapshots(currentSnapshots);
|
|
249
|
-
|
|
250
|
-
|
|
249
|
+
const color = createColorizer();
|
|
250
|
+
writeSectionTitle("Summary", color);
|
|
251
|
+
process.stdout.write(
|
|
252
|
+
`Baseline updated: ${summary.groups} groups, ${summary.rules} rules.
|
|
253
|
+
Severity mix: ${summary.error} errors, ${summary.warn} warnings, ${summary.off} off.
|
|
254
|
+
`
|
|
255
|
+
);
|
|
251
256
|
}
|
|
252
257
|
return 0;
|
|
253
258
|
}
|
|
@@ -297,19 +302,20 @@ async function computeCurrentSnapshots(cwd) {
|
|
|
297
302
|
const sampled = await sampleWorkspaceFiles(workspaceAbs, config.sampling);
|
|
298
303
|
let extractedCount = 0;
|
|
299
304
|
let lastExtractionError;
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
305
|
+
const sampledAbs = sampled.map((sampledRel) => path.resolve(workspaceAbs, sampledRel));
|
|
306
|
+
const results = await extractRulesForWorkspaceSamples(workspaceAbs, sampledAbs);
|
|
307
|
+
for (const result of results) {
|
|
308
|
+
if (result.rules) {
|
|
309
|
+
extractedForGroup.push(result.rules);
|
|
304
310
|
extractedCount += 1;
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
throw error;
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
const message = result.error instanceof Error ? result.error.message : String(result.error);
|
|
314
|
+
if (isRecoverableExtractionError(message)) {
|
|
315
|
+
lastExtractionError = message;
|
|
316
|
+
continue;
|
|
312
317
|
}
|
|
318
|
+
throw result.error ?? new Error(message);
|
|
313
319
|
}
|
|
314
320
|
if (extractedCount === 0) {
|
|
315
321
|
const context = lastExtractionError ? ` Last error: ${lastExtractionError}` : "";
|
|
@@ -323,6 +329,9 @@ async function computeCurrentSnapshots(cwd) {
|
|
|
323
329
|
}
|
|
324
330
|
return snapshots;
|
|
325
331
|
}
|
|
332
|
+
function isRecoverableExtractionError(message) {
|
|
333
|
+
return message.startsWith("Invalid JSON from eslint --print-config") || message.startsWith("Empty ESLint print-config output") || message.includes("File ignored because of a matching ignore pattern") || message.includes("File ignored by default");
|
|
334
|
+
}
|
|
326
335
|
async function resolveWorkspaceAssignments(cwd, config) {
|
|
327
336
|
const discovery = await discoverWorkspaces({ cwd, workspaceInput: config.workspaceInput });
|
|
328
337
|
const assignments = config.grouping.mode === "standalone" ? discovery.workspacesRel.map((workspace) => ({ name: workspace, workspaces: [workspace] })) : assignGroupsByMatch(discovery.workspacesRel, config.grouping.groups ?? [{ name: "default", match: ["**/*"] }]);
|
|
@@ -685,22 +694,29 @@ function printWhatChanged(changes, currentSnapshots) {
|
|
|
685
694
|
const changeSummary = summarizeChanges(changes);
|
|
686
695
|
if (changes.length === 0) {
|
|
687
696
|
process.stdout.write(color.green("Great news: no snapshot drift detected.\n"));
|
|
697
|
+
writeSectionTitle("Summary", color);
|
|
688
698
|
process.stdout.write(
|
|
689
|
-
|
|
699
|
+
`- baseline: ${currentSummary.groups} groups, ${currentSummary.rules} rules
|
|
700
|
+
- severity mix: ${currentSummary.error} errors, ${currentSummary.warn} warnings, ${currentSummary.off} off
|
|
690
701
|
`
|
|
691
702
|
);
|
|
692
703
|
return 0;
|
|
693
704
|
}
|
|
694
705
|
process.stdout.write(color.red("Heads up: snapshot drift detected.\n"));
|
|
706
|
+
writeSectionTitle("Summary", color);
|
|
695
707
|
process.stdout.write(
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
708
|
+
`- changed groups: ${changes.length}
|
|
709
|
+
- introduced rules: ${changeSummary.introduced}
|
|
710
|
+
- removed rules: ${changeSummary.removed}
|
|
711
|
+
- severity changes: ${changeSummary.severity}
|
|
712
|
+
- options changes: ${changeSummary.options}
|
|
713
|
+
- workspace membership changes: ${changeSummary.workspace}
|
|
714
|
+
- current baseline: ${currentSummary.groups} groups, ${currentSummary.rules} rules
|
|
715
|
+
- current severity mix: ${currentSummary.error} errors, ${currentSummary.warn} warnings, ${currentSummary.off} off
|
|
701
716
|
|
|
702
717
|
`
|
|
703
718
|
);
|
|
719
|
+
writeSectionTitle("Changes", color);
|
|
704
720
|
for (const change of changes) {
|
|
705
721
|
process.stdout.write(color.bold(`group ${change.groupId}
|
|
706
722
|
`));
|
|
@@ -715,6 +731,10 @@ function printWhatChanged(changes, currentSnapshots) {
|
|
|
715
731
|
writeSubtleInfo(UPDATE_HINT);
|
|
716
732
|
return 1;
|
|
717
733
|
}
|
|
734
|
+
function writeSectionTitle(title, color) {
|
|
735
|
+
process.stdout.write(`${color.bold(title)}
|
|
736
|
+
`);
|
|
737
|
+
}
|
|
718
738
|
function summarizeChanges(changes) {
|
|
719
739
|
let introduced = 0;
|
|
720
740
|
let removed = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-config-snapshot/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -30,6 +30,6 @@
|
|
|
30
30
|
"@inquirer/prompts": "^8.2.0",
|
|
31
31
|
"commander": "^14.0.3",
|
|
32
32
|
"fast-glob": "^3.3.3",
|
|
33
|
-
"@eslint-config-snapshot/api": "0.
|
|
33
|
+
"@eslint-config-snapshot/api": "0.4.0"
|
|
34
34
|
}
|
|
35
35
|
}
|
package/src/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
buildSnapshot,
|
|
6
6
|
diffSnapshots,
|
|
7
7
|
discoverWorkspaces,
|
|
8
|
-
|
|
8
|
+
extractRulesForWorkspaceSamples,
|
|
9
9
|
findConfigPath,
|
|
10
10
|
getConfigScaffold,
|
|
11
11
|
hasDiff,
|
|
@@ -340,7 +340,11 @@ async function executeUpdate(cwd: string, printSummary: boolean): Promise<number
|
|
|
340
340
|
|
|
341
341
|
if (printSummary) {
|
|
342
342
|
const summary = summarizeSnapshots(currentSnapshots)
|
|
343
|
-
|
|
343
|
+
const color = createColorizer()
|
|
344
|
+
writeSectionTitle('Summary', color)
|
|
345
|
+
process.stdout.write(
|
|
346
|
+
`Baseline updated: ${summary.groups} groups, ${summary.rules} rules.\nSeverity mix: ${summary.error} errors, ${summary.warn} warnings, ${summary.off} off.\n`
|
|
347
|
+
)
|
|
344
348
|
}
|
|
345
349
|
|
|
346
350
|
return 0
|
|
@@ -400,23 +404,23 @@ async function computeCurrentSnapshots(cwd: string): Promise<Map<string, BuiltSn
|
|
|
400
404
|
let extractedCount = 0
|
|
401
405
|
let lastExtractionError: string | undefined
|
|
402
406
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
+
const sampledAbs = sampled.map((sampledRel) => path.resolve(workspaceAbs, sampledRel))
|
|
408
|
+
const results = await extractRulesForWorkspaceSamples(workspaceAbs, sampledAbs)
|
|
409
|
+
|
|
410
|
+
for (const result of results) {
|
|
411
|
+
if (result.rules) {
|
|
412
|
+
extractedForGroup.push(result.rules)
|
|
407
413
|
extractedCount += 1
|
|
408
|
-
|
|
409
|
-
const message = error instanceof Error ? error.message : String(error)
|
|
410
|
-
if (
|
|
411
|
-
message.startsWith('Invalid JSON from eslint --print-config') ||
|
|
412
|
-
message.startsWith('Empty ESLint print-config output')
|
|
413
|
-
) {
|
|
414
|
-
lastExtractionError = message
|
|
415
|
-
continue
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
throw error
|
|
414
|
+
continue
|
|
419
415
|
}
|
|
416
|
+
|
|
417
|
+
const message = result.error instanceof Error ? result.error.message : String(result.error)
|
|
418
|
+
if (isRecoverableExtractionError(message)) {
|
|
419
|
+
lastExtractionError = message
|
|
420
|
+
continue
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
throw result.error ?? new Error(message)
|
|
420
424
|
}
|
|
421
425
|
|
|
422
426
|
if (extractedCount === 0) {
|
|
@@ -434,6 +438,15 @@ async function computeCurrentSnapshots(cwd: string): Promise<Map<string, BuiltSn
|
|
|
434
438
|
return snapshots
|
|
435
439
|
}
|
|
436
440
|
|
|
441
|
+
function isRecoverableExtractionError(message: string): boolean {
|
|
442
|
+
return (
|
|
443
|
+
message.startsWith('Invalid JSON from eslint --print-config') ||
|
|
444
|
+
message.startsWith('Empty ESLint print-config output') ||
|
|
445
|
+
message.includes('File ignored because of a matching ignore pattern') ||
|
|
446
|
+
message.includes('File ignored by default')
|
|
447
|
+
)
|
|
448
|
+
}
|
|
449
|
+
|
|
437
450
|
async function resolveWorkspaceAssignments(cwd: string, config: Awaited<ReturnType<typeof loadConfig>>) {
|
|
438
451
|
const discovery = await discoverWorkspaces({ cwd, workspaceInput: config.workspaceInput })
|
|
439
452
|
|
|
@@ -880,20 +893,20 @@ function printWhatChanged(changes: Array<{ groupId: string; diff: SnapshotDiff }
|
|
|
880
893
|
|
|
881
894
|
if (changes.length === 0) {
|
|
882
895
|
process.stdout.write(color.green('Great news: no snapshot drift detected.\n'))
|
|
896
|
+
writeSectionTitle('Summary', color)
|
|
883
897
|
process.stdout.write(
|
|
884
|
-
|
|
898
|
+
`- baseline: ${currentSummary.groups} groups, ${currentSummary.rules} rules\n- severity mix: ${currentSummary.error} errors, ${currentSummary.warn} warnings, ${currentSummary.off} off\n`
|
|
885
899
|
)
|
|
886
900
|
return 0
|
|
887
901
|
}
|
|
888
902
|
|
|
889
903
|
process.stdout.write(color.red('Heads up: snapshot drift detected.\n'))
|
|
904
|
+
writeSectionTitle('Summary', color)
|
|
890
905
|
process.stdout.write(
|
|
891
|
-
|
|
892
|
-
)
|
|
893
|
-
process.stdout.write(
|
|
894
|
-
`Current rules: ${currentSummary.rules} (severity mix: ${currentSummary.error} errors, ${currentSummary.warn} warnings, ${currentSummary.off} off)\n\n`
|
|
906
|
+
`- changed groups: ${changes.length}\n- introduced rules: ${changeSummary.introduced}\n- removed rules: ${changeSummary.removed}\n- severity changes: ${changeSummary.severity}\n- options changes: ${changeSummary.options}\n- workspace membership changes: ${changeSummary.workspace}\n- current baseline: ${currentSummary.groups} groups, ${currentSummary.rules} rules\n- current severity mix: ${currentSummary.error} errors, ${currentSummary.warn} warnings, ${currentSummary.off} off\n\n`
|
|
895
907
|
)
|
|
896
908
|
|
|
909
|
+
writeSectionTitle('Changes', color)
|
|
897
910
|
for (const change of changes) {
|
|
898
911
|
process.stdout.write(color.bold(`group ${change.groupId}\n`))
|
|
899
912
|
const lines = formatDiff(change.groupId, change.diff).split('\n').slice(1)
|
|
@@ -908,6 +921,10 @@ function printWhatChanged(changes: Array<{ groupId: string; diff: SnapshotDiff }
|
|
|
908
921
|
return 1
|
|
909
922
|
}
|
|
910
923
|
|
|
924
|
+
function writeSectionTitle(title: string, color: ReturnType<typeof createColorizer>): void {
|
|
925
|
+
process.stdout.write(`${color.bold(title)}\n`)
|
|
926
|
+
}
|
|
927
|
+
|
|
911
928
|
function summarizeChanges(changes: Array<{ groupId: string; diff: SnapshotDiff }>) {
|
|
912
929
|
let introduced = 0
|
|
913
930
|
let removed = 0
|