mirror of
https://github.com/stablyai/orca.git
synced 2026-11-03 10:37:35 +00:00
* [comment audit] Shorten daemon, hook, and emulator comments [skip ci] * [comment audit] Shorten VM, conversation, SQLite, and theme-import comments [skip ci] * [comment audit] Tighten Git execution and source-control comment contracts [skip ci] * [comment audit] Clarify repository probes and maintenance comments [skip ci] * [comment audit] Shorten status, diff-cache, and checkout comments [skip ci] * [comment audit] Clarify worktree lifecycle and WSL routing comments [skip ci] * [comment audit] Shorten forge identity and review-refresh comments [skip ci] * [comment audit] Tighten hosted-review client comment contracts [skip ci] * [comment audit] Clarify GitLab compatibility and review comments [skip ci] * [comment audit] Tighten hook ownership and watchdog rationale [skip ci] * [comment audit] Condense host and integration compatibility comments [skip ci] * [comment audit] Clarify IPC authority and remote-routing rationale [skip ci] * [comment audit] Finalize file-import and containment comment cleanup * [comment audit] Fix stale Jira type imports blocking full CI --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
157 lines
5.3 KiB
TypeScript
157 lines
5.3 KiB
TypeScript
import { installRealWorkerThreadChildProcesses } from '../worker-thread-child-process/worker-thread-child-process-real.test-fixtures'
|
|
import { execFileSync } from 'node:child_process'
|
|
import { mkdtemp, realpath, rm } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import * as path from 'node:path'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import { listWorktrees, removeWorktree } from './worktree'
|
|
|
|
const tempRoots: string[] = []
|
|
|
|
function git(cwd: string, args: string[]): string {
|
|
return execFileSync('git', args, { cwd, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] })
|
|
}
|
|
|
|
async function createRepoWithNewlineWorktree(): Promise<{
|
|
repoPath: string
|
|
worktreePath: string
|
|
}> {
|
|
const root = await mkdtemp(path.join(tmpdir(), 'orca-worktree-paths-'))
|
|
tempRoots.push(root)
|
|
const repoPath = path.join(root, 'repo')
|
|
const requestedWorktreePath = path.join(root, 'linked\nworktree')
|
|
|
|
execFileSync('git', ['init', '--quiet', repoPath])
|
|
git(repoPath, ['symbolic-ref', 'HEAD', 'refs/heads/main'])
|
|
git(repoPath, ['config', 'user.email', 'test@example.com'])
|
|
git(repoPath, ['config', 'user.name', 'Test User'])
|
|
git(repoPath, ['commit', '--allow-empty', '--quiet', '-m', 'initial'])
|
|
git(repoPath, ['worktree', 'add', '--quiet', '-b', 'feature/newline', requestedWorktreePath])
|
|
|
|
return {
|
|
repoPath: await realpath(repoPath),
|
|
worktreePath: await realpath(requestedWorktreePath)
|
|
}
|
|
}
|
|
|
|
async function createRepoWithLockedDeletedWorktree(): Promise<{
|
|
repoPath: string
|
|
worktreePath: string
|
|
}> {
|
|
const root = await mkdtemp(path.join(tmpdir(), 'orca-worktree-locked-delete-'))
|
|
tempRoots.push(root)
|
|
const repoPath = path.join(root, 'repo')
|
|
const requestedWorktreePath = path.join(root, 'locked deleted worktree')
|
|
|
|
execFileSync('git', ['init', '--quiet', repoPath])
|
|
git(repoPath, ['symbolic-ref', 'HEAD', 'refs/heads/main'])
|
|
git(repoPath, ['config', 'user.email', 'test@example.com'])
|
|
git(repoPath, ['config', 'user.name', 'Test User'])
|
|
git(repoPath, ['commit', '--allow-empty', '--quiet', '-m', 'initial'])
|
|
git(repoPath, [
|
|
'worktree',
|
|
'add',
|
|
'--quiet',
|
|
'-b',
|
|
'feature/locked-delete',
|
|
requestedWorktreePath
|
|
])
|
|
git(repoPath, ['worktree', 'lock', '--reason', 'orca locked stale repro', requestedWorktreePath])
|
|
|
|
const worktreePath = await realpath(requestedWorktreePath)
|
|
await rm(worktreePath, { recursive: true, force: true })
|
|
|
|
return {
|
|
repoPath: await realpath(repoPath),
|
|
worktreePath
|
|
}
|
|
}
|
|
|
|
async function createRepoWithPrunableWorktree(): Promise<{
|
|
repoPath: string
|
|
worktreePath: string
|
|
}> {
|
|
const root = await mkdtemp(path.join(tmpdir(), 'orca-worktree-prunable-'))
|
|
tempRoots.push(root)
|
|
const repoPath = path.join(root, 'repo')
|
|
const requestedWorktreePath = path.join(root, 'stale-worktree')
|
|
|
|
execFileSync('git', ['init', '--quiet', repoPath])
|
|
git(repoPath, ['symbolic-ref', 'HEAD', 'refs/heads/main'])
|
|
git(repoPath, ['config', 'user.email', 'test@example.com'])
|
|
git(repoPath, ['config', 'user.name', 'Test User'])
|
|
git(repoPath, ['commit', '--allow-empty', '--quiet', '-m', 'initial'])
|
|
git(repoPath, ['worktree', 'add', '--quiet', '-b', 'feature/stale', requestedWorktreePath])
|
|
|
|
const worktreePath = await realpath(requestedWorktreePath)
|
|
await rm(worktreePath, { recursive: true, force: true })
|
|
|
|
return {
|
|
repoPath: await realpath(repoPath),
|
|
worktreePath
|
|
}
|
|
}
|
|
|
|
function branchExists(repoPath: string, branchName: string): boolean {
|
|
try {
|
|
git(repoPath, ['show-ref', '--verify', '--quiet', `refs/heads/${branchName}`])
|
|
return true
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
afterEach(async () => {
|
|
await Promise.all(tempRoots.splice(0).map((root) => rm(root, { recursive: true, force: true })))
|
|
})
|
|
|
|
describe('git worktree paths', () => {
|
|
it.skipIf(process.platform === 'win32')(
|
|
'lists worktrees whose paths contain newlines',
|
|
async () => {
|
|
const { repoPath, worktreePath } = await createRepoWithNewlineWorktree()
|
|
|
|
const worktrees = await listWorktrees(repoPath)
|
|
|
|
expect(worktrees.map((worktree) => worktree.path)).toContain(worktreePath)
|
|
}
|
|
)
|
|
|
|
it.skipIf(process.platform === 'win32')(
|
|
'deletes the matching local branch after removing a newline-path worktree',
|
|
async () => {
|
|
const { repoPath, worktreePath } = await createRepoWithNewlineWorktree()
|
|
|
|
await removeWorktree(repoPath, worktreePath)
|
|
|
|
expect(branchExists(repoPath, 'feature/newline')).toBe(false)
|
|
}
|
|
)
|
|
|
|
it('annotates a worktree whose directory was deleted as prunable', async () => {
|
|
const { repoPath, worktreePath } = await createRepoWithPrunableWorktree()
|
|
|
|
const worktrees = await listWorktrees(repoPath)
|
|
const stale = worktrees.find(
|
|
(worktree) => worktree.path.replaceAll('\\', '/') === worktreePath.replaceAll('\\', '/')
|
|
)
|
|
|
|
expect(stale).toMatchObject({ prunable: true })
|
|
})
|
|
|
|
it('preserves a locked worktree whose directory was deleted manually', async () => {
|
|
const { repoPath, worktreePath } = await createRepoWithLockedDeletedWorktree()
|
|
|
|
await expect(removeWorktree(repoPath, worktreePath, true)).rejects.toThrow(
|
|
'Worktree is locked by Git'
|
|
)
|
|
|
|
expect(git(repoPath, ['worktree', 'list', '--porcelain'])).toContain(
|
|
worktreePath.replaceAll('\\', '/')
|
|
)
|
|
expect(branchExists(repoPath, 'feature/locked-delete')).toBe(true)
|
|
})
|
|
})
|
|
|
|
installRealWorkerThreadChildProcesses()
|