Skip to content

Commit d08ddbf

Browse files
committed
fix(setup): require OrbStack to be installed before selecting it
A context or DOCKER_HOST left behind by an OrbStack uninstall selected an app that can never launch, turning a working Docker Desktop start into a guaranteed 90s timeout. Gate the OrbStack signal on the bundle being present and fall through to whichever app is. Look in ~/Applications as well as /Applications while here — Homebrew casks honour --appdir, so a user-local install is not unusual and a hardcoded /Applications check would misread it as "not installed".
1 parent 847944f commit d08ddbf

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

scripts/setup/docker.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { spawnSync } from 'node:child_process'
22
import { existsSync } from 'node:fs'
3+
import { homedir } from 'node:os'
4+
import { join } from 'node:path'
35
import { SetupError } from './errors.ts'
46
import { waitFor } from './probes.ts'
57
import * as p from './prompter.ts'
@@ -11,8 +13,13 @@ const INSTALL_HINTS = [
1113
]
1214

1315
/** macOS GUI docker providers we know how to launch via `open -a`. */
14-
const ORBSTACK_APP = { name: 'OrbStack', path: '/Applications/OrbStack.app' } as const
15-
const DOCKER_DESKTOP_APP = { name: 'Docker', path: '/Applications/Docker.app' } as const
16+
const ORBSTACK_APP = { name: 'OrbStack', bundle: 'OrbStack.app' } as const
17+
const DOCKER_DESKTOP_APP = { name: 'Docker', bundle: 'Docker.app' } as const
18+
19+
type DockerApp = typeof ORBSTACK_APP | typeof DOCKER_DESKTOP_APP
20+
21+
/** Homebrew casks honour `--appdir`, so a user-local install is not unusual. */
22+
const APP_DIRS = ['/Applications', join(homedir(), 'Applications')]
1623

1724
function daemonUp(): boolean {
1825
return spawnSync('docker', ['info'], { stdio: 'ignore' }).status === 0
@@ -37,16 +44,22 @@ function orbstackSelected(): boolean {
3744
return result.status === 0 && result.stdout.trim() === 'orbstack'
3845
}
3946

47+
function appInstalled(app: DockerApp): boolean {
48+
return APP_DIRS.some((dir) => existsSync(join(dir, app.bundle)))
49+
}
50+
4051
/**
4152
* Which GUI app owns the `docker` CLI on this Mac. Both apps install a `docker`
4253
* binary, so CLI presence alone doesn't say which one to launch. An explicit
43-
* OrbStack selection wins; otherwise prefer whichever app is actually
44-
* installed, which also covers CLIs too old for `docker context show`.
54+
* OrbStack selection wins, but only when OrbStack is still installed — a
55+
* context or `DOCKER_HOST` left behind by an uninstall would otherwise pick an
56+
* app that can never come up. Otherwise fall back to whichever app is present,
57+
* which also covers CLIs too old for `docker context show`.
4558
*/
46-
function macDockerApp(): typeof ORBSTACK_APP | typeof DOCKER_DESKTOP_APP {
47-
if (orbstackSelected()) return ORBSTACK_APP
48-
if (existsSync(DOCKER_DESKTOP_APP.path)) return DOCKER_DESKTOP_APP
49-
return existsSync(ORBSTACK_APP.path) ? ORBSTACK_APP : DOCKER_DESKTOP_APP
59+
function macDockerApp(): DockerApp {
60+
if (orbstackSelected() && appInstalled(ORBSTACK_APP)) return ORBSTACK_APP
61+
if (appInstalled(DOCKER_DESKTOP_APP)) return DOCKER_DESKTOP_APP
62+
return appInstalled(ORBSTACK_APP) ? ORBSTACK_APP : DOCKER_DESKTOP_APP
5063
}
5164

5265
/**

0 commit comments

Comments
 (0)