mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
fix(project): name the folder's project id when setup-existing-folder identity mismatches (#23551)
When an imported or cloned folder's derived project id does not match the selected project, the error now names the id the folder resolves to (for example github:owner/repo) instead of a generic mismatch message. Host-local ids and identical ids keep the generic message. The setup-existing-folder help notes which ids --project accepts. Fixes #23528 Co-authored-by: Neil <neil@stably.ai>
This commit is contained in:
@@ -36,7 +36,8 @@ export const PROJECT_COMMAND_SPECS: CommandSpec[] = [
|
||||
notes: [
|
||||
'For remote runtimes, --path must be an absolute path on the remote server.',
|
||||
'--host takes local, ssh:<target-id>, runtime:<environment-id>, or the bare host name `orca host list` prints for any of them.',
|
||||
'SSH targets are set up through the desktop UI because the desktop client owns SSH connections.'
|
||||
'SSH targets are set up through the desktop UI because the desktop client owns SSH connections.',
|
||||
"--project takes a project id or an existing project's name. A remote-backed Git folder's project id usually comes from its remote: github:owner/repo, github:<host>/owner/repo for GitHub Enterprise, or git:<host>/<path> for other remotes."
|
||||
],
|
||||
examples: [
|
||||
'orca project setup-existing-folder --project github:stablyai/orca --host local --path ~/orca',
|
||||
|
||||
@@ -64,7 +64,7 @@ function alignRepoWithRequestedProject(
|
||||
const updated = store.updateRepo(
|
||||
repo,
|
||||
resolveImportedFolderProjectLink(
|
||||
folderRemote,
|
||||
{ ...repo, ...folderRemote },
|
||||
projectId,
|
||||
project?.providerIdentity ?? requestedProviderIdentity
|
||||
)
|
||||
|
||||
@@ -295,7 +295,7 @@ export class RuntimeProjectHostSetupController {
|
||||
const updated = store.updateRepo(
|
||||
repo,
|
||||
resolveImportedFolderProjectLink(
|
||||
folderRemote,
|
||||
{ ...repo, ...folderRemote },
|
||||
args.projectId,
|
||||
existingProject?.providerIdentity ?? args.projectProviderIdentity
|
||||
)
|
||||
|
||||
@@ -88,7 +88,7 @@ describe('RuntimeProjectHostSetupController with a Git-remote project', () => {
|
||||
url: 'https://gitlab.com/group/other.git',
|
||||
destination: '/tmp'
|
||||
})
|
||||
).rejects.toThrow('Imported folder does not match the selected project identity.')
|
||||
).rejects.toThrow('Imported folder resolves to project "git:gitlab.com/group/other"')
|
||||
expect(repos).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -5,6 +5,7 @@ import { getProjectIdentityKey } from './project-host-setup-projection'
|
||||
|
||||
function folder(remoteUrl: string | null) {
|
||||
return {
|
||||
id: 'imported-repo',
|
||||
gitRemoteIdentity: remoteUrl
|
||||
? deriveGitRemoteIdentity(`origin\t${remoteUrl} (fetch)\norigin\t${remoteUrl} (push)\n`)
|
||||
: null
|
||||
@@ -13,7 +14,7 @@ function folder(remoteUrl: string | null) {
|
||||
|
||||
/** The project a source host derives for a repo with this remote. */
|
||||
function projectIdFor(remoteUrl: string): string {
|
||||
return getProjectIdentityKey({ id: 'source-repo', ...folder(remoteUrl) })
|
||||
return getProjectIdentityKey(folder(remoteUrl))
|
||||
}
|
||||
|
||||
describe('resolveImportedFolderProjectLink', () => {
|
||||
@@ -55,7 +56,21 @@ describe('resolveImportedFolderProjectLink', () => {
|
||||
projectIdFor('https://gitlab.com/group/app.git'),
|
||||
undefined
|
||||
)
|
||||
).toThrow('Imported folder does not match the selected project identity.')
|
||||
).toThrow(
|
||||
'Imported folder resolves to project "git:gitlab.com/group/other", not the selected project "git:gitlab.com/group/app".'
|
||||
)
|
||||
})
|
||||
|
||||
it('names the GitHub project a folder resolves to when given a free-form project id', () => {
|
||||
expect(() =>
|
||||
resolveImportedFolderProjectLink(
|
||||
folder('https://github.com/owner/repo.git'),
|
||||
'my-project',
|
||||
undefined
|
||||
)
|
||||
).toThrow(
|
||||
'Imported folder resolves to project "github:owner/repo", not the selected project "my-project".'
|
||||
)
|
||||
})
|
||||
|
||||
it('refuses a folder with no remote for a Git-remote project', () => {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import {
|
||||
GIT_REMOTE_PROJECT_ID_PREFIX,
|
||||
getGitRemoteProviderIdentity,
|
||||
getProjectIdForProviderIdentity
|
||||
getProjectIdForProviderIdentity,
|
||||
getProjectIdentityKey,
|
||||
isHostLocalProjectId
|
||||
} from './project-host-setup-projection'
|
||||
import type { ProjectProviderIdentity } from './project-types'
|
||||
import type { Repo } from './repo-types'
|
||||
@@ -31,7 +33,7 @@ export function assertImportedFolderRemoteMatchesProject(
|
||||
|
||||
/** Supply missing project links: GitHub projects stamp upstream; remote-keyed projects record matching remotes not yet probed after cloning. */
|
||||
export function resolveImportedFolderProjectLink(
|
||||
folder: Pick<Repo, 'gitRemoteIdentity'>,
|
||||
folder: Pick<Repo, 'id' | 'upstream' | 'repoIcon' | 'gitRemoteIdentity'>,
|
||||
projectId: string,
|
||||
providerIdentity: ProjectProviderIdentity | undefined
|
||||
): Pick<Repo, 'upstream'> | Pick<Repo, 'gitRemoteIdentity'> {
|
||||
@@ -53,5 +55,12 @@ export function resolveImportedFolderProjectLink(
|
||||
) {
|
||||
return { gitRemoteIdentity: remote }
|
||||
}
|
||||
throw new Error('Imported folder does not match the selected project identity.')
|
||||
const folderProjectId = getProjectIdentityKey(folder)
|
||||
// Host-local or identical ids give the caller no better project to choose.
|
||||
if (isHostLocalProjectId(folderProjectId) || folderProjectId === projectId) {
|
||||
throw new Error('Imported folder does not match the selected project identity.')
|
||||
}
|
||||
throw new Error(
|
||||
`Imported folder resolves to project "${folderProjectId}", not the selected project "${projectId}".`
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user