orca/src/main/local-project-runtime-resol...

107 lines
3.5 KiB
TypeScript

import type { Store } from './persistence'
import type { Project, Repo } from '../shared/types'
import {
resolveProjectExecutionRuntime,
type ProjectExecutionRuntimeResolution
} from '../shared/project-execution-runtime'
import {
getCachedWslAvailability,
getCachedWslDistros,
hasCachedWslAvailability,
hasCachedWslDistros
} from './wsl'
import { getRepoIdFromWorktreeId } from '../shared/worktree-id'
import { getRepoExecutionHostId, LOCAL_EXECUTION_HOST_ID } from '../shared/execution-host'
function canResolveProjectRuntimeForRepo(store: Store): boolean {
return typeof store.getProjects === 'function' && typeof store.getSettings === 'function'
}
function canResolveProjectRuntimeForWorktreeId(store: Store): boolean {
return canResolveProjectRuntimeForRepo(store) && typeof store.getRepo === 'function'
}
function resolveLocalProjectRuntime(
store: Store,
project: Project,
settings: ReturnType<Store['getSettings']> = store.getSettings()
): ProjectExecutionRuntimeResolution {
const wslAvailable = hasCachedWslAvailability()
? (getCachedWslAvailability() ?? undefined)
: undefined
const availableWslDistros = hasCachedWslDistros() ? getCachedWslDistros() : null
return resolveProjectExecutionRuntime({
appPlatform: process.platform,
projectId: project.id,
projectRuntimePreference: project.localWindowsRuntimePreference,
globalWindowsRuntimeDefault: settings.localWindowsRuntimeDefault,
wslAvailable,
availableWslDistros
})
}
export function resolveLocalProjectRuntimeForRepo(
store: Store,
repo: Repo
): ProjectExecutionRuntimeResolution | undefined {
if (
getRepoExecutionHostId(repo) !== LOCAL_EXECUTION_HOST_ID ||
!canResolveProjectRuntimeForRepo(store)
) {
return undefined
}
const project = store.getProjects().find((entry) => entry.sourceRepoIds.includes(repo.id))
if (!project) {
return undefined
}
return resolveLocalProjectRuntime(store, project)
}
export function resolveLocalProjectRuntimesForRepos(
store: Store,
repos: readonly Repo[]
): ReadonlyMap<string, ProjectExecutionRuntimeResolution> {
const runtimeByRepoId = new Map<string, ProjectExecutionRuntimeResolution>()
if (!canResolveProjectRuntimeForRepo(store)) {
return runtimeByRepoId
}
const requestedRepoIds = new Set(
repos
.filter((repo) => getRepoExecutionHostId(repo) === LOCAL_EXECUTION_HOST_ID)
.map((repo) => repo.id)
)
if (requestedRepoIds.size === 0) {
return runtimeByRepoId
}
const settings = store.getSettings()
for (const project of store.getProjects()) {
const matchingRepoIds = project.sourceRepoIds.filter(
(repoId) => requestedRepoIds.has(repoId) && !runtimeByRepoId.has(repoId)
)
if (matchingRepoIds.length === 0) {
continue
}
// Why: one project runtime applies to every source repo in that project;
// resolving it once prevents mobile polls from rescanning project settings.
const runtime = resolveLocalProjectRuntime(store, project, settings)
for (const repoId of matchingRepoIds) {
runtimeByRepoId.set(repoId, runtime)
}
}
return runtimeByRepoId
}
export function resolveLocalProjectRuntimeForWorktreeId(
store: Store | undefined,
worktreeId: string | undefined
): ProjectExecutionRuntimeResolution | undefined {
if (!store || !worktreeId) {
return undefined
}
if (!canResolveProjectRuntimeForWorktreeId(store)) {
return undefined
}
const repo = store.getRepo(getRepoIdFromWorktreeId(worktreeId))
return repo ? resolveLocalProjectRuntimeForRepo(store, repo) : undefined
}