Refresh Windows PATH for local preflight probes (#5442)
Co-authored-by: Neil <neil@stably.ai>
This commit is contained in:
parent
1d05e72de3
commit
a32fe5d823
|
|
@ -0,0 +1,12 @@
|
|||
import { mergePersistedWindowsPath } from '../pty/windows-environment-path'
|
||||
|
||||
export function buildLocalPreflightEnv(): NodeJS.ProcessEnv | undefined {
|
||||
if (process.platform !== 'win32') {
|
||||
return undefined
|
||||
}
|
||||
const env = { ...process.env }
|
||||
// Why: newly installed CLIs update persisted Windows Path, but the running
|
||||
// Electron process keeps its old environment until we merge it explicitly.
|
||||
mergePersistedWindowsPath(env)
|
||||
return env
|
||||
}
|
||||
|
|
@ -12,7 +12,8 @@ const {
|
|||
getBitbucketAuthStatusMock,
|
||||
getAzureDevOpsAuthStatusMock,
|
||||
getGiteaAuthStatusMock,
|
||||
resolveCliCommandsMock
|
||||
resolveCliCommandsMock,
|
||||
mergePersistedWindowsPathMock
|
||||
} = vi.hoisted(() => ({
|
||||
handleMock: vi.fn(),
|
||||
execFileMock: vi.fn(),
|
||||
|
|
@ -23,7 +24,8 @@ const {
|
|||
getBitbucketAuthStatusMock: vi.fn(),
|
||||
getAzureDevOpsAuthStatusMock: vi.fn(),
|
||||
getGiteaAuthStatusMock: vi.fn(),
|
||||
resolveCliCommandsMock: vi.fn()
|
||||
resolveCliCommandsMock: vi.fn(),
|
||||
mergePersistedWindowsPathMock: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('electron', () => ({
|
||||
|
|
@ -51,6 +53,10 @@ vi.mock('../codex-cli/command', () => ({
|
|||
resolveCliCommands: resolveCliCommandsMock
|
||||
}))
|
||||
|
||||
vi.mock('../pty/windows-environment-path', () => ({
|
||||
mergePersistedWindowsPath: mergePersistedWindowsPathMock
|
||||
}))
|
||||
|
||||
vi.mock('./ssh', () => ({
|
||||
getActiveMultiplexer: getActiveMultiplexerMock
|
||||
}))
|
||||
|
|
@ -104,6 +110,7 @@ describe('preflight', () => {
|
|||
getBitbucketAuthStatusMock.mockReset()
|
||||
getAzureDevOpsAuthStatusMock.mockReset()
|
||||
getGiteaAuthStatusMock.mockReset()
|
||||
mergePersistedWindowsPathMock.mockReset()
|
||||
// Why: existing tests should keep treating `which` as the only source
|
||||
// unless a case explicitly exercises the install-dir fallback.
|
||||
resolveCliCommandsMock.mockReset()
|
||||
|
|
@ -304,6 +311,34 @@ describe('preflight', () => {
|
|||
)
|
||||
})
|
||||
|
||||
it('uses the persisted Windows Path when probing host CLIs', async () => {
|
||||
Object.defineProperty(process, 'platform', {
|
||||
configurable: true,
|
||||
value: 'win32'
|
||||
})
|
||||
mergePersistedWindowsPathMock.mockImplementation((env: Record<string, string>) => {
|
||||
env.Path = 'C:\\Windows\\System32;C:\\Program Files\\GitHub CLI'
|
||||
})
|
||||
execFileAsyncMock
|
||||
.mockResolvedValueOnce({ stdout: 'git version 2.0.0\n' })
|
||||
.mockResolvedValueOnce({ stdout: 'gh version 2.0.0\n' })
|
||||
.mockResolvedValueOnce({ stdout: 'glab version 1.92.1\n' })
|
||||
.mockResolvedValueOnce({ stdout: 'github.com\n - Active account: true\n' })
|
||||
.mockResolvedValueOnce({ stdout: 'Logged in to gitlab.com\n' })
|
||||
|
||||
const status = await runPreflightCheck()
|
||||
|
||||
expect(status.gh).toEqual({ installed: true, authenticated: true })
|
||||
expect(mergePersistedWindowsPathMock).toHaveBeenCalled()
|
||||
expect(execFileAsyncMock).toHaveBeenNthCalledWith(2, 'gh', ['--version'], {
|
||||
encoding: 'utf-8',
|
||||
timeout: 5000,
|
||||
env: expect.objectContaining({
|
||||
Path: 'C:\\Windows\\System32;C:\\Program Files\\GitHub CLI'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('times out hung WSL preflight probes', async () => {
|
||||
vi.useFakeTimers()
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { getActiveMultiplexer } from './ssh'
|
|||
import { detectWslCommandsOnPath, type WslPreflightTarget } from './preflight-wsl-agent-detection'
|
||||
import { runPreflightCommandInWsl } from './preflight-wsl-command'
|
||||
import { detectCommandsInInstallDirs } from './local-agent-install-dir-detection'
|
||||
import { buildLocalPreflightEnv } from './preflight-local-env'
|
||||
const execFileAsync = promisify(execFile)
|
||||
const PREFLIGHT_COMMAND_TIMEOUT_MS = 5000
|
||||
|
||||
|
|
@ -91,9 +92,11 @@ async function execLocalPreflightCommand(
|
|||
command: string,
|
||||
args: string[]
|
||||
): Promise<PreflightCommandResult> {
|
||||
const env = buildLocalPreflightEnv()
|
||||
const commandPromise = execFileAsync(command, args, {
|
||||
encoding: 'utf-8',
|
||||
timeout: PREFLIGHT_COMMAND_TIMEOUT_MS
|
||||
timeout: PREFLIGHT_COMMAND_TIMEOUT_MS,
|
||||
...(env ? { env } : {})
|
||||
}) as Promise<PreflightCommandResult>
|
||||
|
||||
return withPreflightTimeout(command, commandPromise)
|
||||
|
|
|
|||
Loading…
Reference in New Issue