mirror of
https://github.com/stablyai/orca.git
synced 2026-10-20 16:03:20 +00:00
110 files carried an eslint/oxlint-disable max-lines directive but are already under the default max-lines budget (300 .ts / 400 .tsx / 600 .mjs / 800 test), so the suppression is dead. Removing it restores real max-lines coverage on these files with zero behavior change. Each removed directive had max-lines as its only rule; verified via a full oxlint run (0 max-lines violations, 0 new errors). Diff is pure deletions (200 lines, 0 additions) — no code touched. Co-authored-by: Orca <help@stably.ai>
353 lines
12 KiB
TypeScript
353 lines
12 KiB
TypeScript
import type { CliInstallStatus } from '../../shared/cli-install-types'
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
const execFileMock = vi.hoisted(() => vi.fn())
|
|
|
|
vi.mock('node:child_process', () => ({
|
|
execFile: execFileMock
|
|
}))
|
|
|
|
import { WslCliInstaller, _internals } from './wsl-cli-installer'
|
|
|
|
function makeHostStatus(
|
|
launcherPath = 'C:\\Users\\me\\AppData\\Local\\Programs\\Orca\\resources\\bin\\orca.cmd'
|
|
) {
|
|
return {
|
|
platform: 'win32',
|
|
commandName: 'orca',
|
|
commandPath: 'C:\\Users\\me\\AppData\\Local\\Programs\\Orca\\bin\\orca.cmd',
|
|
pathDirectory: 'C:\\Users\\me\\AppData\\Local\\Programs\\Orca\\bin',
|
|
pathConfigured: true,
|
|
launcherPath,
|
|
installMethod: 'wrapper',
|
|
supported: true,
|
|
state: 'installed',
|
|
currentTarget: launcherPath,
|
|
unsupportedReason: null,
|
|
detail: null
|
|
} satisfies CliInstallStatus
|
|
}
|
|
|
|
function createWslRunner(initialFile: string | null = null, pathIncludesLocalBin = true) {
|
|
const commandPath = '/home/alice/.local/bin/orca-ide'
|
|
const bridgePath = '/home/alice/.local/share/orca/orca-wsl-bridge.ps1'
|
|
const files = new Map<string, string>()
|
|
if (initialFile !== null) {
|
|
files.set(commandPath, initialFile)
|
|
files.set(bridgePath, _internals.buildWslBridgeScript())
|
|
}
|
|
const calls: string[] = []
|
|
const runner = vi.fn(async (_distro: string, command: string) => {
|
|
calls.push(command)
|
|
if (command.includes('printf %s "$HOME"')) {
|
|
return '/home/alice'
|
|
}
|
|
if (command.includes('case ":$PATH:"')) {
|
|
return pathIncludesLocalBin ? 'yes' : 'no'
|
|
}
|
|
if (command.includes('cat > "$command_tmp"')) {
|
|
const launcher =
|
|
command.match(/cat > "\$command_tmp" <<'ORCA_WSL_CLI'\n([\s\S]*)\nORCA_WSL_CLI/)?.[1] ?? ''
|
|
const bridge =
|
|
command.match(
|
|
/cat > "\$bridge_tmp" <<'ORCA_WSL_BRIDGE'\n([\s\S]*)\nORCA_WSL_BRIDGE/
|
|
)?.[1] ?? ''
|
|
files.set(commandPath, launcher)
|
|
files.set(bridgePath, bridge)
|
|
return ''
|
|
}
|
|
if (command.includes('command -v powershell.exe')) {
|
|
return 'yes'
|
|
}
|
|
if (command.includes('rm -f')) {
|
|
if (
|
|
files.has(bridgePath) &&
|
|
!files.get(bridgePath)?.includes('# Orca managed WSL CLI PowerShell bridge')
|
|
) {
|
|
throw new Error('__ORCA_CONFLICT__')
|
|
}
|
|
files.delete(commandPath)
|
|
files.delete(bridgePath)
|
|
return ''
|
|
}
|
|
if (command.includes('cat ')) {
|
|
if (command.includes(commandPath)) {
|
|
return files.get(commandPath) ?? '__ORCA_MISSING__'
|
|
}
|
|
if (command.includes(bridgePath)) {
|
|
return files.get(bridgePath) ?? '__ORCA_MISSING__'
|
|
}
|
|
}
|
|
throw new Error(`Unexpected WSL command: ${command}`)
|
|
})
|
|
return {
|
|
runner,
|
|
calls,
|
|
getBridge: () => files.get(bridgePath) ?? null,
|
|
getFile: () => files.get(commandPath) ?? null
|
|
}
|
|
}
|
|
|
|
describe('WslCliInstaller', () => {
|
|
beforeEach(() => {
|
|
execFileMock.mockReset()
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers()
|
|
})
|
|
|
|
it('installs a WSL launcher that forwards to the Windows Orca launcher', async () => {
|
|
const wsl = createWslRunner()
|
|
const installer = new WslCliInstaller({
|
|
platform: 'win32',
|
|
distro: 'Ubuntu',
|
|
hostInstaller: { getStatus: async () => makeHostStatus() },
|
|
wslRunner: wsl.runner
|
|
})
|
|
|
|
await expect(installer.getStatus()).resolves.toMatchObject({
|
|
state: 'not_installed',
|
|
commandPath: '/home/alice/.local/bin/orca-ide'
|
|
})
|
|
|
|
const installed = await installer.install()
|
|
|
|
expect(installed).toMatchObject({
|
|
state: 'installed',
|
|
pathConfigured: true,
|
|
launcherPath: 'C:\\Users\\me\\AppData\\Local\\Programs\\Orca\\resources\\bin\\orca.cmd'
|
|
})
|
|
expect(wsl.getFile()).toBe(
|
|
_internals.buildWslLauncher(
|
|
'C:\\Users\\me\\AppData\\Local\\Programs\\Orca\\resources\\bin\\orca.cmd',
|
|
'/home/alice/.local/share/orca/orca-wsl-bridge.ps1'
|
|
)
|
|
)
|
|
expect(wsl.getBridge()).toBe(_internals.buildWslBridgeScript())
|
|
const installCommand = wsl.calls.find((command) => command.includes('cat > "$command_tmp"'))
|
|
expect(installCommand).toContain("legacy_command_path='/home/alice/.local/bin/orca'")
|
|
expect(installCommand).toContain('rm -f "$legacy_command_path"')
|
|
})
|
|
|
|
it('derives the shared WSL bridge path for current and legacy command names', () => {
|
|
expect(_internals.getBridgePathFromCommandPath('/home/alice/.local/bin/orca-ide')).toBe(
|
|
'/home/alice/.local/share/orca/orca-wsl-bridge.ps1'
|
|
)
|
|
expect(_internals.getBridgePathFromCommandPath('/home/alice/.local/bin/orca')).toBe(
|
|
'/home/alice/.local/share/orca/orca-wsl-bridge.ps1'
|
|
)
|
|
})
|
|
|
|
it('reports installed WSL launchers whose bin directory is missing from PATH', async () => {
|
|
const launcher = _internals.buildWslLauncher(
|
|
'C:\\Orca\\orca.cmd',
|
|
'/home/alice/.local/share/orca/orca-wsl-bridge.ps1'
|
|
)
|
|
const wsl = createWslRunner(launcher, false)
|
|
const installer = new WslCliInstaller({
|
|
platform: 'win32',
|
|
distro: 'Ubuntu',
|
|
hostInstaller: { getStatus: async () => makeHostStatus('C:\\Orca\\orca.cmd') },
|
|
wslRunner: wsl.runner
|
|
})
|
|
|
|
await expect(installer.getStatus()).resolves.toMatchObject({
|
|
state: 'installed',
|
|
pathConfigured: false,
|
|
detail: expect.stringContaining('not on PATH')
|
|
})
|
|
})
|
|
|
|
it('accepts current managed WSL scripts with an extra heredoc trailing newline', async () => {
|
|
const launcher = `${_internals.buildWslLauncher(
|
|
'C:\\Orca\\orca.cmd',
|
|
'/home/alice/.local/share/orca/orca-wsl-bridge.ps1'
|
|
)}\n`
|
|
const wsl = createWslRunner(launcher)
|
|
const installer = new WslCliInstaller({
|
|
platform: 'win32',
|
|
distro: 'Ubuntu',
|
|
hostInstaller: { getStatus: async () => makeHostStatus('C:\\Orca\\orca.cmd') },
|
|
wslRunner: async (distro, command) => {
|
|
if (command.includes('cat /home/alice/.local/share/orca/orca-wsl-bridge.ps1')) {
|
|
return `${_internals.buildWslBridgeScript()}\n`
|
|
}
|
|
return wsl.runner(distro, command)
|
|
}
|
|
})
|
|
|
|
await expect(installer.getStatus()).resolves.toMatchObject({
|
|
state: 'installed',
|
|
currentTarget: 'C:\\Orca\\orca.cmd'
|
|
})
|
|
})
|
|
|
|
it('refuses to replace an unmanaged WSL command', async () => {
|
|
const wsl = createWslRunner('#!/usr/bin/env bash\necho elsewhere\n')
|
|
const installer = new WslCliInstaller({
|
|
platform: 'win32',
|
|
distro: 'Ubuntu',
|
|
hostInstaller: { getStatus: async () => makeHostStatus() },
|
|
wslRunner: wsl.runner
|
|
})
|
|
|
|
await expect(installer.getStatus()).resolves.toMatchObject({ state: 'conflict' })
|
|
await expect(installer.install()).rejects.toThrow('Refusing to replace')
|
|
})
|
|
|
|
it('removes a managed WSL launcher', async () => {
|
|
const wsl = createWslRunner(
|
|
_internals.buildWslLauncher(
|
|
'C:\\Orca\\orca.cmd',
|
|
'/home/alice/.local/share/orca/orca-wsl-bridge.ps1'
|
|
)
|
|
)
|
|
const installer = new WslCliInstaller({
|
|
platform: 'win32',
|
|
distro: 'Ubuntu',
|
|
hostInstaller: { getStatus: async () => makeHostStatus('C:\\Orca\\orca.cmd') },
|
|
wslRunner: wsl.runner
|
|
})
|
|
|
|
await expect(installer.remove()).resolves.toMatchObject({ state: 'not_installed' })
|
|
expect(wsl.getFile()).toBeNull()
|
|
})
|
|
|
|
it('generates a launcher that forwards arguments through a PowerShell file bridge', () => {
|
|
const launcher = _internals.buildWslLauncher(
|
|
'C:\\Program Files\\Orca\\orca.cmd',
|
|
'/home/alice/.local/share/orca/orca-wsl-bridge.ps1'
|
|
)
|
|
const bridge = _internals.buildWslBridgeScript()
|
|
|
|
expect(launcher).toContain('command -v powershell.exe')
|
|
expect(launcher).toContain('/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe')
|
|
expect(launcher).toContain(
|
|
'Orca WSL CLI requires Windows interop and could not find powershell.exe.'
|
|
)
|
|
expect(launcher).toContain('"$ORCA_POWERSHELL" -NoProfile -ExecutionPolicy Bypass -File')
|
|
expect(launcher).toContain('"$ORCA_WIN_LAUNCHER" "$@"')
|
|
expect(launcher).not.toContain('-Command')
|
|
expect(bridge).toContain('[Parameter(ValueFromRemainingArguments=$true)]')
|
|
expect(bridge).toContain('& $OrcaLauncher @ForwardArgs')
|
|
expect(bridge).toContain('catch')
|
|
expect(bridge).toContain('exit 1')
|
|
})
|
|
|
|
it('wraps WSL bash scripts as a single encoded command line', () => {
|
|
const command = [
|
|
'set -euo pipefail',
|
|
`cat > "$command_tmp" <<'ORCA_WSL_CLI'`,
|
|
'#!/usr/bin/env bash',
|
|
'exec powershell.exe "$@"',
|
|
'ORCA_WSL_CLI'
|
|
].join('\n')
|
|
const wrapped = _internals.buildEncodedWslBashCommand(command)
|
|
const encoded = wrapped.match(
|
|
/^set -o pipefail; printf %s '([^']+)' \| base64 -d \| bash$/
|
|
)?.[1]
|
|
|
|
expect(wrapped).not.toContain('\n')
|
|
expect(wrapped).toContain('set -o pipefail;')
|
|
expect(encoded).toBeTruthy()
|
|
expect(Buffer.from(encoded as string, 'base64').toString('utf8')).toBe(command)
|
|
})
|
|
|
|
it('treats absolute Windows PowerShell as interop-ready when powershell.exe is missing from PATH', async () => {
|
|
const wsl = createWslRunner()
|
|
const installer = new WslCliInstaller({
|
|
platform: 'win32',
|
|
distro: 'Ubuntu',
|
|
hostInstaller: { getStatus: async () => makeHostStatus() },
|
|
wslRunner: async (distro, command) => {
|
|
if (command.includes('command -v powershell.exe') && !command.includes('cat >')) {
|
|
expect(command).toContain('/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe')
|
|
return 'yes'
|
|
}
|
|
return wsl.runner(distro, command)
|
|
}
|
|
})
|
|
|
|
await expect(installer.getStatus()).resolves.toMatchObject({
|
|
state: 'not_installed',
|
|
commandPath: '/home/alice/.local/bin/orca-ide'
|
|
})
|
|
})
|
|
|
|
it('marks stale managed launchers that point at the old app bin instead of packaged resources', async () => {
|
|
const oldLauncher = _internals.buildWslLauncher(
|
|
'C:\\Users\\me\\AppData\\Local\\Programs\\Orca\\bin\\orca.cmd',
|
|
'/home/alice/.local/share/orca/orca-wsl-bridge.ps1'
|
|
)
|
|
const wsl = createWslRunner(oldLauncher)
|
|
const installer = new WslCliInstaller({
|
|
platform: 'win32',
|
|
distro: 'Ubuntu',
|
|
hostInstaller: { getStatus: async () => makeHostStatus() },
|
|
wslRunner: wsl.runner
|
|
})
|
|
|
|
await expect(installer.getStatus()).resolves.toMatchObject({
|
|
state: 'stale',
|
|
currentTarget: 'C:\\Users\\me\\AppData\\Local\\Programs\\Orca\\bin\\orca.cmd',
|
|
launcherPath: 'C:\\Users\\me\\AppData\\Local\\Programs\\Orca\\resources\\bin\\orca.cmd'
|
|
})
|
|
|
|
await expect(installer.install()).resolves.toMatchObject({
|
|
state: 'installed',
|
|
currentTarget: 'C:\\Users\\me\\AppData\\Local\\Programs\\Orca\\resources\\bin\\orca.cmd'
|
|
})
|
|
})
|
|
|
|
it('settles when wsl.exe never reports completion', async () => {
|
|
vi.useFakeTimers()
|
|
const killMock = vi.fn()
|
|
execFileMock.mockImplementation(() => ({ kill: killMock }))
|
|
const installer = new WslCliInstaller({
|
|
platform: 'win32',
|
|
distro: 'Ubuntu',
|
|
hostInstaller: { getStatus: async () => makeHostStatus() }
|
|
})
|
|
|
|
const promise = installer.getStatus()
|
|
let settled = false
|
|
void promise
|
|
.catch(() => undefined)
|
|
.finally(() => {
|
|
settled = true
|
|
})
|
|
|
|
await vi.advanceTimersByTimeAsync(10_000)
|
|
await Promise.resolve()
|
|
|
|
expect(settled).toBe(true)
|
|
await expect(promise).rejects.toThrow('WSL command timed out')
|
|
expect(killMock).toHaveBeenCalled()
|
|
})
|
|
|
|
it('refuses to remove an old managed launcher when the bridge path is user-owned', async () => {
|
|
const oldLauncher = _internals.buildWslLauncher(
|
|
'C:\\Old\\orca.cmd',
|
|
'/home/alice/.local/share/orca/orca-wsl-bridge.ps1'
|
|
)
|
|
const wsl = createWslRunner(oldLauncher)
|
|
const installer = new WslCliInstaller({
|
|
platform: 'win32',
|
|
distro: 'Ubuntu',
|
|
hostInstaller: { getStatus: async () => makeHostStatus('C:\\Orca\\orca.cmd') },
|
|
wslRunner: async (distro, command) => {
|
|
if (command.includes('cat /home/alice/.local/share/orca/orca-wsl-bridge.ps1')) {
|
|
return 'user bridge'
|
|
}
|
|
if (command.includes('rm -f')) {
|
|
throw new Error('__ORCA_CONFLICT__')
|
|
}
|
|
return wsl.runner(distro, command)
|
|
}
|
|
})
|
|
|
|
await expect(installer.remove()).rejects.toThrow('__ORCA_CONFLICT__')
|
|
})
|
|
})
|