From 044a0622a4b44be612525861090d2bf7c65c6b62 Mon Sep 17 00:00:00 2001 From: ozymandiashh <234437643+ozymandiashh@users.noreply.github.com> Date: Fri, 17 Jul 2026 01:54:28 +0300 Subject: [PATCH] test(electron): isolate dev-resolution fixtures via CODEBURN_DEV_REPO_ROOT Rework of the #681 fix per review: instead of stubbing the real repo dist/cli.js with snapshot-restore, the Vite-dev resolution branch gains a CODEBURN_DEV_REPO_ROOT override (matching the CODEBURN_PATH_DIRS precedent) so the whole fixture lives in a per-test tmpdir. With the env unset the resolution order is byte-identical to before. - covers all three fresh-clone failures on current main, including the resolveTarget dev-repo-beats-bundled case - deletes the snapshot-restore machinery, the parent-path precondition and the beforeAll repo-scanning guard - tests assert both override-set (tmpdir wins) and override-unset behavior Closes #681 --- app/electron/cli.test.ts | 34 ++++++++++++++++++++++++++++++---- app/electron/cli.ts | 19 +++++++++++++------ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/app/electron/cli.test.ts b/app/electron/cli.test.ts index f71789d4..bc72e8bb 100644 --- a/app/electron/cli.test.ts +++ b/app/electron/cli.test.ts @@ -12,6 +12,7 @@ const originalPathDirs = process.env.CODEBURN_PATH_DIRS const originalPathFile = process.env.CODEBURN_CLI_PATH_FILE const originalViteUrl = process.env.VITE_DEV_SERVER_URL const originalBundled = process.env.CODEBURN_BUNDLED_CLI +const originalDevRepoRoot = process.env.CODEBURN_DEV_REPO_ROOT /** Writes an executable node script and points CODEBURN_BIN at it. */ function fakeBin(name: string, body: string): string { @@ -22,6 +23,17 @@ function fakeBin(name: string, body: string): string { return p } +/** Writes the repo CLI under this test's isolated dev-root override. */ +function fakeDevRepoCli(): string { + const repoRoot = join(dir, 'dev-repo') + const p = join(repoRoot, 'dist', 'cli.js') + mkdirSync(dirname(p), { recursive: true }) + writeFileSync(p, '#!/usr/bin/env node\n', { mode: 0o755 }) + chmodSync(p, 0o755) + process.env.CODEBURN_DEV_REPO_ROOT = repoRoot + return p +} + beforeEach(() => { dir = mkdtempSync(join(tmpdir(), 'codeburn-cli-')) }) @@ -37,6 +49,8 @@ afterEach(() => { else process.env.VITE_DEV_SERVER_URL = originalViteUrl if (originalBundled === undefined) delete process.env.CODEBURN_BUNDLED_CLI else process.env.CODEBURN_BUNDLED_CLI = originalBundled + if (originalDevRepoRoot === undefined) delete process.env.CODEBURN_DEV_REPO_ROOT + else process.env.CODEBURN_DEV_REPO_ROOT = originalDevRepoRoot rmSync(dir, { recursive: true, force: true }) }) @@ -46,8 +60,9 @@ describe('resolveCodeburnPath (Vite development)', () => { process.env.CODEBURN_PATH_DIRS = '' process.env.CODEBURN_CLI_PATH_FILE = join(dir, 'no-persisted-path') process.env.VITE_DEV_SERVER_URL = 'http://localhost:5173' + const devBin = fakeDevRepoCli() - expect(resolveCodeburnPath()).toMatch(/dist\/cli\.js$/) + expect(resolveCodeburnPath()).toBe(devBin) }) it('prefers the repo dev CLI over a persisted-path file (stale global) in dev', () => { @@ -63,12 +78,23 @@ describe('resolveCodeburnPath (Vite development)', () => { writeFileSync(persistedFile, persistedTarget) process.env.CODEBURN_CLI_PATH_FILE = persistedFile process.env.VITE_DEV_SERVER_URL = 'http://localhost:5173' + const devBin = fakeDevRepoCli() const resolved = resolveCodeburnPath() - expect(resolved).toMatch(/dist\/cli\.js$/) + expect(resolved).toBe(devBin) expect(resolved).not.toBe(persistedTarget) }) + it('keeps the existing Vite-dev resolution when the dev-root override is unset', () => { + delete process.env.CODEBURN_BIN + delete process.env.CODEBURN_DEV_REPO_ROOT + process.env.CODEBURN_PATH_DIRS = '' + process.env.CODEBURN_CLI_PATH_FILE = join(dir, 'no-persisted-path') + process.env.VITE_DEV_SERVER_URL = 'http://localhost:5173' + + expect(resolveCodeburnPath()).toBeNull() + }) + it('does not return the repo dev CLI outside the Vite dev server', () => { delete process.env.CODEBURN_BIN process.env.CODEBURN_PATH_DIRS = '' @@ -120,10 +146,10 @@ describe('resolveTarget (bundled CLI in the packaged app)', () => { process.env.CODEBURN_CLI_PATH_FILE = join(dir, 'no-persisted-path') process.env.CODEBURN_BUNDLED_CLI = bundledEntry('bundled.js') process.env.VITE_DEV_SERVER_URL = 'http://localhost:5173' + const devBin = fakeDevRepoCli() const target = resolveTarget() - expect(target?.kind).toBe('external') - expect(target && target.kind === 'external' ? target.bin : '').toMatch(/dist\/cli\.js$/) + expect(target).toEqual({ kind: 'external', bin: devBin }) }) it('falls through when CODEBURN_BUNDLED_CLI points at a missing file', () => { diff --git a/app/electron/cli.ts b/app/electron/cli.ts index ccbc461e..0d084cd4 100644 --- a/app/electron/cli.ts +++ b/app/electron/cli.ts @@ -187,12 +187,19 @@ export function resolveTarget(): CliTarget | null { // freshly-built CLI over a stale globally-installed/persisted one, so // newly-added commands (sessions/compare/act JSON) work without CODEBURN_BIN. if (process.env.VITE_DEV_SERVER_URL) { - const devBin = join(__dirname, '..', '..', '..', 'dist', 'cli.js') - if (isExecutableFile(devBin)) return { kind: 'external', bin: devBin } - // Vitest loads this source module from app/electron rather than the emitted - // app/dist/electron directory; keep the same repo CLI discoverable there. - const sourceDevBin = join(__dirname, '..', '..', 'dist', 'cli.js') - if (isExecutableFile(sourceDevBin)) return { kind: 'external', bin: sourceDevBin } + const devRepoRoot = process.env.CODEBURN_DEV_REPO_ROOT + if (devRepoRoot) { + // Test/advanced override, matching CODEBURN_PATH_DIRS: keep dev lookup in an isolated repo root. + const devBin = join(devRepoRoot, 'dist', 'cli.js') + if (isExecutableFile(devBin)) return { kind: 'external', bin: devBin } + } else { + const devBin = join(__dirname, '..', '..', '..', 'dist', 'cli.js') + if (isExecutableFile(devBin)) return { kind: 'external', bin: devBin } + // Vitest loads this source module from app/electron rather than the emitted + // app/dist/electron directory; keep the same repo CLI discoverable there. + const sourceDevBin = join(__dirname, '..', '..', 'dist', 'cli.js') + if (isExecutableFile(sourceDevBin)) return { kind: 'external', bin: sourceDevBin } + } } // Packaged app: main.ts sets CODEBURN_BUNDLED_CLI to resources/cli/dist/cli.js.