@eslint-config-snapshot/cli 1.1.1 → 1.2.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 +106 -111
- package/dist/index.js +104 -109
- package/package.json +2 -2
- package/src/commands/check.ts +20 -69
- package/src/commands/print.ts +31 -23
- package/src/commands/skipped-workspaces.ts +9 -0
- package/src/commands/snapshot-executor.ts +97 -0
- package/src/commands/update.ts +14 -62
- package/src/index.ts +2 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @eslint-config-snapshot/cli
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Minor release: centralize shared command execution flow with reusable snapshot preparation executor.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @eslint-config-snapshot/api@1.2.0
|
|
13
|
+
|
|
3
14
|
## 1.1.1
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -40,9 +40,6 @@ var import_commander = require("commander");
|
|
|
40
40
|
var import_debug2 = __toESM(require("debug"), 1);
|
|
41
41
|
var import_node_path5 = __toESM(require("path"), 1);
|
|
42
42
|
|
|
43
|
-
// src/commands/check.ts
|
|
44
|
-
var import_api3 = require("@eslint-config-snapshot/api");
|
|
45
|
-
|
|
46
43
|
// src/formatters.ts
|
|
47
44
|
function formatDiff(groupId, diff) {
|
|
48
45
|
const lines = [`group: ${groupId}`];
|
|
@@ -586,6 +583,14 @@ async function resolveGroupEslintVersions(cwd) {
|
|
|
586
583
|
|
|
587
584
|
// src/commands/skipped-workspaces.ts
|
|
588
585
|
var import_node_path3 = __toESM(require("path"), 1);
|
|
586
|
+
function writeDiscoveredWorkspacesSummary(terminal, workspacesRel) {
|
|
587
|
+
if (workspacesRel.length === 0) {
|
|
588
|
+
terminal.subtle("Auto-discovered workspaces: none\n");
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
terminal.subtle(`Auto-discovered workspaces (${workspacesRel.length}): ${workspacesRel.join(", ")}
|
|
592
|
+
`);
|
|
593
|
+
}
|
|
589
594
|
function writeSkippedWorkspaceSummary(terminal, cwd, configPath, skippedWorkspaces) {
|
|
590
595
|
if (skippedWorkspaces.length === 0) {
|
|
591
596
|
return;
|
|
@@ -641,26 +646,27 @@ ${objectLiteral}`;
|
|
|
641
646
|
${objectLiteral}`;
|
|
642
647
|
}
|
|
643
648
|
|
|
644
|
-
// src/commands/
|
|
645
|
-
var
|
|
646
|
-
async function
|
|
649
|
+
// src/commands/snapshot-executor.ts
|
|
650
|
+
var import_api3 = require("@eslint-config-snapshot/api");
|
|
651
|
+
async function prepareSnapshotExecution(options) {
|
|
652
|
+
const { cwd, snapshotDir, terminal, commandLabel, progressMessage, showContext = true } = options;
|
|
647
653
|
const foundConfig = await (0, import_api3.findConfigPath)(cwd);
|
|
648
654
|
const storedSnapshots = await loadStoredSnapshots(cwd, snapshotDir);
|
|
649
|
-
if (
|
|
650
|
-
writeRunContextHeader(terminal, cwd,
|
|
651
|
-
if (terminal.showProgress) {
|
|
652
|
-
terminal.subtle("\u{1F50E} Checking current ESLint configuration...\n");
|
|
653
|
-
}
|
|
655
|
+
if (showContext) {
|
|
656
|
+
writeRunContextHeader(terminal, cwd, commandLabel, foundConfig?.path, storedSnapshots);
|
|
654
657
|
}
|
|
655
|
-
if (
|
|
658
|
+
if (showContext && terminal.showProgress && progressMessage.length > 0) {
|
|
659
|
+
terminal.subtle(progressMessage);
|
|
660
|
+
}
|
|
661
|
+
if (showContext && !foundConfig) {
|
|
656
662
|
terminal.subtle(
|
|
657
663
|
"Tip: no explicit config found. Using safe built-in defaults. Run `eslint-config-snapshot init` to customize when needed.\n"
|
|
658
664
|
);
|
|
659
665
|
}
|
|
660
|
-
let currentSnapshots;
|
|
661
666
|
const skippedWorkspaces = [];
|
|
662
667
|
let discoveredWorkspaces = [];
|
|
663
668
|
const allowWorkspaceExtractionFailure = !foundConfig || isDefaultEquivalentConfig(foundConfig.config);
|
|
669
|
+
let currentSnapshots;
|
|
664
670
|
try {
|
|
665
671
|
currentSnapshots = await computeCurrentSnapshots(cwd, {
|
|
666
672
|
allowWorkspaceExtractionFailure,
|
|
@@ -672,18 +678,56 @@ async function executeCheck(cwd, format, terminal, snapshotDir, defaultInvocatio
|
|
|
672
678
|
}
|
|
673
679
|
});
|
|
674
680
|
} catch (error) {
|
|
675
|
-
if (
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
681
|
+
if (allowWorkspaceExtractionFailure && isWorkspaceDiscoveryDefaultsError(error)) {
|
|
682
|
+
if (showContext) {
|
|
683
|
+
terminal.write(
|
|
684
|
+
"Automatic workspace discovery could not complete with defaults.\nRun `eslint-config-snapshot init` to configure workspaces, then run `eslint-config-snapshot --update`.\n"
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
return { ok: false, exitCode: 1 };
|
|
680
688
|
}
|
|
681
689
|
throw error;
|
|
682
690
|
}
|
|
683
|
-
|
|
691
|
+
return {
|
|
692
|
+
ok: true,
|
|
693
|
+
foundConfig,
|
|
694
|
+
storedSnapshots,
|
|
695
|
+
currentSnapshots,
|
|
696
|
+
discoveredWorkspaces,
|
|
697
|
+
skippedWorkspaces
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
function isWorkspaceDiscoveryDefaultsError(error) {
|
|
701
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
702
|
+
return message.includes("Unable to discover workspaces") || message.includes("Unmatched workspaces") || message.includes("zero-config mode");
|
|
703
|
+
}
|
|
704
|
+
function isDefaultEquivalentConfig(config) {
|
|
705
|
+
return JSON.stringify(config) === JSON.stringify(import_api3.DEFAULT_CONFIG);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// src/commands/check.ts
|
|
709
|
+
var UPDATE_HINT = "Tip: when you intentionally accept changes, run `eslint-config-snapshot --update` to refresh the baseline.\n";
|
|
710
|
+
async function executeCheck(cwd, format, terminal, snapshotDir, defaultInvocation = false) {
|
|
711
|
+
const isStatusFormat = format === "status";
|
|
712
|
+
const commandLabel = defaultInvocation ? "check" : `check:${format}`;
|
|
713
|
+
const prepared = await prepareSnapshotExecution({
|
|
714
|
+
cwd,
|
|
715
|
+
snapshotDir,
|
|
716
|
+
terminal,
|
|
717
|
+
commandLabel: isStatusFormat ? "check:status" : commandLabel,
|
|
718
|
+
progressMessage: isStatusFormat ? "" : "\u{1F50E} Checking current ESLint configuration...\n",
|
|
719
|
+
showContext: isStatusFormat === false
|
|
720
|
+
});
|
|
721
|
+
if (prepared.ok === false) {
|
|
722
|
+
return prepared.exitCode;
|
|
723
|
+
}
|
|
724
|
+
const { foundConfig, storedSnapshots, currentSnapshots, discoveredWorkspaces, skippedWorkspaces } = prepared;
|
|
725
|
+
if (foundConfig === null && isStatusFormat === false) {
|
|
684
726
|
writeDiscoveredWorkspacesSummary(terminal, discoveredWorkspaces);
|
|
685
727
|
}
|
|
686
|
-
|
|
728
|
+
if (isStatusFormat === false) {
|
|
729
|
+
writeSkippedWorkspaceSummary(terminal, cwd, foundConfig?.path, skippedWorkspaces);
|
|
730
|
+
}
|
|
687
731
|
if (storedSnapshots.size === 0) {
|
|
688
732
|
const summary = summarizeSnapshots(currentSnapshots);
|
|
689
733
|
terminal.write(
|
|
@@ -778,36 +822,24 @@ function printWhatChanged(terminal, changes, currentSnapshots, eslintVersionsByG
|
|
|
778
822
|
terminal.subtle(UPDATE_HINT);
|
|
779
823
|
return 1;
|
|
780
824
|
}
|
|
781
|
-
function isWorkspaceDiscoveryDefaultsError(error) {
|
|
782
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
783
|
-
return message.includes("Unable to discover workspaces") || message.includes("Unmatched workspaces") || message.includes("zero-config mode");
|
|
784
|
-
}
|
|
785
|
-
function isDefaultEquivalentConfig(config) {
|
|
786
|
-
return JSON.stringify(config) === JSON.stringify(import_api3.DEFAULT_CONFIG);
|
|
787
|
-
}
|
|
788
|
-
function writeDiscoveredWorkspacesSummary(terminal, workspacesRel) {
|
|
789
|
-
if (workspacesRel.length === 0) {
|
|
790
|
-
terminal.subtle("Auto-discovered workspaces: none\n");
|
|
791
|
-
return;
|
|
792
|
-
}
|
|
793
|
-
terminal.subtle(`Auto-discovered workspaces (${workspacesRel.length}): ${workspacesRel.join(", ")}
|
|
794
|
-
`);
|
|
795
|
-
}
|
|
796
825
|
|
|
797
826
|
// src/commands/print.ts
|
|
798
827
|
var import_api4 = require("@eslint-config-snapshot/api");
|
|
799
828
|
async function executePrint(cwd, terminal, snapshotDir, format) {
|
|
800
|
-
const
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
829
|
+
const prepared = await prepareSnapshotExecution({
|
|
830
|
+
cwd,
|
|
831
|
+
snapshotDir,
|
|
832
|
+
terminal,
|
|
833
|
+
commandLabel: `print:${format}`,
|
|
834
|
+
progressMessage: "\u{1F50E} Checking current ESLint configuration...\n"
|
|
835
|
+
});
|
|
836
|
+
if (!prepared.ok) {
|
|
837
|
+
return prepared.exitCode;
|
|
805
838
|
}
|
|
806
|
-
const
|
|
807
|
-
const currentSnapshots = await computeCurrentSnapshots(cwd, { allowWorkspaceExtractionFailure });
|
|
839
|
+
const { currentSnapshots } = prepared;
|
|
808
840
|
if (format === "short") {
|
|
809
841
|
terminal.write(formatShortPrint([...currentSnapshots.values()]));
|
|
810
|
-
return;
|
|
842
|
+
return 0;
|
|
811
843
|
}
|
|
812
844
|
const output = [...currentSnapshots.values()].map((snapshot) => ({
|
|
813
845
|
groupId: snapshot.groupId,
|
|
@@ -815,14 +847,20 @@ async function executePrint(cwd, terminal, snapshotDir, format) {
|
|
|
815
847
|
}));
|
|
816
848
|
terminal.write(`${JSON.stringify(output, null, 2)}
|
|
817
849
|
`);
|
|
850
|
+
return 0;
|
|
818
851
|
}
|
|
819
852
|
async function executeConfig(cwd, terminal, snapshotDir, format) {
|
|
820
|
-
const
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
853
|
+
const prepared = await prepareSnapshotExecution({
|
|
854
|
+
cwd,
|
|
855
|
+
snapshotDir,
|
|
856
|
+
terminal,
|
|
857
|
+
commandLabel: `config:${format}`,
|
|
858
|
+
progressMessage: "\u2699\uFE0F Resolving effective runtime configuration...\n"
|
|
859
|
+
});
|
|
860
|
+
if (!prepared.ok) {
|
|
861
|
+
return prepared.exitCode;
|
|
825
862
|
}
|
|
863
|
+
const { foundConfig } = prepared;
|
|
826
864
|
const config = await (0, import_api4.loadConfig)(cwd);
|
|
827
865
|
const resolved = await resolveWorkspaceAssignments(cwd, config);
|
|
828
866
|
const payload = {
|
|
@@ -838,54 +876,28 @@ async function executeConfig(cwd, terminal, snapshotDir, format) {
|
|
|
838
876
|
};
|
|
839
877
|
if (format === "short") {
|
|
840
878
|
terminal.write(formatShortConfig(payload));
|
|
841
|
-
return;
|
|
879
|
+
return 0;
|
|
842
880
|
}
|
|
843
881
|
terminal.write(`${JSON.stringify(payload, null, 2)}
|
|
844
882
|
`);
|
|
845
|
-
|
|
846
|
-
function isDefaultEquivalentConfig2(config) {
|
|
847
|
-
return JSON.stringify(config) === JSON.stringify(import_api4.DEFAULT_CONFIG);
|
|
883
|
+
return 0;
|
|
848
884
|
}
|
|
849
885
|
|
|
850
886
|
// src/commands/update.ts
|
|
851
|
-
var import_api5 = require("@eslint-config-snapshot/api");
|
|
852
887
|
async function executeUpdate(cwd, terminal, snapshotDir, printSummary) {
|
|
853
|
-
const
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
);
|
|
863
|
-
}
|
|
864
|
-
let currentSnapshots;
|
|
865
|
-
const skippedWorkspaces = [];
|
|
866
|
-
let discoveredWorkspaces = [];
|
|
867
|
-
const allowWorkspaceExtractionFailure = !foundConfig || isDefaultEquivalentConfig3(foundConfig.config);
|
|
868
|
-
try {
|
|
869
|
-
currentSnapshots = await computeCurrentSnapshots(cwd, {
|
|
870
|
-
allowWorkspaceExtractionFailure,
|
|
871
|
-
onWorkspacesDiscovered: (workspacesRel) => {
|
|
872
|
-
discoveredWorkspaces = workspacesRel;
|
|
873
|
-
},
|
|
874
|
-
onWorkspaceSkipped: (skipped) => {
|
|
875
|
-
skippedWorkspaces.push(skipped);
|
|
876
|
-
}
|
|
877
|
-
});
|
|
878
|
-
} catch (error) {
|
|
879
|
-
if (!foundConfig && isWorkspaceDiscoveryDefaultsError2(error)) {
|
|
880
|
-
terminal.write(
|
|
881
|
-
"Automatic workspace discovery could not complete with defaults.\nRun `eslint-config-snapshot init` to configure workspaces, then run `eslint-config-snapshot --update`.\n"
|
|
882
|
-
);
|
|
883
|
-
return 1;
|
|
884
|
-
}
|
|
885
|
-
throw error;
|
|
888
|
+
const prepared = await prepareSnapshotExecution({
|
|
889
|
+
cwd,
|
|
890
|
+
snapshotDir,
|
|
891
|
+
terminal,
|
|
892
|
+
commandLabel: "update",
|
|
893
|
+
progressMessage: "\u{1F50E} Checking current ESLint configuration...\n"
|
|
894
|
+
});
|
|
895
|
+
if (prepared.ok === false) {
|
|
896
|
+
return prepared.exitCode;
|
|
886
897
|
}
|
|
898
|
+
const { foundConfig, storedSnapshots, currentSnapshots, discoveredWorkspaces, skippedWorkspaces } = prepared;
|
|
887
899
|
if (!foundConfig) {
|
|
888
|
-
|
|
900
|
+
writeDiscoveredWorkspacesSummary(terminal, discoveredWorkspaces);
|
|
889
901
|
}
|
|
890
902
|
writeSkippedWorkspaceSummary(terminal, cwd, foundConfig?.path, skippedWorkspaces);
|
|
891
903
|
await writeSnapshots(cwd, snapshotDir, currentSnapshots);
|
|
@@ -902,31 +914,16 @@ async function executeUpdate(cwd, terminal, snapshotDir, printSummary) {
|
|
|
902
914
|
}
|
|
903
915
|
return 0;
|
|
904
916
|
}
|
|
905
|
-
function isWorkspaceDiscoveryDefaultsError2(error) {
|
|
906
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
907
|
-
return message.includes("Unable to discover workspaces") || message.includes("Unmatched workspaces") || message.includes("zero-config mode");
|
|
908
|
-
}
|
|
909
|
-
function isDefaultEquivalentConfig3(config) {
|
|
910
|
-
return JSON.stringify(config) === JSON.stringify(import_api5.DEFAULT_CONFIG);
|
|
911
|
-
}
|
|
912
|
-
function writeDiscoveredWorkspacesSummary2(terminal, workspacesRel) {
|
|
913
|
-
if (workspacesRel.length === 0) {
|
|
914
|
-
terminal.subtle("Auto-discovered workspaces: none\n");
|
|
915
|
-
return;
|
|
916
|
-
}
|
|
917
|
-
terminal.subtle(`Auto-discovered workspaces (${workspacesRel.length}): ${workspacesRel.join(", ")}
|
|
918
|
-
`);
|
|
919
|
-
}
|
|
920
917
|
|
|
921
918
|
// src/init.ts
|
|
922
|
-
var
|
|
919
|
+
var import_api5 = require("@eslint-config-snapshot/api");
|
|
923
920
|
var import_fast_glob2 = __toESM(require("fast-glob"), 1);
|
|
924
921
|
var import_promises2 = require("fs/promises");
|
|
925
922
|
var import_node_path4 = __toESM(require("path"), 1);
|
|
926
923
|
async function runInit(cwd, opts, runtime) {
|
|
927
924
|
const force = opts.force ?? false;
|
|
928
925
|
const showEffective = opts.showEffective ?? false;
|
|
929
|
-
const existing = await (0,
|
|
926
|
+
const existing = await (0, import_api5.findConfigPath)(cwd);
|
|
930
927
|
if (existing && !force) {
|
|
931
928
|
runtime.writeStderr(
|
|
932
929
|
`Existing config detected at ${existing.path}. Creating another config can cause conflicts. Remove the existing config or rerun with --force.
|
|
@@ -1063,7 +1060,7 @@ function buildRecommendedConfigFromAssignments(workspaces, assignments) {
|
|
|
1063
1060
|
};
|
|
1064
1061
|
}
|
|
1065
1062
|
async function discoverInitWorkspaces(cwd) {
|
|
1066
|
-
const discovered = await (0,
|
|
1063
|
+
const discovered = await (0, import_api5.discoverWorkspaces)({ cwd, workspaceInput: { mode: "discover" } });
|
|
1067
1064
|
if (!(discovered.workspacesRel.length === 1 && discovered.workspacesRel[0] === ".")) {
|
|
1068
1065
|
return discovered.workspacesRel;
|
|
1069
1066
|
}
|
|
@@ -1085,7 +1082,7 @@ async function discoverInitWorkspaces(cwd) {
|
|
|
1085
1082
|
onlyFiles: true,
|
|
1086
1083
|
dot: true
|
|
1087
1084
|
});
|
|
1088
|
-
const workspaceDirs = [...new Set(workspacePackageFiles.map((entry) => (0,
|
|
1085
|
+
const workspaceDirs = [...new Set(workspacePackageFiles.map((entry) => (0, import_api5.normalizePath)(import_node_path4.default.dirname(entry))))].sort(
|
|
1089
1086
|
(a, b) => a.localeCompare(b)
|
|
1090
1087
|
);
|
|
1091
1088
|
if (workspaceDirs.length > 0) {
|
|
@@ -1136,7 +1133,7 @@ async function askRecommendedGroupAssignments(workspaces, runtime) {
|
|
|
1136
1133
|
}
|
|
1137
1134
|
function toConfigScaffold(configObject) {
|
|
1138
1135
|
if (Object.keys(configObject).length === 0) {
|
|
1139
|
-
return (0,
|
|
1136
|
+
return (0, import_api5.getConfigScaffold)("minimal");
|
|
1140
1137
|
}
|
|
1141
1138
|
return `export default ${JSON.stringify(configObject, null, 2)}
|
|
1142
1139
|
`;
|
|
@@ -1416,13 +1413,11 @@ function createProgram(cwd, terminal, onActionExit) {
|
|
|
1416
1413
|
});
|
|
1417
1414
|
program.command("print").description("Print aggregated rules").option("--format <format>", "Output format: json|short", parsePrintFormat, "json").option("--short", "Alias for --format short").action(async (opts) => {
|
|
1418
1415
|
const format = opts.short ? "short" : opts.format;
|
|
1419
|
-
await executePrint(cwd, terminal, SNAPSHOT_DIR, format);
|
|
1420
|
-
onActionExit(0);
|
|
1416
|
+
onActionExit(await executePrint(cwd, terminal, SNAPSHOT_DIR, format));
|
|
1421
1417
|
});
|
|
1422
1418
|
program.command("config").description("Print effective evaluated config").option("--format <format>", "Output format: json|short", parsePrintFormat, "json").option("--short", "Alias for --format short").action(async (opts) => {
|
|
1423
1419
|
const format = opts.short ? "short" : opts.format;
|
|
1424
|
-
await executeConfig(cwd, terminal, SNAPSHOT_DIR, format);
|
|
1425
|
-
onActionExit(0);
|
|
1420
|
+
onActionExit(await executeConfig(cwd, terminal, SNAPSHOT_DIR, format));
|
|
1426
1421
|
});
|
|
1427
1422
|
program.command("init").description("Initialize config (file or package.json)").option("--target <target>", "Config target: file|package-json", parseInitTarget).option("--preset <preset>", "Config preset: recommended|minimal|full", parseInitPreset).option("--show-effective", "Print the evaluated config that will be written").option("-f, --force", "Allow init even when an existing config is detected").option("-y, --yes", "Skip prompts and use defaults/options").addHelpText(
|
|
1428
1423
|
"after",
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,6 @@ import { Command, CommanderError, InvalidArgumentError } from "commander";
|
|
|
5
5
|
import createDebug2 from "debug";
|
|
6
6
|
import path5 from "path";
|
|
7
7
|
|
|
8
|
-
// src/commands/check.ts
|
|
9
|
-
import { DEFAULT_CONFIG, findConfigPath } from "@eslint-config-snapshot/api";
|
|
10
|
-
|
|
11
8
|
// src/formatters.ts
|
|
12
9
|
function formatDiff(groupId, diff) {
|
|
13
10
|
const lines = [`group: ${groupId}`];
|
|
@@ -564,6 +561,14 @@ async function resolveGroupEslintVersions(cwd) {
|
|
|
564
561
|
|
|
565
562
|
// src/commands/skipped-workspaces.ts
|
|
566
563
|
import path3 from "path";
|
|
564
|
+
function writeDiscoveredWorkspacesSummary(terminal, workspacesRel) {
|
|
565
|
+
if (workspacesRel.length === 0) {
|
|
566
|
+
terminal.subtle("Auto-discovered workspaces: none\n");
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
terminal.subtle(`Auto-discovered workspaces (${workspacesRel.length}): ${workspacesRel.join(", ")}
|
|
570
|
+
`);
|
|
571
|
+
}
|
|
567
572
|
function writeSkippedWorkspaceSummary(terminal, cwd, configPath, skippedWorkspaces) {
|
|
568
573
|
if (skippedWorkspaces.length === 0) {
|
|
569
574
|
return;
|
|
@@ -619,26 +624,27 @@ ${objectLiteral}`;
|
|
|
619
624
|
${objectLiteral}`;
|
|
620
625
|
}
|
|
621
626
|
|
|
622
|
-
// src/commands/
|
|
623
|
-
|
|
624
|
-
async function
|
|
627
|
+
// src/commands/snapshot-executor.ts
|
|
628
|
+
import { DEFAULT_CONFIG, findConfigPath } from "@eslint-config-snapshot/api";
|
|
629
|
+
async function prepareSnapshotExecution(options) {
|
|
630
|
+
const { cwd, snapshotDir, terminal, commandLabel, progressMessage, showContext = true } = options;
|
|
625
631
|
const foundConfig = await findConfigPath(cwd);
|
|
626
632
|
const storedSnapshots = await loadStoredSnapshots(cwd, snapshotDir);
|
|
627
|
-
if (
|
|
628
|
-
writeRunContextHeader(terminal, cwd,
|
|
629
|
-
if (terminal.showProgress) {
|
|
630
|
-
terminal.subtle("\u{1F50E} Checking current ESLint configuration...\n");
|
|
631
|
-
}
|
|
633
|
+
if (showContext) {
|
|
634
|
+
writeRunContextHeader(terminal, cwd, commandLabel, foundConfig?.path, storedSnapshots);
|
|
632
635
|
}
|
|
633
|
-
if (
|
|
636
|
+
if (showContext && terminal.showProgress && progressMessage.length > 0) {
|
|
637
|
+
terminal.subtle(progressMessage);
|
|
638
|
+
}
|
|
639
|
+
if (showContext && !foundConfig) {
|
|
634
640
|
terminal.subtle(
|
|
635
641
|
"Tip: no explicit config found. Using safe built-in defaults. Run `eslint-config-snapshot init` to customize when needed.\n"
|
|
636
642
|
);
|
|
637
643
|
}
|
|
638
|
-
let currentSnapshots;
|
|
639
644
|
const skippedWorkspaces = [];
|
|
640
645
|
let discoveredWorkspaces = [];
|
|
641
646
|
const allowWorkspaceExtractionFailure = !foundConfig || isDefaultEquivalentConfig(foundConfig.config);
|
|
647
|
+
let currentSnapshots;
|
|
642
648
|
try {
|
|
643
649
|
currentSnapshots = await computeCurrentSnapshots(cwd, {
|
|
644
650
|
allowWorkspaceExtractionFailure,
|
|
@@ -650,18 +656,56 @@ async function executeCheck(cwd, format, terminal, snapshotDir, defaultInvocatio
|
|
|
650
656
|
}
|
|
651
657
|
});
|
|
652
658
|
} catch (error) {
|
|
653
|
-
if (
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
659
|
+
if (allowWorkspaceExtractionFailure && isWorkspaceDiscoveryDefaultsError(error)) {
|
|
660
|
+
if (showContext) {
|
|
661
|
+
terminal.write(
|
|
662
|
+
"Automatic workspace discovery could not complete with defaults.\nRun `eslint-config-snapshot init` to configure workspaces, then run `eslint-config-snapshot --update`.\n"
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
return { ok: false, exitCode: 1 };
|
|
658
666
|
}
|
|
659
667
|
throw error;
|
|
660
668
|
}
|
|
661
|
-
|
|
669
|
+
return {
|
|
670
|
+
ok: true,
|
|
671
|
+
foundConfig,
|
|
672
|
+
storedSnapshots,
|
|
673
|
+
currentSnapshots,
|
|
674
|
+
discoveredWorkspaces,
|
|
675
|
+
skippedWorkspaces
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
function isWorkspaceDiscoveryDefaultsError(error) {
|
|
679
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
680
|
+
return message.includes("Unable to discover workspaces") || message.includes("Unmatched workspaces") || message.includes("zero-config mode");
|
|
681
|
+
}
|
|
682
|
+
function isDefaultEquivalentConfig(config) {
|
|
683
|
+
return JSON.stringify(config) === JSON.stringify(DEFAULT_CONFIG);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// src/commands/check.ts
|
|
687
|
+
var UPDATE_HINT = "Tip: when you intentionally accept changes, run `eslint-config-snapshot --update` to refresh the baseline.\n";
|
|
688
|
+
async function executeCheck(cwd, format, terminal, snapshotDir, defaultInvocation = false) {
|
|
689
|
+
const isStatusFormat = format === "status";
|
|
690
|
+
const commandLabel = defaultInvocation ? "check" : `check:${format}`;
|
|
691
|
+
const prepared = await prepareSnapshotExecution({
|
|
692
|
+
cwd,
|
|
693
|
+
snapshotDir,
|
|
694
|
+
terminal,
|
|
695
|
+
commandLabel: isStatusFormat ? "check:status" : commandLabel,
|
|
696
|
+
progressMessage: isStatusFormat ? "" : "\u{1F50E} Checking current ESLint configuration...\n",
|
|
697
|
+
showContext: isStatusFormat === false
|
|
698
|
+
});
|
|
699
|
+
if (prepared.ok === false) {
|
|
700
|
+
return prepared.exitCode;
|
|
701
|
+
}
|
|
702
|
+
const { foundConfig, storedSnapshots, currentSnapshots, discoveredWorkspaces, skippedWorkspaces } = prepared;
|
|
703
|
+
if (foundConfig === null && isStatusFormat === false) {
|
|
662
704
|
writeDiscoveredWorkspacesSummary(terminal, discoveredWorkspaces);
|
|
663
705
|
}
|
|
664
|
-
|
|
706
|
+
if (isStatusFormat === false) {
|
|
707
|
+
writeSkippedWorkspaceSummary(terminal, cwd, foundConfig?.path, skippedWorkspaces);
|
|
708
|
+
}
|
|
665
709
|
if (storedSnapshots.size === 0) {
|
|
666
710
|
const summary = summarizeSnapshots(currentSnapshots);
|
|
667
711
|
terminal.write(
|
|
@@ -756,36 +800,24 @@ function printWhatChanged(terminal, changes, currentSnapshots, eslintVersionsByG
|
|
|
756
800
|
terminal.subtle(UPDATE_HINT);
|
|
757
801
|
return 1;
|
|
758
802
|
}
|
|
759
|
-
function isWorkspaceDiscoveryDefaultsError(error) {
|
|
760
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
761
|
-
return message.includes("Unable to discover workspaces") || message.includes("Unmatched workspaces") || message.includes("zero-config mode");
|
|
762
|
-
}
|
|
763
|
-
function isDefaultEquivalentConfig(config) {
|
|
764
|
-
return JSON.stringify(config) === JSON.stringify(DEFAULT_CONFIG);
|
|
765
|
-
}
|
|
766
|
-
function writeDiscoveredWorkspacesSummary(terminal, workspacesRel) {
|
|
767
|
-
if (workspacesRel.length === 0) {
|
|
768
|
-
terminal.subtle("Auto-discovered workspaces: none\n");
|
|
769
|
-
return;
|
|
770
|
-
}
|
|
771
|
-
terminal.subtle(`Auto-discovered workspaces (${workspacesRel.length}): ${workspacesRel.join(", ")}
|
|
772
|
-
`);
|
|
773
|
-
}
|
|
774
803
|
|
|
775
804
|
// src/commands/print.ts
|
|
776
|
-
import {
|
|
805
|
+
import { loadConfig as loadConfig2 } from "@eslint-config-snapshot/api";
|
|
777
806
|
async function executePrint(cwd, terminal, snapshotDir, format) {
|
|
778
|
-
const
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
807
|
+
const prepared = await prepareSnapshotExecution({
|
|
808
|
+
cwd,
|
|
809
|
+
snapshotDir,
|
|
810
|
+
terminal,
|
|
811
|
+
commandLabel: `print:${format}`,
|
|
812
|
+
progressMessage: "\u{1F50E} Checking current ESLint configuration...\n"
|
|
813
|
+
});
|
|
814
|
+
if (!prepared.ok) {
|
|
815
|
+
return prepared.exitCode;
|
|
783
816
|
}
|
|
784
|
-
const
|
|
785
|
-
const currentSnapshots = await computeCurrentSnapshots(cwd, { allowWorkspaceExtractionFailure });
|
|
817
|
+
const { currentSnapshots } = prepared;
|
|
786
818
|
if (format === "short") {
|
|
787
819
|
terminal.write(formatShortPrint([...currentSnapshots.values()]));
|
|
788
|
-
return;
|
|
820
|
+
return 0;
|
|
789
821
|
}
|
|
790
822
|
const output = [...currentSnapshots.values()].map((snapshot) => ({
|
|
791
823
|
groupId: snapshot.groupId,
|
|
@@ -793,14 +825,20 @@ async function executePrint(cwd, terminal, snapshotDir, format) {
|
|
|
793
825
|
}));
|
|
794
826
|
terminal.write(`${JSON.stringify(output, null, 2)}
|
|
795
827
|
`);
|
|
828
|
+
return 0;
|
|
796
829
|
}
|
|
797
830
|
async function executeConfig(cwd, terminal, snapshotDir, format) {
|
|
798
|
-
const
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
831
|
+
const prepared = await prepareSnapshotExecution({
|
|
832
|
+
cwd,
|
|
833
|
+
snapshotDir,
|
|
834
|
+
terminal,
|
|
835
|
+
commandLabel: `config:${format}`,
|
|
836
|
+
progressMessage: "\u2699\uFE0F Resolving effective runtime configuration...\n"
|
|
837
|
+
});
|
|
838
|
+
if (!prepared.ok) {
|
|
839
|
+
return prepared.exitCode;
|
|
803
840
|
}
|
|
841
|
+
const { foundConfig } = prepared;
|
|
804
842
|
const config = await loadConfig2(cwd);
|
|
805
843
|
const resolved = await resolveWorkspaceAssignments(cwd, config);
|
|
806
844
|
const payload = {
|
|
@@ -816,54 +854,28 @@ async function executeConfig(cwd, terminal, snapshotDir, format) {
|
|
|
816
854
|
};
|
|
817
855
|
if (format === "short") {
|
|
818
856
|
terminal.write(formatShortConfig(payload));
|
|
819
|
-
return;
|
|
857
|
+
return 0;
|
|
820
858
|
}
|
|
821
859
|
terminal.write(`${JSON.stringify(payload, null, 2)}
|
|
822
860
|
`);
|
|
823
|
-
|
|
824
|
-
function isDefaultEquivalentConfig2(config) {
|
|
825
|
-
return JSON.stringify(config) === JSON.stringify(DEFAULT_CONFIG2);
|
|
861
|
+
return 0;
|
|
826
862
|
}
|
|
827
863
|
|
|
828
864
|
// src/commands/update.ts
|
|
829
|
-
import { DEFAULT_CONFIG as DEFAULT_CONFIG3, findConfigPath as findConfigPath3 } from "@eslint-config-snapshot/api";
|
|
830
865
|
async function executeUpdate(cwd, terminal, snapshotDir, printSummary) {
|
|
831
|
-
const
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
);
|
|
841
|
-
}
|
|
842
|
-
let currentSnapshots;
|
|
843
|
-
const skippedWorkspaces = [];
|
|
844
|
-
let discoveredWorkspaces = [];
|
|
845
|
-
const allowWorkspaceExtractionFailure = !foundConfig || isDefaultEquivalentConfig3(foundConfig.config);
|
|
846
|
-
try {
|
|
847
|
-
currentSnapshots = await computeCurrentSnapshots(cwd, {
|
|
848
|
-
allowWorkspaceExtractionFailure,
|
|
849
|
-
onWorkspacesDiscovered: (workspacesRel) => {
|
|
850
|
-
discoveredWorkspaces = workspacesRel;
|
|
851
|
-
},
|
|
852
|
-
onWorkspaceSkipped: (skipped) => {
|
|
853
|
-
skippedWorkspaces.push(skipped);
|
|
854
|
-
}
|
|
855
|
-
});
|
|
856
|
-
} catch (error) {
|
|
857
|
-
if (!foundConfig && isWorkspaceDiscoveryDefaultsError2(error)) {
|
|
858
|
-
terminal.write(
|
|
859
|
-
"Automatic workspace discovery could not complete with defaults.\nRun `eslint-config-snapshot init` to configure workspaces, then run `eslint-config-snapshot --update`.\n"
|
|
860
|
-
);
|
|
861
|
-
return 1;
|
|
862
|
-
}
|
|
863
|
-
throw error;
|
|
866
|
+
const prepared = await prepareSnapshotExecution({
|
|
867
|
+
cwd,
|
|
868
|
+
snapshotDir,
|
|
869
|
+
terminal,
|
|
870
|
+
commandLabel: "update",
|
|
871
|
+
progressMessage: "\u{1F50E} Checking current ESLint configuration...\n"
|
|
872
|
+
});
|
|
873
|
+
if (prepared.ok === false) {
|
|
874
|
+
return prepared.exitCode;
|
|
864
875
|
}
|
|
876
|
+
const { foundConfig, storedSnapshots, currentSnapshots, discoveredWorkspaces, skippedWorkspaces } = prepared;
|
|
865
877
|
if (!foundConfig) {
|
|
866
|
-
|
|
878
|
+
writeDiscoveredWorkspacesSummary(terminal, discoveredWorkspaces);
|
|
867
879
|
}
|
|
868
880
|
writeSkippedWorkspaceSummary(terminal, cwd, foundConfig?.path, skippedWorkspaces);
|
|
869
881
|
await writeSnapshots(cwd, snapshotDir, currentSnapshots);
|
|
@@ -880,31 +892,16 @@ async function executeUpdate(cwd, terminal, snapshotDir, printSummary) {
|
|
|
880
892
|
}
|
|
881
893
|
return 0;
|
|
882
894
|
}
|
|
883
|
-
function isWorkspaceDiscoveryDefaultsError2(error) {
|
|
884
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
885
|
-
return message.includes("Unable to discover workspaces") || message.includes("Unmatched workspaces") || message.includes("zero-config mode");
|
|
886
|
-
}
|
|
887
|
-
function isDefaultEquivalentConfig3(config) {
|
|
888
|
-
return JSON.stringify(config) === JSON.stringify(DEFAULT_CONFIG3);
|
|
889
|
-
}
|
|
890
|
-
function writeDiscoveredWorkspacesSummary2(terminal, workspacesRel) {
|
|
891
|
-
if (workspacesRel.length === 0) {
|
|
892
|
-
terminal.subtle("Auto-discovered workspaces: none\n");
|
|
893
|
-
return;
|
|
894
|
-
}
|
|
895
|
-
terminal.subtle(`Auto-discovered workspaces (${workspacesRel.length}): ${workspacesRel.join(", ")}
|
|
896
|
-
`);
|
|
897
|
-
}
|
|
898
895
|
|
|
899
896
|
// src/init.ts
|
|
900
|
-
import { discoverWorkspaces as discoverWorkspaces2, findConfigPath as
|
|
897
|
+
import { discoverWorkspaces as discoverWorkspaces2, findConfigPath as findConfigPath2, getConfigScaffold, normalizePath as normalizePath2 } from "@eslint-config-snapshot/api";
|
|
901
898
|
import fg2 from "fast-glob";
|
|
902
899
|
import { access, readFile, writeFile } from "fs/promises";
|
|
903
900
|
import path4 from "path";
|
|
904
901
|
async function runInit(cwd, opts, runtime) {
|
|
905
902
|
const force = opts.force ?? false;
|
|
906
903
|
const showEffective = opts.showEffective ?? false;
|
|
907
|
-
const existing = await
|
|
904
|
+
const existing = await findConfigPath2(cwd);
|
|
908
905
|
if (existing && !force) {
|
|
909
906
|
runtime.writeStderr(
|
|
910
907
|
`Existing config detected at ${existing.path}. Creating another config can cause conflicts. Remove the existing config or rerun with --force.
|
|
@@ -1394,13 +1391,11 @@ function createProgram(cwd, terminal, onActionExit) {
|
|
|
1394
1391
|
});
|
|
1395
1392
|
program.command("print").description("Print aggregated rules").option("--format <format>", "Output format: json|short", parsePrintFormat, "json").option("--short", "Alias for --format short").action(async (opts) => {
|
|
1396
1393
|
const format = opts.short ? "short" : opts.format;
|
|
1397
|
-
await executePrint(cwd, terminal, SNAPSHOT_DIR, format);
|
|
1398
|
-
onActionExit(0);
|
|
1394
|
+
onActionExit(await executePrint(cwd, terminal, SNAPSHOT_DIR, format));
|
|
1399
1395
|
});
|
|
1400
1396
|
program.command("config").description("Print effective evaluated config").option("--format <format>", "Output format: json|short", parsePrintFormat, "json").option("--short", "Alias for --format short").action(async (opts) => {
|
|
1401
1397
|
const format = opts.short ? "short" : opts.format;
|
|
1402
|
-
await executeConfig(cwd, terminal, SNAPSHOT_DIR, format);
|
|
1403
|
-
onActionExit(0);
|
|
1398
|
+
onActionExit(await executeConfig(cwd, terminal, SNAPSHOT_DIR, format));
|
|
1404
1399
|
});
|
|
1405
1400
|
program.command("init").description("Initialize config (file or package.json)").option("--target <target>", "Config target: file|package-json", parseInitTarget).option("--preset <preset>", "Config preset: recommended|minimal|full", parseInitPreset).option("--show-effective", "Print the evaluated config that will be written").option("-f, --force", "Allow init even when an existing config is detected").option("-y, --yes", "Skip prompts and use defaults/options").addHelpText(
|
|
1406
1401
|
"after",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-config-snapshot/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,6 +31,6 @@
|
|
|
31
31
|
"commander": "^14.0.3",
|
|
32
32
|
"debug": "^4.4.3",
|
|
33
33
|
"fast-glob": "^3.3.3",
|
|
34
|
-
"@eslint-config-snapshot/api": "1.
|
|
34
|
+
"@eslint-config-snapshot/api": "1.2.0"
|
|
35
35
|
}
|
|
36
36
|
}
|
package/src/commands/check.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { DEFAULT_CONFIG, findConfigPath, type SnapshotConfig } from '@eslint-config-snapshot/api'
|
|
2
|
-
|
|
3
1
|
import {
|
|
4
2
|
countUniqueWorkspaces,
|
|
5
3
|
decorateDiffLine,
|
|
@@ -8,20 +6,18 @@ import {
|
|
|
8
6
|
summarizeChanges,
|
|
9
7
|
summarizeSnapshots
|
|
10
8
|
} from '../formatters.js'
|
|
11
|
-
import { writeEslintVersionSummary
|
|
9
|
+
import { writeEslintVersionSummary } from '../run-context.js'
|
|
12
10
|
import {
|
|
13
11
|
type BuiltSnapshot,
|
|
14
12
|
compareSnapshotMaps,
|
|
15
|
-
computeCurrentSnapshots,
|
|
16
13
|
type GroupEslintVersions,
|
|
17
|
-
loadStoredSnapshots,
|
|
18
14
|
resolveGroupEslintVersions,
|
|
19
|
-
type SkippedWorkspace,
|
|
20
15
|
type SnapshotDiff,
|
|
21
16
|
writeSnapshots
|
|
22
17
|
} from '../runtime.js'
|
|
23
18
|
import { type TerminalIO } from '../terminal.js'
|
|
24
|
-
import { writeSkippedWorkspaceSummary } from './skipped-workspaces.js'
|
|
19
|
+
import { writeDiscoveredWorkspacesSummary, writeSkippedWorkspaceSummary } from './skipped-workspaces.js'
|
|
20
|
+
import { prepareSnapshotExecution } from './snapshot-executor.js'
|
|
25
21
|
|
|
26
22
|
export type CheckFormat = 'summary' | 'status' | 'diff'
|
|
27
23
|
|
|
@@ -34,50 +30,27 @@ export async function executeCheck(
|
|
|
34
30
|
snapshotDir: string,
|
|
35
31
|
defaultInvocation = false
|
|
36
32
|
): Promise<number> {
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
'Tip: no explicit config found. Using safe built-in defaults. Run `eslint-config-snapshot init` to customize when needed.\n'
|
|
50
|
-
)
|
|
33
|
+
const isStatusFormat = format === 'status'
|
|
34
|
+
const commandLabel = defaultInvocation ? 'check' : `check:${format}`
|
|
35
|
+
const prepared = await prepareSnapshotExecution({
|
|
36
|
+
cwd,
|
|
37
|
+
snapshotDir,
|
|
38
|
+
terminal,
|
|
39
|
+
commandLabel: isStatusFormat ? 'check:status' : commandLabel,
|
|
40
|
+
progressMessage: isStatusFormat ? '' : '🔎 Checking current ESLint configuration...\n',
|
|
41
|
+
showContext: isStatusFormat === false
|
|
42
|
+
})
|
|
43
|
+
if (prepared.ok === false) {
|
|
44
|
+
return prepared.exitCode
|
|
51
45
|
}
|
|
52
46
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
let discoveredWorkspaces: string[] = []
|
|
56
|
-
const allowWorkspaceExtractionFailure = !foundConfig || isDefaultEquivalentConfig(foundConfig.config)
|
|
57
|
-
try {
|
|
58
|
-
currentSnapshots = await computeCurrentSnapshots(cwd, {
|
|
59
|
-
allowWorkspaceExtractionFailure,
|
|
60
|
-
onWorkspacesDiscovered: (workspacesRel) => {
|
|
61
|
-
discoveredWorkspaces = workspacesRel
|
|
62
|
-
},
|
|
63
|
-
onWorkspaceSkipped: (skipped) => {
|
|
64
|
-
skippedWorkspaces.push(skipped)
|
|
65
|
-
}
|
|
66
|
-
})
|
|
67
|
-
} catch (error: unknown) {
|
|
68
|
-
if (!foundConfig && isWorkspaceDiscoveryDefaultsError(error)) {
|
|
69
|
-
terminal.write(
|
|
70
|
-
'Automatic workspace discovery could not complete with defaults.\nRun `eslint-config-snapshot init` to configure workspaces, then run `eslint-config-snapshot --update`.\n'
|
|
71
|
-
)
|
|
72
|
-
return 1
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
throw error
|
|
76
|
-
}
|
|
77
|
-
if (!foundConfig) {
|
|
47
|
+
const { foundConfig, storedSnapshots, currentSnapshots, discoveredWorkspaces, skippedWorkspaces } = prepared
|
|
48
|
+
if (foundConfig === null && isStatusFormat === false) {
|
|
78
49
|
writeDiscoveredWorkspacesSummary(terminal, discoveredWorkspaces)
|
|
79
50
|
}
|
|
80
|
-
|
|
51
|
+
if (isStatusFormat === false) {
|
|
52
|
+
writeSkippedWorkspaceSummary(terminal, cwd, foundConfig?.path, skippedWorkspaces)
|
|
53
|
+
}
|
|
81
54
|
if (storedSnapshots.size === 0) {
|
|
82
55
|
const summary = summarizeSnapshots(currentSnapshots)
|
|
83
56
|
terminal.write(
|
|
@@ -177,25 +150,3 @@ function printWhatChanged(
|
|
|
177
150
|
|
|
178
151
|
return 1
|
|
179
152
|
}
|
|
180
|
-
|
|
181
|
-
function isWorkspaceDiscoveryDefaultsError(error: unknown): boolean {
|
|
182
|
-
const message = error instanceof Error ? error.message : String(error)
|
|
183
|
-
return (
|
|
184
|
-
message.includes('Unable to discover workspaces') ||
|
|
185
|
-
message.includes('Unmatched workspaces') ||
|
|
186
|
-
message.includes('zero-config mode')
|
|
187
|
-
)
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function isDefaultEquivalentConfig(config: SnapshotConfig): boolean {
|
|
191
|
-
return JSON.stringify(config) === JSON.stringify(DEFAULT_CONFIG)
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function writeDiscoveredWorkspacesSummary(terminal: TerminalIO, workspacesRel: string[]): void {
|
|
195
|
-
if (workspacesRel.length === 0) {
|
|
196
|
-
terminal.subtle('Auto-discovered workspaces: none\n')
|
|
197
|
-
return
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
terminal.subtle(`Auto-discovered workspaces (${workspacesRel.length}): ${workspacesRel.join(', ')}\n`)
|
|
201
|
-
}
|
package/src/commands/print.ts
CHANGED
|
@@ -1,25 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { loadConfig } from '@eslint-config-snapshot/api'
|
|
2
2
|
|
|
3
3
|
import { formatShortConfig, formatShortPrint } from '../formatters.js'
|
|
4
|
-
import {
|
|
5
|
-
import { computeCurrentSnapshots, loadStoredSnapshots, resolveWorkspaceAssignments, type WorkspaceAssignments } from '../runtime.js'
|
|
4
|
+
import { resolveWorkspaceAssignments, type WorkspaceAssignments } from '../runtime.js'
|
|
6
5
|
import { type TerminalIO } from '../terminal.js'
|
|
6
|
+
import { prepareSnapshotExecution } from './snapshot-executor.js'
|
|
7
7
|
|
|
8
8
|
export type PrintFormat = 'json' | 'short'
|
|
9
9
|
|
|
10
|
-
export async function executePrint(cwd: string, terminal: TerminalIO, snapshotDir: string, format: PrintFormat): Promise<
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
export async function executePrint(cwd: string, terminal: TerminalIO, snapshotDir: string, format: PrintFormat): Promise<number> {
|
|
11
|
+
const prepared = await prepareSnapshotExecution({
|
|
12
|
+
cwd,
|
|
13
|
+
snapshotDir,
|
|
14
|
+
terminal,
|
|
15
|
+
commandLabel: `print:${format}`,
|
|
16
|
+
progressMessage: '🔎 Checking current ESLint configuration...\n'
|
|
17
|
+
})
|
|
18
|
+
if (!prepared.ok) {
|
|
19
|
+
return prepared.exitCode
|
|
16
20
|
}
|
|
17
|
-
|
|
18
|
-
const currentSnapshots =
|
|
21
|
+
|
|
22
|
+
const { currentSnapshots } = prepared
|
|
19
23
|
|
|
20
24
|
if (format === 'short') {
|
|
21
25
|
terminal.write(formatShortPrint([...currentSnapshots.values()]))
|
|
22
|
-
return
|
|
26
|
+
return 0
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
const output = [...currentSnapshots.values()].map((snapshot) => ({
|
|
@@ -27,15 +31,22 @@ export async function executePrint(cwd: string, terminal: TerminalIO, snapshotDi
|
|
|
27
31
|
rules: snapshot.rules
|
|
28
32
|
}))
|
|
29
33
|
terminal.write(`${JSON.stringify(output, null, 2)}\n`)
|
|
34
|
+
return 0
|
|
30
35
|
}
|
|
31
36
|
|
|
32
|
-
export async function executeConfig(cwd: string, terminal: TerminalIO, snapshotDir: string, format: PrintFormat): Promise<
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
export async function executeConfig(cwd: string, terminal: TerminalIO, snapshotDir: string, format: PrintFormat): Promise<number> {
|
|
38
|
+
const prepared = await prepareSnapshotExecution({
|
|
39
|
+
cwd,
|
|
40
|
+
snapshotDir,
|
|
41
|
+
terminal,
|
|
42
|
+
commandLabel: `config:${format}`,
|
|
43
|
+
progressMessage: '⚙️ Resolving effective runtime configuration...\n'
|
|
44
|
+
})
|
|
45
|
+
if (!prepared.ok) {
|
|
46
|
+
return prepared.exitCode
|
|
38
47
|
}
|
|
48
|
+
|
|
49
|
+
const { foundConfig } = prepared
|
|
39
50
|
const config = await loadConfig(cwd)
|
|
40
51
|
const resolved: WorkspaceAssignments = await resolveWorkspaceAssignments(cwd, config)
|
|
41
52
|
const payload = {
|
|
@@ -52,12 +63,9 @@ export async function executeConfig(cwd: string, terminal: TerminalIO, snapshotD
|
|
|
52
63
|
|
|
53
64
|
if (format === 'short') {
|
|
54
65
|
terminal.write(formatShortConfig(payload))
|
|
55
|
-
return
|
|
66
|
+
return 0
|
|
56
67
|
}
|
|
57
68
|
|
|
58
69
|
terminal.write(`${JSON.stringify(payload, null, 2)}\n`)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
function isDefaultEquivalentConfig(config: SnapshotConfig): boolean {
|
|
62
|
-
return JSON.stringify(config) === JSON.stringify(DEFAULT_CONFIG)
|
|
70
|
+
return 0
|
|
63
71
|
}
|
|
@@ -3,6 +3,15 @@ import path from 'node:path'
|
|
|
3
3
|
import { type SkippedWorkspace } from '../runtime.js'
|
|
4
4
|
import { type TerminalIO } from '../terminal.js'
|
|
5
5
|
|
|
6
|
+
export function writeDiscoveredWorkspacesSummary(terminal: TerminalIO, workspacesRel: string[]): void {
|
|
7
|
+
if (workspacesRel.length === 0) {
|
|
8
|
+
terminal.subtle('Auto-discovered workspaces: none\n')
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
terminal.subtle(`Auto-discovered workspaces (${workspacesRel.length}): ${workspacesRel.join(', ')}\n`)
|
|
13
|
+
}
|
|
14
|
+
|
|
6
15
|
export function writeSkippedWorkspaceSummary(
|
|
7
16
|
terminal: TerminalIO,
|
|
8
17
|
cwd: string,
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { DEFAULT_CONFIG, findConfigPath, type SnapshotConfig } from '@eslint-config-snapshot/api'
|
|
2
|
+
|
|
3
|
+
import { writeRunContextHeader } from '../run-context.js'
|
|
4
|
+
import { type BuiltSnapshot, computeCurrentSnapshots, loadStoredSnapshots, type SkippedWorkspace, type StoredSnapshot } from '../runtime.js'
|
|
5
|
+
import { type TerminalIO } from '../terminal.js'
|
|
6
|
+
|
|
7
|
+
type SnapshotPreparationSuccess = {
|
|
8
|
+
ok: true
|
|
9
|
+
foundConfig: Awaited<ReturnType<typeof findConfigPath>>
|
|
10
|
+
storedSnapshots: Map<string, StoredSnapshot>
|
|
11
|
+
currentSnapshots: Map<string, BuiltSnapshot>
|
|
12
|
+
discoveredWorkspaces: string[]
|
|
13
|
+
skippedWorkspaces: SkippedWorkspace[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type SnapshotPreparationFailure = {
|
|
17
|
+
ok: false
|
|
18
|
+
exitCode: number
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type SnapshotPreparationResult = SnapshotPreparationSuccess | SnapshotPreparationFailure
|
|
22
|
+
|
|
23
|
+
export async function prepareSnapshotExecution(options: {
|
|
24
|
+
cwd: string
|
|
25
|
+
snapshotDir: string
|
|
26
|
+
terminal: TerminalIO
|
|
27
|
+
commandLabel: string
|
|
28
|
+
progressMessage: string
|
|
29
|
+
showContext?: boolean
|
|
30
|
+
}): Promise<SnapshotPreparationResult> {
|
|
31
|
+
const { cwd, snapshotDir, terminal, commandLabel, progressMessage, showContext = true } = options
|
|
32
|
+
|
|
33
|
+
const foundConfig = await findConfigPath(cwd)
|
|
34
|
+
const storedSnapshots = await loadStoredSnapshots(cwd, snapshotDir)
|
|
35
|
+
if (showContext) {
|
|
36
|
+
writeRunContextHeader(terminal, cwd, commandLabel, foundConfig?.path, storedSnapshots)
|
|
37
|
+
}
|
|
38
|
+
if (showContext && terminal.showProgress && progressMessage.length > 0) {
|
|
39
|
+
terminal.subtle(progressMessage)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (showContext && !foundConfig) {
|
|
43
|
+
terminal.subtle(
|
|
44
|
+
'Tip: no explicit config found. Using safe built-in defaults. Run `eslint-config-snapshot init` to customize when needed.\n'
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const skippedWorkspaces: SkippedWorkspace[] = []
|
|
49
|
+
let discoveredWorkspaces: string[] = []
|
|
50
|
+
const allowWorkspaceExtractionFailure = !foundConfig || isDefaultEquivalentConfig(foundConfig.config)
|
|
51
|
+
|
|
52
|
+
let currentSnapshots: Map<string, BuiltSnapshot>
|
|
53
|
+
try {
|
|
54
|
+
currentSnapshots = await computeCurrentSnapshots(cwd, {
|
|
55
|
+
allowWorkspaceExtractionFailure,
|
|
56
|
+
onWorkspacesDiscovered: (workspacesRel) => {
|
|
57
|
+
discoveredWorkspaces = workspacesRel
|
|
58
|
+
},
|
|
59
|
+
onWorkspaceSkipped: (skipped) => {
|
|
60
|
+
skippedWorkspaces.push(skipped)
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
} catch (error: unknown) {
|
|
64
|
+
if (allowWorkspaceExtractionFailure && isWorkspaceDiscoveryDefaultsError(error)) {
|
|
65
|
+
if (showContext) {
|
|
66
|
+
terminal.write(
|
|
67
|
+
'Automatic workspace discovery could not complete with defaults.\nRun `eslint-config-snapshot init` to configure workspaces, then run `eslint-config-snapshot --update`.\n'
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
return { ok: false, exitCode: 1 }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
throw error
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
ok: true,
|
|
78
|
+
foundConfig,
|
|
79
|
+
storedSnapshots,
|
|
80
|
+
currentSnapshots,
|
|
81
|
+
discoveredWorkspaces,
|
|
82
|
+
skippedWorkspaces
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function isWorkspaceDiscoveryDefaultsError(error: unknown): boolean {
|
|
87
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
88
|
+
return (
|
|
89
|
+
message.includes('Unable to discover workspaces') ||
|
|
90
|
+
message.includes('Unmatched workspaces') ||
|
|
91
|
+
message.includes('zero-config mode')
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function isDefaultEquivalentConfig(config: SnapshotConfig): boolean {
|
|
96
|
+
return JSON.stringify(config) === JSON.stringify(DEFAULT_CONFIG)
|
|
97
|
+
}
|
package/src/commands/update.ts
CHANGED
|
@@ -1,49 +1,23 @@
|
|
|
1
|
-
import { DEFAULT_CONFIG, findConfigPath, type SnapshotConfig } from '@eslint-config-snapshot/api'
|
|
2
|
-
|
|
3
1
|
import { countUniqueWorkspaces, formatBaselineSummaryLines, summarizeSnapshots } from '../formatters.js'
|
|
4
|
-
import { writeEslintVersionSummary
|
|
5
|
-
import {
|
|
2
|
+
import { writeEslintVersionSummary } from '../run-context.js'
|
|
3
|
+
import { resolveGroupEslintVersions, writeSnapshots } from '../runtime.js'
|
|
6
4
|
import { type TerminalIO } from '../terminal.js'
|
|
7
|
-
import { writeSkippedWorkspaceSummary } from './skipped-workspaces.js'
|
|
5
|
+
import { writeDiscoveredWorkspacesSummary, writeSkippedWorkspaceSummary } from './skipped-workspaces.js'
|
|
6
|
+
import { prepareSnapshotExecution } from './snapshot-executor.js'
|
|
8
7
|
|
|
9
8
|
export async function executeUpdate(cwd: string, terminal: TerminalIO, snapshotDir: string, printSummary: boolean): Promise<number> {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
const prepared = await prepareSnapshotExecution({
|
|
10
|
+
cwd,
|
|
11
|
+
snapshotDir,
|
|
12
|
+
terminal,
|
|
13
|
+
commandLabel: 'update',
|
|
14
|
+
progressMessage: '🔎 Checking current ESLint configuration...\n'
|
|
15
|
+
})
|
|
16
|
+
if (prepared.ok === false) {
|
|
17
|
+
return prepared.exitCode
|
|
15
18
|
}
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
terminal.subtle(
|
|
19
|
-
'Tip: no explicit config found. Using safe built-in defaults. Run `eslint-config-snapshot init` to customize when needed.\n'
|
|
20
|
-
)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
let currentSnapshots
|
|
24
|
-
const skippedWorkspaces: SkippedWorkspace[] = []
|
|
25
|
-
let discoveredWorkspaces: string[] = []
|
|
26
|
-
const allowWorkspaceExtractionFailure = !foundConfig || isDefaultEquivalentConfig(foundConfig.config)
|
|
27
|
-
try {
|
|
28
|
-
currentSnapshots = await computeCurrentSnapshots(cwd, {
|
|
29
|
-
allowWorkspaceExtractionFailure,
|
|
30
|
-
onWorkspacesDiscovered: (workspacesRel) => {
|
|
31
|
-
discoveredWorkspaces = workspacesRel
|
|
32
|
-
},
|
|
33
|
-
onWorkspaceSkipped: (skipped) => {
|
|
34
|
-
skippedWorkspaces.push(skipped)
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
} catch (error: unknown) {
|
|
38
|
-
if (!foundConfig && isWorkspaceDiscoveryDefaultsError(error)) {
|
|
39
|
-
terminal.write(
|
|
40
|
-
'Automatic workspace discovery could not complete with defaults.\nRun `eslint-config-snapshot init` to configure workspaces, then run `eslint-config-snapshot --update`.\n'
|
|
41
|
-
)
|
|
42
|
-
return 1
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
throw error
|
|
46
|
-
}
|
|
20
|
+
const { foundConfig, storedSnapshots, currentSnapshots, discoveredWorkspaces, skippedWorkspaces } = prepared
|
|
47
21
|
if (!foundConfig) {
|
|
48
22
|
writeDiscoveredWorkspacesSummary(terminal, discoveredWorkspaces)
|
|
49
23
|
}
|
|
@@ -63,25 +37,3 @@ export async function executeUpdate(cwd: string, terminal: TerminalIO, snapshotD
|
|
|
63
37
|
|
|
64
38
|
return 0
|
|
65
39
|
}
|
|
66
|
-
|
|
67
|
-
function isWorkspaceDiscoveryDefaultsError(error: unknown): boolean {
|
|
68
|
-
const message = error instanceof Error ? error.message : String(error)
|
|
69
|
-
return (
|
|
70
|
-
message.includes('Unable to discover workspaces') ||
|
|
71
|
-
message.includes('Unmatched workspaces') ||
|
|
72
|
-
message.includes('zero-config mode')
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function isDefaultEquivalentConfig(config: SnapshotConfig): boolean {
|
|
77
|
-
return JSON.stringify(config) === JSON.stringify(DEFAULT_CONFIG)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function writeDiscoveredWorkspacesSummary(terminal: TerminalIO, workspacesRel: string[]): void {
|
|
81
|
-
if (workspacesRel.length === 0) {
|
|
82
|
-
terminal.subtle('Auto-discovered workspaces: none\n')
|
|
83
|
-
return
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
terminal.subtle(`Auto-discovered workspaces (${workspacesRel.length}): ${workspacesRel.join(', ')}\n`)
|
|
87
|
-
}
|
package/src/index.ts
CHANGED
|
@@ -141,8 +141,7 @@ function createProgram(cwd: string, terminal: TerminalIO, onActionExit: (code: n
|
|
|
141
141
|
.option('--short', 'Alias for --format short')
|
|
142
142
|
.action(async (opts: { format: PrintFormat; short?: boolean }) => {
|
|
143
143
|
const format: PrintFormat = opts.short ? 'short' : opts.format
|
|
144
|
-
await executePrint(cwd, terminal, SNAPSHOT_DIR, format)
|
|
145
|
-
onActionExit(0)
|
|
144
|
+
onActionExit(await executePrint(cwd, terminal, SNAPSHOT_DIR, format))
|
|
146
145
|
})
|
|
147
146
|
|
|
148
147
|
program
|
|
@@ -152,8 +151,7 @@ function createProgram(cwd: string, terminal: TerminalIO, onActionExit: (code: n
|
|
|
152
151
|
.option('--short', 'Alias for --format short')
|
|
153
152
|
.action(async (opts: { format: PrintFormat; short?: boolean }) => {
|
|
154
153
|
const format: PrintFormat = opts.short ? 'short' : opts.format
|
|
155
|
-
await executeConfig(cwd, terminal, SNAPSHOT_DIR, format)
|
|
156
|
-
onActionExit(0)
|
|
154
|
+
onActionExit(await executeConfig(cwd, terminal, SNAPSHOT_DIR, format))
|
|
157
155
|
})
|
|
158
156
|
|
|
159
157
|
program
|