mirror of
https://github.com/stablyai/orca.git
synced 2026-10-19 16:03:26 +00:00
fix(runtime): log the folder-workspace fan-out failures instead of swallowing them
A child repo whose status read fails silently vanished from the merged status (indistinguishable from clean) and from the commit set (a "success" that skipped staged files). A failed abort left a repo conflicted with no trail. Each now warns with the repo path. Also gives the test fixture a unique temp dir so concurrent runs stop rm -rf'ing each other mid-test. Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { afterAll, describe, expect, it, vi } from 'vitest'
|
||||
import { execFileSync } from 'node:child_process'
|
||||
import { mkdirSync, writeFileSync, appendFileSync, rmSync, realpathSync } from 'node:fs'
|
||||
import {
|
||||
mkdirSync,
|
||||
mkdtempSync,
|
||||
writeFileSync,
|
||||
appendFileSync,
|
||||
rmSync,
|
||||
realpathSync
|
||||
} from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { OrcaRuntimeService } from './orca-runtime'
|
||||
import { folderWorkspaceKey } from '../../shared/workspace-scope'
|
||||
@@ -15,7 +23,9 @@ vi.mock('electron', () => ({
|
||||
app: { getPath: vi.fn(() => '/tmp') }
|
||||
}))
|
||||
|
||||
const FIXTURE = `${realpathSync('/tmp')}/hotbugs/fixture-6357`
|
||||
// Why: a fixed path collides when two runs of this file overlap (watch mode, CI
|
||||
// shards), and each `buildFixture` rm -rf's the other's repos mid-test.
|
||||
const FIXTURE = mkdtempSync(join(realpathSync(tmpdir()), 'orca-6357-'))
|
||||
const CONTAINER = join(FIXTURE, 'fint')
|
||||
const CHILD_API = join(CONTAINER, 'fint_api')
|
||||
const CHILD_WT = join(FIXTURE, 'wt-fint_api-refund')
|
||||
@@ -139,6 +149,10 @@ function makeStore(overrides: { repos?: Repo[] } = {}): unknown {
|
||||
}
|
||||
|
||||
describe('#6357 monorepo folder workspace', () => {
|
||||
afterAll(() => {
|
||||
rmSync(FIXTURE, { recursive: true, force: true })
|
||||
})
|
||||
|
||||
it('A: file explorer resolves for a folder workspace (merged #6569 path)', async () => {
|
||||
buildFixture()
|
||||
const runtime = new OrcaRuntimeService(makeStore() as never)
|
||||
|
||||
@@ -24191,8 +24191,18 @@ export class OrcaRuntimeService {
|
||||
if (!target) {
|
||||
return null
|
||||
}
|
||||
// Why: one unreadable child repo must not blank the whole workspace list.
|
||||
const status = await getRuntimeGitStatusForTarget(target, options).catch(() => null)
|
||||
// Why: one unreadable child repo must not blank the whole workspace list,
|
||||
// but it also must not vanish without a trace — its files silently go missing
|
||||
// from the merged status, which looks identical to a clean repo.
|
||||
const status = await getRuntimeGitStatusForTarget(target, options).catch(
|
||||
(error: unknown) => {
|
||||
console.warn('[runtime] folder-workspace status failed for child repo', {
|
||||
repo: repo.path,
|
||||
error
|
||||
})
|
||||
return null
|
||||
}
|
||||
)
|
||||
if (!status) {
|
||||
return null
|
||||
}
|
||||
@@ -24236,7 +24246,15 @@ export class OrcaRuntimeService {
|
||||
if (!target) {
|
||||
return null
|
||||
}
|
||||
const status = await getRuntimeGitStatusForTarget(target).catch(() => null)
|
||||
// Why: a status failure here silently drops the repo from the commit, so the
|
||||
// user sees a success that skipped their staged files. Log which one.
|
||||
const status = await getRuntimeGitStatusForTarget(target).catch((error: unknown) => {
|
||||
console.warn('[runtime] folder-workspace commit skipped a child repo', {
|
||||
repo: repo.path,
|
||||
error
|
||||
})
|
||||
return null
|
||||
})
|
||||
const hasStaged = status?.entries.some((entry) => entry.area === 'staged') === true
|
||||
return hasStaged ? { repo, target } : null
|
||||
})
|
||||
@@ -24288,7 +24306,13 @@ export class OrcaRuntimeService {
|
||||
}
|
||||
const detected = await this.gitCommands
|
||||
.getRuntimeGitConflictOperation(`id:${target.worktree.id}`)
|
||||
.catch(() => 'unknown' as const)
|
||||
.catch((error: unknown) => {
|
||||
console.warn('[runtime] folder-workspace abort could not read conflict state', {
|
||||
repo: repo.path,
|
||||
error
|
||||
})
|
||||
return 'unknown' as const
|
||||
})
|
||||
// Why: belt-and-braces. Git already refuses `merge --abort` on a mid-rebase
|
||||
// repo (and vice versa), so this narrows what we run rather than what we
|
||||
// prevent — it keeps N-1 pointless failing git invocations off the wire.
|
||||
@@ -24299,7 +24323,16 @@ export class OrcaRuntimeService {
|
||||
// Why: aborting nothing is not an error — the conflict may have been resolved
|
||||
// in a terminal already, and the renderer only needs the state to settle.
|
||||
await Promise.all(
|
||||
targets.map((target) => abortRuntimeGitForTarget(target, operation).catch(() => undefined))
|
||||
targets.map((target) =>
|
||||
abortRuntimeGitForTarget(target, operation).catch((error: unknown) => {
|
||||
// Why: one repo refusing the abort must not block the others, but a
|
||||
// still-conflicted repo the user believes is clean needs a trail.
|
||||
console.warn(`[runtime] folder-workspace ${operation} abort failed`, {
|
||||
repo: target.worktree.path,
|
||||
error
|
||||
})
|
||||
})
|
||||
)
|
||||
)
|
||||
return { ok: true }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user