mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 18:37:24 +00:00
* refactor(git): group worktree operations and ref owners * test(git): retarget remaining concrete executor mocks
110 lines
3.1 KiB
TypeScript
110 lines
3.1 KiB
TypeScript
import type { IssueSourcePreference } from '../../shared/repo-types'
|
|
import { githubRepoIdentityKey } from '../../shared/github/repository-identity-key'
|
|
import { shouldProbeGitRemote } from '../git/remotes/remote-name-listing'
|
|
import {
|
|
getOwnerRepoForRemote,
|
|
type LocalGitExecOptions,
|
|
type OwnerRepo
|
|
} from './github-repository-identity'
|
|
|
|
export async function getOwnerRepo(
|
|
repoPath: string,
|
|
connectionId?: string | null,
|
|
localGitOptions: LocalGitExecOptions = {}
|
|
): Promise<OwnerRepo | null> {
|
|
// Fork contribution PRs usually live on upstream.
|
|
const originPromise = getOwnerRepoForRemote(repoPath, 'origin', connectionId, localGitOptions)
|
|
if (await shouldProbeGitRemote(repoPath, 'upstream', connectionId, localGitOptions)) {
|
|
const upstream = await getOwnerRepoForRemote(
|
|
repoPath,
|
|
'upstream',
|
|
connectionId,
|
|
localGitOptions
|
|
)
|
|
if (upstream) {
|
|
return upstream
|
|
}
|
|
}
|
|
return originPromise
|
|
}
|
|
|
|
export const getIssueOwnerRepo = getOwnerRepo
|
|
|
|
export type PRRepositoryCandidates = {
|
|
candidates: OwnerRepo[]
|
|
headRepo: OwnerRepo | null
|
|
}
|
|
|
|
export async function resolvePRRepositoryCandidates(
|
|
repoPath: string,
|
|
connectionId?: string | null,
|
|
localGitOptions: LocalGitExecOptions = {}
|
|
): Promise<PRRepositoryCandidates> {
|
|
const originPromise = getOwnerRepoForRemote(repoPath, 'origin', connectionId, localGitOptions)
|
|
const probeUpstream = await shouldProbeGitRemote(
|
|
repoPath,
|
|
'upstream',
|
|
connectionId,
|
|
localGitOptions
|
|
)
|
|
const [upstream, origin] = await Promise.all([
|
|
probeUpstream
|
|
? getOwnerRepoForRemote(repoPath, 'upstream', connectionId, localGitOptions)
|
|
: null,
|
|
originPromise
|
|
])
|
|
const seen = new Set<string>()
|
|
const candidates: OwnerRepo[] = []
|
|
|
|
for (const candidate of [upstream, origin]) {
|
|
if (!candidate) {
|
|
continue
|
|
}
|
|
const key = githubRepoIdentityKey(candidate)
|
|
if (seen.has(key)) {
|
|
continue
|
|
}
|
|
seen.add(key)
|
|
candidates.push(candidate)
|
|
}
|
|
|
|
return { candidates, headRepo: origin }
|
|
}
|
|
|
|
export type ResolvedIssueSource = {
|
|
source: OwnerRepo | null
|
|
/** True when explicit upstream is gone and resolver fell back to origin. */
|
|
fellBack: boolean
|
|
}
|
|
|
|
export async function resolveIssueSource(
|
|
repoPath: string,
|
|
preference: IssueSourcePreference | undefined,
|
|
connectionId?: string | null,
|
|
localGitOptions: LocalGitExecOptions = {}
|
|
): Promise<ResolvedIssueSource> {
|
|
if (preference === 'upstream') {
|
|
const upstream = await getOwnerRepoForRemote(
|
|
repoPath,
|
|
'upstream',
|
|
connectionId,
|
|
localGitOptions
|
|
)
|
|
if (upstream) {
|
|
return { source: upstream, fellBack: false }
|
|
}
|
|
const origin = await getOwnerRepoForRemote(repoPath, 'origin', connectionId, localGitOptions)
|
|
return { source: origin, fellBack: origin !== null }
|
|
}
|
|
if (preference === 'origin') {
|
|
return {
|
|
source: await getOwnerRepoForRemote(repoPath, 'origin', connectionId, localGitOptions),
|
|
fellBack: false
|
|
}
|
|
}
|
|
return {
|
|
source: await getIssueOwnerRepo(repoPath, connectionId, localGitOptions),
|
|
fellBack: false
|
|
}
|
|
}
|