mirror of
https://github.com/stablyai/orca.git
synced 2026-10-23 00:03:52 +00:00
fix(repo): make the remote .git probe verdict a discriminated union
Promise<string | null | 'unverifiable'> collapses: the literal is subsumed by string, so callers got no type help distinguishing 'could not look' from a real signature. The three outcomes are now structurally distinct.
This commit is contained in:
@@ -103,27 +103,40 @@ function isRemoteMissingPathError(error: unknown): boolean {
|
||||
return /\bENOENT\b|no such file|not found/i.test(message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remote `.git` probe verdict. A bare `string | 'unverifiable'` union collapses —
|
||||
* the literal is subsumed by `string`, so callers get no type help distinguishing
|
||||
* "could not look" from a signature. Keep the three outcomes structurally distinct.
|
||||
*/
|
||||
export type RemoteGitMarkerSignature =
|
||||
| { status: 'present'; signature: string }
|
||||
| { status: 'absent' }
|
||||
| { status: 'unverifiable' }
|
||||
|
||||
export async function readRemoteGitMarkerSignature(
|
||||
repo: Pick<Repo, 'path' | 'connectionId'>
|
||||
): Promise<string | null | 'unverifiable'> {
|
||||
): Promise<RemoteGitMarkerSignature> {
|
||||
const connectionId = repo.connectionId
|
||||
if (!connectionId) {
|
||||
return 'unverifiable'
|
||||
return { status: 'unverifiable' }
|
||||
}
|
||||
const filesystem = getSshFilesystemProvider(connectionId)
|
||||
const git = getSshGitProvider(connectionId)
|
||||
const host = git?.getHostPlatform()
|
||||
if (!filesystem || !git || !host) {
|
||||
return 'unverifiable'
|
||||
return { status: 'unverifiable' }
|
||||
}
|
||||
try {
|
||||
const marker = await filesystem.stat(joinRemotePath(host, repo.path, '.git'))
|
||||
return `${marker.mtimeMs ?? marker.mtime}:${marker.ino ?? 0}:${marker.type}`
|
||||
return {
|
||||
status: 'present',
|
||||
signature: `${marker.mtimeMs ?? marker.mtime}:${marker.ino ?? 0}:${marker.type}`
|
||||
}
|
||||
} catch (error) {
|
||||
if (isRemoteMissingPathError(error)) {
|
||||
return null
|
||||
return { status: 'absent' }
|
||||
}
|
||||
return 'unverifiable'
|
||||
return { status: 'unverifiable' }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -152,16 +152,12 @@ async function pollOnce(watch: UpgradeWatch): Promise<void> {
|
||||
const key = candidateKey(repo)
|
||||
liveKeys.add(key)
|
||||
if (isSshCandidate(repo)) {
|
||||
const signature = await readRemoteGitMarkerSignature(repo)
|
||||
if (
|
||||
signature === 'unverifiable' ||
|
||||
signature === null ||
|
||||
rejectedMarkers.get(key) === signature
|
||||
) {
|
||||
const marker = await readRemoteGitMarkerSignature(repo)
|
||||
if (marker.status !== 'present' || rejectedMarkers.get(key) === marker.signature) {
|
||||
continue
|
||||
}
|
||||
if ((await upgradeSshFolderRepo(watch, repo)) === 'rejected') {
|
||||
rejectedMarkers.set(key, signature)
|
||||
rejectedMarkers.set(key, marker.signature)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user