fix(macos): keep CLI path discovery off main actor (#106089)

This commit is contained in:
Peter Steinberger
2026-07-13 00:41:59 -07:00
committed by GitHub
parent 6df498c3cd
commit 4e46f08fed
2 changed files with 30 additions and 7 deletions

View File

@@ -160,8 +160,9 @@ enum CLIInstaller {
}
static func status() async -> Status {
let preferredPaths = await CommandResolver.preferredPathsAsync()
let locations = self.installedLocations(
searchPaths: CommandResolver.preferredPaths(),
searchPaths: preferredPaths,
fileManager: .default)
guard !locations.isEmpty else {
return .missing(location: self.managedExecutableLocation())
@@ -169,7 +170,10 @@ enum CLIInstaller {
var fallbackStatus: Status?
for location in locations {
let status = await self.status(location: location)
let status = await self.status(
location: location,
expectedVersion: GatewayEnvironment.expectedGatewayVersionString(),
preferredPaths: preferredPaths)
if status.isReady {
self.rememberValidated(status)
return status
@@ -189,7 +193,11 @@ enum CLIInstaller {
return .missing(location: location)
}
let status = await self.status(location: location, expectedVersion: expectedVersion)
let preferredPaths = await CommandResolver.preferredPathsAsync()
let status = await self.status(
location: location,
expectedVersion: expectedVersion,
preferredPaths: preferredPaths)
if status.isReady {
self.rememberValidated(status)
}
@@ -197,13 +205,21 @@ enum CLIInstaller {
}
static func status(location: String) async -> Status {
await self.status(
let preferredPaths = await CommandResolver.preferredPathsAsync()
return await self.status(
location: location,
expectedVersion: GatewayEnvironment.expectedGatewayVersionString())
expectedVersion: GatewayEnvironment.expectedGatewayVersionString(),
preferredPaths: preferredPaths)
}
private static func status(location: String, expectedVersion: String?) async -> Status {
let environment = self.probeEnvironment(location: location)
private static func status(
location: String,
expectedVersion: String?,
preferredPaths: [String]) async -> Status
{
let environment = self.probeEnvironment(
location: location,
preferredPaths: preferredPaths)
let response = await ShellExecutor.runDetailed(
command: [location, "--version"],
cwd: nil,

View File

@@ -81,6 +81,13 @@ enum CommandResolver {
validatedExecutable: validatedExecutable)
}
/// Version-manager trees can make discovery arbitrarily slow. Async callers
/// must leave their actor before touching the filesystem or the UI can stall.
@concurrent
static func preferredPathsAsync() async -> [String] {
self.preferredPaths()
}
static func preferredPaths(
home: URL,
current: [String],