@rainy-updates/cli 0.5.7 → 0.6.1
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 +134 -0
- package/README.md +90 -31
- package/dist/bin/cli.js +11 -126
- package/dist/bin/dispatch.js +35 -32
- package/dist/bin/help.js +79 -2
- package/dist/bin/main.d.ts +1 -0
- package/dist/bin/main.js +126 -0
- package/dist/cache/cache.js +13 -11
- package/dist/commands/audit/parser.js +38 -2
- package/dist/commands/audit/runner.js +41 -61
- package/dist/commands/audit/targets.js +13 -13
- package/dist/commands/bisect/oracle.js +31 -11
- package/dist/commands/bisect/parser.js +3 -3
- package/dist/commands/bisect/runner.js +16 -8
- package/dist/commands/changelog/fetcher.js +11 -5
- package/dist/commands/dashboard/parser.js +144 -1
- package/dist/commands/dashboard/runner.d.ts +2 -2
- package/dist/commands/dashboard/runner.js +67 -37
- package/dist/commands/doctor/parser.js +53 -4
- package/dist/commands/doctor/runner.js +2 -2
- package/dist/commands/ga/parser.js +43 -4
- package/dist/commands/ga/runner.js +22 -13
- package/dist/commands/health/parser.js +38 -2
- package/dist/commands/health/runner.js +5 -1
- package/dist/commands/hook/parser.d.ts +2 -0
- package/dist/commands/hook/parser.js +40 -0
- package/dist/commands/hook/runner.d.ts +2 -0
- package/dist/commands/hook/runner.js +174 -0
- package/dist/commands/licenses/parser.js +39 -0
- package/dist/commands/licenses/runner.js +9 -5
- package/dist/commands/resolve/graph/builder.js +5 -1
- package/dist/commands/resolve/parser.js +39 -0
- package/dist/commands/resolve/runner.js +14 -4
- package/dist/commands/review/parser.js +101 -4
- package/dist/commands/review/runner.js +31 -5
- package/dist/commands/snapshot/parser.js +39 -0
- package/dist/commands/snapshot/runner.js +21 -18
- package/dist/commands/snapshot/store.d.ts +0 -12
- package/dist/commands/snapshot/store.js +26 -38
- package/dist/commands/unused/parser.js +39 -0
- package/dist/commands/unused/runner.js +10 -8
- package/dist/commands/unused/scanner.d.ts +2 -1
- package/dist/commands/unused/scanner.js +65 -52
- package/dist/config/loader.d.ts +2 -2
- package/dist/config/loader.js +2 -5
- package/dist/config/policy.js +20 -11
- package/dist/core/analysis/run-silenced.js +0 -1
- package/dist/core/artifacts.js +6 -5
- package/dist/core/baseline.js +3 -5
- package/dist/core/check.js +7 -3
- package/dist/core/ci.js +52 -1
- package/dist/core/decision-plan.d.ts +14 -0
- package/dist/core/decision-plan.js +107 -0
- package/dist/core/doctor/result.js +8 -5
- package/dist/core/fix-pr-batch.js +38 -28
- package/dist/core/fix-pr.js +27 -24
- package/dist/core/init-ci.js +34 -28
- package/dist/core/options.d.ts +4 -1
- package/dist/core/options.js +152 -4
- package/dist/core/review-model.js +3 -0
- package/dist/core/summary.js +6 -0
- package/dist/core/upgrade.js +64 -2
- package/dist/core/verification.d.ts +2 -0
- package/dist/core/verification.js +108 -0
- package/dist/core/warm-cache.js +7 -3
- package/dist/generated/version.d.ts +1 -0
- package/dist/generated/version.js +2 -0
- package/dist/git/scope.d.ts +19 -0
- package/dist/git/scope.js +167 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/output/format.js +15 -0
- package/dist/output/github.js +6 -0
- package/dist/output/sarif.js +12 -18
- package/dist/parsers/package-json.js +2 -4
- package/dist/pm/detect.d.ts +40 -1
- package/dist/pm/detect.js +152 -9
- package/dist/pm/install.d.ts +3 -1
- package/dist/pm/install.js +18 -17
- package/dist/registry/npm.js +34 -76
- package/dist/rup +0 -0
- package/dist/types/index.d.ts +134 -5
- package/dist/ui/tui.d.ts +4 -1
- package/dist/ui/tui.js +156 -67
- package/dist/utils/io.js +5 -6
- package/dist/utils/lockfile.js +24 -19
- package/dist/utils/runtime-paths.d.ts +4 -0
- package/dist/utils/runtime-paths.js +35 -0
- package/dist/utils/runtime.d.ts +7 -0
- package/dist/utils/runtime.js +32 -0
- package/dist/workspace/discover.d.ts +7 -1
- package/dist/workspace/discover.js +67 -54
- package/package.json +24 -19
- package/dist/ui/dashboard/DashboardTUI.d.ts +0 -6
- package/dist/ui/dashboard/DashboardTUI.js +0 -34
- package/dist/ui/dashboard/components/DetailPanel.d.ts +0 -4
- package/dist/ui/dashboard/components/DetailPanel.js +0 -30
- package/dist/ui/dashboard/components/Footer.d.ts +0 -4
- package/dist/ui/dashboard/components/Footer.js +0 -9
- package/dist/ui/dashboard/components/Header.d.ts +0 -4
- package/dist/ui/dashboard/components/Header.js +0 -12
- package/dist/ui/dashboard/components/Sidebar.d.ts +0 -4
- package/dist/ui/dashboard/components/Sidebar.js +0 -23
- package/dist/ui/dashboard/store.d.ts +0 -34
- package/dist/ui/dashboard/store.js +0 -148
package/dist/core/options.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import process from "node:process";
|
|
3
2
|
import { loadConfig } from "../config/loader.js";
|
|
3
|
+
import { getRuntimeCwd } from "../utils/runtime.js";
|
|
4
4
|
const DEFAULT_INCLUDE_KINDS = [
|
|
5
5
|
"dependencies",
|
|
6
6
|
"devDependencies",
|
|
@@ -25,6 +25,7 @@ const KNOWN_COMMANDS = [
|
|
|
25
25
|
"doctor",
|
|
26
26
|
"dashboard",
|
|
27
27
|
"ga",
|
|
28
|
+
"hook",
|
|
28
29
|
];
|
|
29
30
|
export async function parseCliArgs(argv) {
|
|
30
31
|
const firstArg = argv[0];
|
|
@@ -82,8 +83,12 @@ export async function parseCliArgs(argv) {
|
|
|
82
83
|
const { parseGaArgs } = await import("../commands/ga/parser.js");
|
|
83
84
|
return { command, options: parseGaArgs(args) };
|
|
84
85
|
}
|
|
86
|
+
if (command === "hook") {
|
|
87
|
+
const { parseHookArgs } = await import("../commands/hook/parser.js");
|
|
88
|
+
return { command, options: parseHookArgs(args) };
|
|
89
|
+
}
|
|
85
90
|
const base = {
|
|
86
|
-
cwd:
|
|
91
|
+
cwd: getRuntimeCwd(),
|
|
87
92
|
target: "latest",
|
|
88
93
|
filter: undefined,
|
|
89
94
|
reject: undefined,
|
|
@@ -117,11 +122,21 @@ export async function parseCliArgs(argv) {
|
|
|
117
122
|
cooldownDays: undefined,
|
|
118
123
|
prLimit: undefined,
|
|
119
124
|
onlyChanged: false,
|
|
125
|
+
affected: false,
|
|
126
|
+
staged: false,
|
|
127
|
+
baseRef: undefined,
|
|
128
|
+
headRef: undefined,
|
|
129
|
+
sinceRef: undefined,
|
|
120
130
|
ciProfile: "minimal",
|
|
121
131
|
lockfileMode: "preserve",
|
|
122
132
|
interactive: false,
|
|
123
133
|
showImpact: false,
|
|
124
134
|
showHomepage: false,
|
|
135
|
+
decisionPlanFile: undefined,
|
|
136
|
+
verify: "none",
|
|
137
|
+
testCommand: undefined,
|
|
138
|
+
verificationReportFile: undefined,
|
|
139
|
+
ciGate: "check",
|
|
125
140
|
};
|
|
126
141
|
let force = false;
|
|
127
142
|
let initCiMode = "enterprise";
|
|
@@ -452,6 +467,38 @@ export async function parseCliArgs(argv) {
|
|
|
452
467
|
base.onlyChanged = true;
|
|
453
468
|
continue;
|
|
454
469
|
}
|
|
470
|
+
if (current === "--affected") {
|
|
471
|
+
base.affected = true;
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
if (current === "--staged") {
|
|
475
|
+
base.staged = true;
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
if (current === "--base" && next) {
|
|
479
|
+
base.baseRef = next;
|
|
480
|
+
index += 1;
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
if (current === "--base") {
|
|
484
|
+
throw new Error("Missing value for --base");
|
|
485
|
+
}
|
|
486
|
+
if (current === "--head" && next) {
|
|
487
|
+
base.headRef = next;
|
|
488
|
+
index += 1;
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
if (current === "--head") {
|
|
492
|
+
throw new Error("Missing value for --head");
|
|
493
|
+
}
|
|
494
|
+
if (current === "--since" && next) {
|
|
495
|
+
base.sinceRef = next;
|
|
496
|
+
index += 1;
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
499
|
+
if (current === "--since") {
|
|
500
|
+
throw new Error("Missing value for --since");
|
|
501
|
+
}
|
|
455
502
|
if (current === "--interactive") {
|
|
456
503
|
base.interactive = true;
|
|
457
504
|
continue;
|
|
@@ -492,6 +539,54 @@ export async function parseCliArgs(argv) {
|
|
|
492
539
|
if (current === "--file") {
|
|
493
540
|
throw new Error("Missing value for --file");
|
|
494
541
|
}
|
|
542
|
+
if (current === "--plan-file" && next) {
|
|
543
|
+
base.decisionPlanFile = path.resolve(base.cwd, next);
|
|
544
|
+
index += 1;
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
if (current === "--plan-file") {
|
|
548
|
+
throw new Error("Missing value for --plan-file");
|
|
549
|
+
}
|
|
550
|
+
if (current === "--from-plan" && next) {
|
|
551
|
+
base.decisionPlanFile = path.resolve(base.cwd, next);
|
|
552
|
+
index += 1;
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
if (current === "--from-plan") {
|
|
556
|
+
throw new Error("Missing value for --from-plan");
|
|
557
|
+
}
|
|
558
|
+
if (current === "--verify" && next) {
|
|
559
|
+
base.verify = ensureVerificationMode(next);
|
|
560
|
+
index += 1;
|
|
561
|
+
continue;
|
|
562
|
+
}
|
|
563
|
+
if (current === "--verify") {
|
|
564
|
+
throw new Error("Missing value for --verify");
|
|
565
|
+
}
|
|
566
|
+
if (current === "--test-command" && next) {
|
|
567
|
+
base.testCommand = next;
|
|
568
|
+
index += 1;
|
|
569
|
+
continue;
|
|
570
|
+
}
|
|
571
|
+
if (current === "--test-command") {
|
|
572
|
+
throw new Error("Missing value for --test-command");
|
|
573
|
+
}
|
|
574
|
+
if (current === "--verification-report-file" && next) {
|
|
575
|
+
base.verificationReportFile = path.resolve(base.cwd, next);
|
|
576
|
+
index += 1;
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
579
|
+
if (current === "--verification-report-file") {
|
|
580
|
+
throw new Error("Missing value for --verification-report-file");
|
|
581
|
+
}
|
|
582
|
+
if (current === "--gate" && next) {
|
|
583
|
+
base.ciGate = ensureCiGate(next);
|
|
584
|
+
index += 1;
|
|
585
|
+
continue;
|
|
586
|
+
}
|
|
587
|
+
if (current === "--gate") {
|
|
588
|
+
throw new Error("Missing value for --gate");
|
|
589
|
+
}
|
|
495
590
|
if (current.startsWith("-")) {
|
|
496
591
|
throw new Error(`Unknown option: ${current}`);
|
|
497
592
|
}
|
|
@@ -526,6 +621,7 @@ export async function parseCliArgs(argv) {
|
|
|
526
621
|
install: args.includes("--install") || resolvedConfig.install === true,
|
|
527
622
|
packageManager: cliPm === "auto" ? (configPm ?? "auto") : cliPm,
|
|
528
623
|
sync: args.includes("--sync") || resolvedConfig.sync === true,
|
|
624
|
+
fromPlanFile: base.decisionPlanFile,
|
|
529
625
|
};
|
|
530
626
|
return { command, options: upgradeOptions };
|
|
531
627
|
}
|
|
@@ -672,6 +768,21 @@ function applyConfig(base, config) {
|
|
|
672
768
|
if (typeof config.onlyChanged === "boolean") {
|
|
673
769
|
base.onlyChanged = config.onlyChanged;
|
|
674
770
|
}
|
|
771
|
+
if (typeof config.affected === "boolean") {
|
|
772
|
+
base.affected = config.affected;
|
|
773
|
+
}
|
|
774
|
+
if (typeof config.staged === "boolean") {
|
|
775
|
+
base.staged = config.staged;
|
|
776
|
+
}
|
|
777
|
+
if (typeof config.baseRef === "string" && config.baseRef.length > 0) {
|
|
778
|
+
base.baseRef = config.baseRef;
|
|
779
|
+
}
|
|
780
|
+
if (typeof config.headRef === "string" && config.headRef.length > 0) {
|
|
781
|
+
base.headRef = config.headRef;
|
|
782
|
+
}
|
|
783
|
+
if (typeof config.sinceRef === "string" && config.sinceRef.length > 0) {
|
|
784
|
+
base.sinceRef = config.sinceRef;
|
|
785
|
+
}
|
|
675
786
|
if (typeof config.ciProfile === "string") {
|
|
676
787
|
base.ciProfile = ensureCiProfile(config.ciProfile);
|
|
677
788
|
}
|
|
@@ -687,16 +798,35 @@ function applyConfig(base, config) {
|
|
|
687
798
|
if (typeof config.showHomepage === "boolean") {
|
|
688
799
|
base.showHomepage = config.showHomepage;
|
|
689
800
|
}
|
|
801
|
+
if (typeof config.decisionPlanFile === "string") {
|
|
802
|
+
base.decisionPlanFile = path.resolve(base.cwd, config.decisionPlanFile);
|
|
803
|
+
}
|
|
804
|
+
if (typeof config.verify === "string") {
|
|
805
|
+
base.verify = ensureVerificationMode(config.verify);
|
|
806
|
+
}
|
|
807
|
+
if (typeof config.testCommand === "string") {
|
|
808
|
+
base.testCommand = config.testCommand;
|
|
809
|
+
}
|
|
810
|
+
if (typeof config.verificationReportFile === "string") {
|
|
811
|
+
base.verificationReportFile = path.resolve(base.cwd, config.verificationReportFile);
|
|
812
|
+
}
|
|
813
|
+
if (typeof config.ciGate === "string") {
|
|
814
|
+
base.ciGate = ensureCiGate(config.ciGate);
|
|
815
|
+
}
|
|
690
816
|
}
|
|
691
817
|
function parsePackageManager(args) {
|
|
692
818
|
const index = args.indexOf("--pm");
|
|
693
819
|
if (index === -1)
|
|
694
820
|
return "auto";
|
|
695
821
|
const value = args[index + 1] ?? "auto";
|
|
696
|
-
if (value === "auto" ||
|
|
822
|
+
if (value === "auto" ||
|
|
823
|
+
value === "bun" ||
|
|
824
|
+
value === "npm" ||
|
|
825
|
+
value === "pnpm" ||
|
|
826
|
+
value === "yarn") {
|
|
697
827
|
return value;
|
|
698
828
|
}
|
|
699
|
-
throw new Error("--pm must be auto, npm or
|
|
829
|
+
throw new Error("--pm must be auto, bun, npm, pnpm or yarn");
|
|
700
830
|
}
|
|
701
831
|
function ensureTarget(value) {
|
|
702
832
|
if (value === "patch" ||
|
|
@@ -800,3 +930,21 @@ export function ensureRiskLevel(value) {
|
|
|
800
930
|
}
|
|
801
931
|
throw new Error("--risk must be critical, high, medium or low");
|
|
802
932
|
}
|
|
933
|
+
function ensureVerificationMode(value) {
|
|
934
|
+
if (value === "none" ||
|
|
935
|
+
value === "install" ||
|
|
936
|
+
value === "test" ||
|
|
937
|
+
value === "install,test") {
|
|
938
|
+
return value;
|
|
939
|
+
}
|
|
940
|
+
throw new Error("--verify must be none, install, test or install,test");
|
|
941
|
+
}
|
|
942
|
+
function ensureCiGate(value) {
|
|
943
|
+
if (value === "check" ||
|
|
944
|
+
value === "doctor" ||
|
|
945
|
+
value === "review" ||
|
|
946
|
+
value === "upgrade") {
|
|
947
|
+
return value;
|
|
948
|
+
}
|
|
949
|
+
throw new Error("--gate must be check, doctor, review or upgrade");
|
|
950
|
+
}
|
|
@@ -109,6 +109,9 @@ export function renderReviewResult(review) {
|
|
|
109
109
|
}
|
|
110
110
|
lines.push("");
|
|
111
111
|
lines.push(`Summary: ${review.summary.updatesFound} updates, riskPackages=${review.summary.riskPackages ?? 0}, securityPackages=${review.summary.securityPackages ?? 0}, peerConflictPackages=${review.summary.peerConflictPackages ?? 0}`);
|
|
112
|
+
if (review.summary.decisionPlan) {
|
|
113
|
+
lines.push(`DecisionPlan: ${review.summary.decisionPlan}`);
|
|
114
|
+
}
|
|
112
115
|
return lines.join("\n");
|
|
113
116
|
}
|
|
114
117
|
function matchesReviewFilters(item, options) {
|
package/dist/core/summary.js
CHANGED
|
@@ -69,6 +69,12 @@ export function createSummary(input) {
|
|
|
69
69
|
primaryFindingCode: undefined,
|
|
70
70
|
primaryFindingCategory: undefined,
|
|
71
71
|
nextActionReason: undefined,
|
|
72
|
+
suggestedCommand: undefined,
|
|
73
|
+
decisionPlan: undefined,
|
|
74
|
+
interactiveSurface: undefined,
|
|
75
|
+
queueFocus: undefined,
|
|
76
|
+
verificationState: "not-run",
|
|
77
|
+
verificationFailures: 0,
|
|
72
78
|
};
|
|
73
79
|
}
|
|
74
80
|
export function finalizeSummary(summary) {
|
package/dist/core/upgrade.js
CHANGED
|
@@ -5,17 +5,25 @@ import { detectPackageManager } from "../pm/detect.js";
|
|
|
5
5
|
import { applyRangeStyle, parseVersion, compareVersions } from "../utils/semver.js";
|
|
6
6
|
import { buildWorkspaceGraph } from "../workspace/graph.js";
|
|
7
7
|
import { captureLockfileSnapshot, changedLockfiles, validateLockfileMode } from "../utils/lockfile.js";
|
|
8
|
+
import { createSummary, finalizeSummary } from "./summary.js";
|
|
9
|
+
import { readDecisionPlan, selectedUpdatesFromPlan } from "./decision-plan.js";
|
|
10
|
+
import { runVerification } from "./verification.js";
|
|
8
11
|
export async function upgrade(options) {
|
|
9
12
|
validateLockfileMode(options.lockfileMode, options.install);
|
|
10
13
|
const lockfilesBefore = await captureLockfileSnapshot(options.cwd);
|
|
11
|
-
const checkResult =
|
|
14
|
+
const checkResult = options.fromPlanFile
|
|
15
|
+
? await createUpgradeResultFromPlan(options)
|
|
16
|
+
: await check(options);
|
|
12
17
|
if (checkResult.updates.length === 0) {
|
|
13
18
|
return {
|
|
14
19
|
...checkResult,
|
|
15
20
|
changed: false,
|
|
16
21
|
};
|
|
17
22
|
}
|
|
18
|
-
|
|
23
|
+
const selectedUpdates = options.fromPlanFile
|
|
24
|
+
? checkResult.updates
|
|
25
|
+
: checkResult.updates;
|
|
26
|
+
await applySelectedUpdates(options, selectedUpdates);
|
|
19
27
|
const lockfileChanges = await changedLockfiles(options.cwd, lockfilesBefore);
|
|
20
28
|
if (lockfileChanges.length > 0 && (options.lockfileMode === "preserve" || options.lockfileMode === "error")) {
|
|
21
29
|
throw new Error(`Lockfile changes detected in ${options.lockfileMode} mode: ${lockfileChanges.join(", ")}`);
|
|
@@ -23,6 +31,18 @@ export async function upgrade(options) {
|
|
|
23
31
|
if (lockfileChanges.length > 0 && options.lockfileMode === "update") {
|
|
24
32
|
checkResult.warnings.push(`Lockfiles changed: ${lockfileChanges.map((item) => item.split("/").pop()).join(", ")}`);
|
|
25
33
|
}
|
|
34
|
+
if (options.verify !== "none") {
|
|
35
|
+
const verification = await runVerification(options);
|
|
36
|
+
checkResult.summary.verificationState = verification.passed
|
|
37
|
+
? "passed"
|
|
38
|
+
: "failed";
|
|
39
|
+
checkResult.summary.verificationFailures = verification.checks.filter((check) => !check.passed).length;
|
|
40
|
+
if (!verification.passed) {
|
|
41
|
+
checkResult.errors.push(...verification.checks
|
|
42
|
+
.filter((check) => !check.passed)
|
|
43
|
+
.map((check) => `Verification failed for ${check.name}: ${check.error ?? check.command}`));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
26
46
|
return {
|
|
27
47
|
...checkResult,
|
|
28
48
|
changed: true,
|
|
@@ -59,6 +79,48 @@ export async function applySelectedUpdates(options, updates) {
|
|
|
59
79
|
await installDependencies(options.cwd, options.packageManager, detected);
|
|
60
80
|
}
|
|
61
81
|
}
|
|
82
|
+
async function createUpgradeResultFromPlan(options) {
|
|
83
|
+
if (!options.fromPlanFile) {
|
|
84
|
+
throw new Error("Missing decision plan file.");
|
|
85
|
+
}
|
|
86
|
+
const plan = await readDecisionPlan(options.fromPlanFile);
|
|
87
|
+
const packageManager = await detectPackageManager(options.cwd);
|
|
88
|
+
const updates = selectedUpdatesFromPlan(plan);
|
|
89
|
+
const packagePaths = Array.from(new Set(updates.map((update) => update.packagePath))).sort((left, right) => left.localeCompare(right));
|
|
90
|
+
const summary = finalizeSummary(createSummary({
|
|
91
|
+
scannedPackages: packagePaths.length,
|
|
92
|
+
totalDependencies: updates.length,
|
|
93
|
+
checkedDependencies: updates.length,
|
|
94
|
+
updatesFound: updates.length,
|
|
95
|
+
upgraded: 0,
|
|
96
|
+
skipped: 0,
|
|
97
|
+
warmedPackages: 0,
|
|
98
|
+
errors: [],
|
|
99
|
+
warnings: [],
|
|
100
|
+
durations: {
|
|
101
|
+
totalMs: 0,
|
|
102
|
+
discoveryMs: 0,
|
|
103
|
+
registryMs: 0,
|
|
104
|
+
cacheMs: 0,
|
|
105
|
+
},
|
|
106
|
+
}));
|
|
107
|
+
summary.decisionPlan = options.fromPlanFile;
|
|
108
|
+
summary.interactiveSurface = plan.interactiveSurface;
|
|
109
|
+
summary.queueFocus = plan.focus;
|
|
110
|
+
summary.updatesFound = updates.length;
|
|
111
|
+
return {
|
|
112
|
+
projectPath: options.cwd,
|
|
113
|
+
packagePaths,
|
|
114
|
+
packageManager,
|
|
115
|
+
target: plan.target,
|
|
116
|
+
timestamp: new Date().toISOString(),
|
|
117
|
+
summary,
|
|
118
|
+
updates,
|
|
119
|
+
errors: [],
|
|
120
|
+
warnings: [],
|
|
121
|
+
changed: false,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
62
124
|
function applyWorkspaceSync(manifestsByPath, orderedPaths, localPackageNames, includeKinds, updates) {
|
|
63
125
|
const desiredByPackage = new Map();
|
|
64
126
|
for (const update of updates) {
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { buildInstallInvocation, buildTestCommand, createPackageManagerProfile, detectPackageManagerDetails, } from "../pm/detect.js";
|
|
2
|
+
import { installDependencies } from "../pm/install.js";
|
|
3
|
+
import { stableStringify } from "../utils/stable-json.js";
|
|
4
|
+
import { writeFileAtomic } from "../utils/io.js";
|
|
5
|
+
import { readEnv } from "../utils/runtime.js";
|
|
6
|
+
export async function runVerification(options) {
|
|
7
|
+
const mode = options.verify;
|
|
8
|
+
if (mode === "none") {
|
|
9
|
+
const result = {
|
|
10
|
+
mode,
|
|
11
|
+
passed: true,
|
|
12
|
+
checks: [],
|
|
13
|
+
};
|
|
14
|
+
await maybeWriteVerificationReport(options.verificationReportFile, result);
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
const checks = [];
|
|
18
|
+
const detected = await detectPackageManagerDetails(options.cwd);
|
|
19
|
+
const profile = createPackageManagerProfile(options.packageManager, detected, "bun");
|
|
20
|
+
if (includesInstall(mode)) {
|
|
21
|
+
const installInvocation = buildInstallInvocation(profile);
|
|
22
|
+
checks.push(await runCheck("install", installInvocation.display, async () => {
|
|
23
|
+
await installDependencies(options.cwd, options.packageManager, detected);
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
if (includesTest(mode)) {
|
|
27
|
+
const command = options.testCommand ??
|
|
28
|
+
defaultTestCommand(profile);
|
|
29
|
+
checks.push(await runShellCheck(options.cwd, command));
|
|
30
|
+
}
|
|
31
|
+
const result = {
|
|
32
|
+
mode,
|
|
33
|
+
passed: checks.every((check) => check.passed),
|
|
34
|
+
checks,
|
|
35
|
+
};
|
|
36
|
+
await maybeWriteVerificationReport(options.verificationReportFile, result);
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
function includesInstall(mode) {
|
|
40
|
+
return mode === "install" || mode === "install,test";
|
|
41
|
+
}
|
|
42
|
+
function includesTest(mode) {
|
|
43
|
+
return mode === "test" || mode === "install,test";
|
|
44
|
+
}
|
|
45
|
+
function defaultTestCommand(profile) {
|
|
46
|
+
return buildTestCommand(profile);
|
|
47
|
+
}
|
|
48
|
+
async function runShellCheck(cwd, command) {
|
|
49
|
+
const startedAt = Date.now();
|
|
50
|
+
try {
|
|
51
|
+
const shell = readEnv("SHELL") || "sh";
|
|
52
|
+
const proc = Bun.spawn([shell, "-lc", command], {
|
|
53
|
+
cwd,
|
|
54
|
+
stdin: "inherit",
|
|
55
|
+
stdout: "inherit",
|
|
56
|
+
stderr: "inherit",
|
|
57
|
+
});
|
|
58
|
+
const exitCode = await proc.exited;
|
|
59
|
+
return {
|
|
60
|
+
name: "test",
|
|
61
|
+
command,
|
|
62
|
+
passed: exitCode === 0,
|
|
63
|
+
exitCode,
|
|
64
|
+
durationMs: Math.max(0, Date.now() - startedAt),
|
|
65
|
+
error: exitCode === 0
|
|
66
|
+
? undefined
|
|
67
|
+
: `${command} failed with exit code ${exitCode}`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
return {
|
|
72
|
+
name: "test",
|
|
73
|
+
command,
|
|
74
|
+
passed: false,
|
|
75
|
+
exitCode: 1,
|
|
76
|
+
durationMs: Math.max(0, Date.now() - startedAt),
|
|
77
|
+
error: String(error),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function runCheck(name, command, action) {
|
|
82
|
+
const startedAt = Date.now();
|
|
83
|
+
try {
|
|
84
|
+
await action();
|
|
85
|
+
return {
|
|
86
|
+
name,
|
|
87
|
+
command,
|
|
88
|
+
passed: true,
|
|
89
|
+
exitCode: 0,
|
|
90
|
+
durationMs: Math.max(0, Date.now() - startedAt),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
return {
|
|
95
|
+
name,
|
|
96
|
+
command,
|
|
97
|
+
passed: false,
|
|
98
|
+
exitCode: 1,
|
|
99
|
+
durationMs: Math.max(0, Date.now() - startedAt),
|
|
100
|
+
error: String(error),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function maybeWriteVerificationReport(filePath, result) {
|
|
105
|
+
if (!filePath)
|
|
106
|
+
return;
|
|
107
|
+
await writeFileAtomic(filePath, stableStringify(result, 2) + "\n");
|
|
108
|
+
}
|
package/dist/core/warm-cache.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import process from "node:process";
|
|
2
1
|
import { collectDependencies, readManifest } from "../parsers/package-json.js";
|
|
3
2
|
import { matchesPattern } from "../utils/pattern.js";
|
|
4
3
|
import { VersionCache } from "../cache/cache.js";
|
|
@@ -7,6 +6,7 @@ import { detectPackageManager } from "../pm/detect.js";
|
|
|
7
6
|
import { discoverPackageDirs } from "../workspace/discover.js";
|
|
8
7
|
import { createSummary, finalizeSummary } from "./summary.js";
|
|
9
8
|
import { formatClassifiedMessage } from "./errors.js";
|
|
9
|
+
import { writeStdout } from "../utils/runtime.js";
|
|
10
10
|
export async function warmCache(options) {
|
|
11
11
|
const startedAt = Date.now();
|
|
12
12
|
let discoveryMs = 0;
|
|
@@ -14,7 +14,11 @@ export async function warmCache(options) {
|
|
|
14
14
|
let registryMs = 0;
|
|
15
15
|
const discoveryStartedAt = Date.now();
|
|
16
16
|
const packageManager = await detectPackageManager(options.cwd);
|
|
17
|
-
const packageDirs = await discoverPackageDirs(options.cwd, options.workspace
|
|
17
|
+
const packageDirs = await discoverPackageDirs(options.cwd, options.workspace, {
|
|
18
|
+
git: options,
|
|
19
|
+
includeKinds: options.includeKinds,
|
|
20
|
+
includeDependents: options.affected === true,
|
|
21
|
+
});
|
|
18
22
|
discoveryMs += Date.now() - discoveryStartedAt;
|
|
19
23
|
const cache = await VersionCache.create();
|
|
20
24
|
const registryClient = new NpmRegistryClient(options.cwd, {
|
|
@@ -39,7 +43,7 @@ export async function warmCache(options) {
|
|
|
39
43
|
if (!options.stream)
|
|
40
44
|
return;
|
|
41
45
|
streamedEvents += 1;
|
|
42
|
-
|
|
46
|
+
writeStdout(`${message}\n`);
|
|
43
47
|
};
|
|
44
48
|
for (const packageDir of packageDirs) {
|
|
45
49
|
try {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CLI_VERSION = "0.6.1";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DependencyKind } from "../types/index.js";
|
|
2
|
+
export interface GitScopeOptions {
|
|
3
|
+
onlyChanged?: boolean;
|
|
4
|
+
affected?: boolean;
|
|
5
|
+
staged?: boolean;
|
|
6
|
+
baseRef?: string;
|
|
7
|
+
headRef?: string;
|
|
8
|
+
sinceRef?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ScopedPackageDirsResult {
|
|
11
|
+
packageDirs: string[];
|
|
12
|
+
warnings: string[];
|
|
13
|
+
changedFiles: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function hasGitScope(options: GitScopeOptions): boolean;
|
|
16
|
+
export declare function scopePackageDirsByGit(cwd: string, packageDirs: string[], options: GitScopeOptions, config?: {
|
|
17
|
+
includeKinds?: DependencyKind[];
|
|
18
|
+
includeDependents?: boolean;
|
|
19
|
+
}): Promise<ScopedPackageDirsResult>;
|