Skip to content

Commit b3563d3

Browse files
committed
fix(doctor): keep dry-run preflight read-only
1 parent 1d513af commit b3563d3

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

src/commands/doctor-config-flow.test.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
getDoctorConfigInputForTest,
99
runDoctorConfigWithInput,
1010
} from "./doctor-config-flow.test-utils.js";
11+
import { runDoctorConfigPreflight } from "./doctor-config-preflight.js";
1112

1213
type TerminalNote = (message: string, title?: string) => void;
1314

@@ -1509,6 +1510,7 @@ describe("doctor config flow", () => {
15091510
callGatewayMock.mockReset();
15101511
callGatewayMock.mockResolvedValue({});
15111512
runDoctorRepairSequenceMock.mockReset();
1513+
vi.mocked(runDoctorConfigPreflight).mockClear();
15121514
collectDoctorPreviewNotesParamsMock.mockClear();
15131515
collectImplicitFallbackClobberWarningsMock.mockClear();
15141516
collectImplicitFallbackClobberWarningsMock.mockReturnValue([]);
@@ -1529,6 +1531,63 @@ describe("doctor config flow", () => {
15291531
});
15301532
});
15311533

1534+
it("does not run state or legacy config migrations for dry-run previews", async () => {
1535+
await runDoctorConfigWithInput({
1536+
config: {},
1537+
run: ({ confirm }) =>
1538+
loadAndMaybeMigrateDoctorConfig({
1539+
options: { nonInteractive: true, dryRun: true },
1540+
confirm: async () => confirm(),
1541+
}),
1542+
});
1543+
1544+
expect(runDoctorConfigPreflight).toHaveBeenCalledWith(
1545+
expect.objectContaining({
1546+
migrateState: false,
1547+
migrateLegacyConfig: false,
1548+
repairPrefixedConfig: false,
1549+
recoverCorruptTargetStore: false,
1550+
}),
1551+
);
1552+
});
1553+
1554+
it("does not run state or legacy config migrations for diff previews", async () => {
1555+
await runDoctorConfigWithInput({
1556+
config: {},
1557+
run: ({ confirm }) =>
1558+
loadAndMaybeMigrateDoctorConfig({
1559+
options: { nonInteractive: true, diff: true },
1560+
confirm: async () => confirm(),
1561+
}),
1562+
});
1563+
1564+
expect(runDoctorConfigPreflight).toHaveBeenCalledWith(
1565+
expect.objectContaining({
1566+
migrateState: false,
1567+
migrateLegacyConfig: false,
1568+
repairPrefixedConfig: false,
1569+
recoverCorruptTargetStore: false,
1570+
}),
1571+
);
1572+
});
1573+
1574+
it("keeps migrations enabled for repair runs", async () => {
1575+
await runDoctorConfigWithInput({
1576+
config: {},
1577+
repair: true,
1578+
run: loadAndMaybeMigrateDoctorConfig,
1579+
});
1580+
1581+
expect(runDoctorConfigPreflight).toHaveBeenCalledWith(
1582+
expect.objectContaining({
1583+
migrateState: true,
1584+
migrateLegacyConfig: true,
1585+
repairPrefixedConfig: true,
1586+
recoverCorruptTargetStore: true,
1587+
}),
1588+
);
1589+
});
1590+
15321591
it("collects plugin blocker previews from the pre-auto-enable config", async () => {
15331592
await runDoctorConfigWithInput({
15341593
config: {

src/commands/doctor-config-flow.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
noteOpencodeProviderOverrides,
1212
} from "./doctor-config-analysis.js";
1313
import { runDoctorConfigPreflight } from "./doctor-config-preflight.js";
14-
import { normalizeCompatibilityConfigValues } from "./doctor/shared/legacy-config-core-migrate.js";
1514
import type { DoctorOptions, DoctorPrompter } from "./doctor-prompter.js";
1615
import { emitDoctorNotes, sanitizeDoctorNote } from "./doctor/emit-notes.js";
1716
import { finalizeDoctorConfigFlow } from "./doctor/finalize-config-flow.js";
@@ -24,6 +23,7 @@ import {
2423
collectMissingDefaultAccountBindingWarnings,
2524
collectMissingExplicitDefaultAccountWarnings,
2625
} from "./doctor/shared/default-account-warnings.js";
26+
import { normalizeCompatibilityConfigValues } from "./doctor/shared/legacy-config-core-migrate.js";
2727

2828
function hasLegacyInternalHookHandlers(raw: unknown): boolean {
2929
const handlers = (raw as { hooks?: { internal?: { handlers?: unknown } } })?.hooks?.internal
@@ -142,7 +142,10 @@ export async function loadAndMaybeMigrateDoctorConfig(params: {
142142
prompter?: DoctorPrompter;
143143
}) {
144144
const shouldRepair = params.options.repair === true || params.options.yes === true;
145+
const previewOnly = params.options.dryRun === true || params.options.diff === true;
145146
const preflight = await runDoctorConfigPreflight({
147+
migrateState: !previewOnly,
148+
migrateLegacyConfig: !previewOnly,
146149
repairPrefixedConfig: shouldRepair,
147150
recoverCorruptTargetStore: shouldRepair,
148151
});

0 commit comments

Comments
 (0)