mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
fix(git): derive clone folder from scp-style remote path (#30763)
This commit is contained in:
@@ -2,9 +2,49 @@ import { describe, expect, it } from 'vitest'
|
||||
import { mkdtemp, rm } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { deriveValidatedClonePath, getClonePathComparisonKey } from './repo-clone-path'
|
||||
import {
|
||||
deriveCloneRepoNameFromUrl,
|
||||
deriveValidatedClonePath,
|
||||
getClonePathComparisonKey
|
||||
} from './repo-clone-path'
|
||||
|
||||
describe('repo clone path helpers', () => {
|
||||
it.each([
|
||||
'git@example.com:project.git',
|
||||
'example.com:project.git',
|
||||
'git@[2001:db8::1]:project.git',
|
||||
'[2001:db8::1]:project.git',
|
||||
'git@example.com:team/project.git',
|
||||
'git@example.com:/srv/project.git'
|
||||
])('derives the repository directory from the path in %s', (url) => {
|
||||
expect(deriveCloneRepoNameFromUrl(url)).toBe('project')
|
||||
expect(deriveValidatedClonePath({ url, destination: process.cwd() })).toBe(
|
||||
join(process.cwd(), 'project')
|
||||
)
|
||||
})
|
||||
|
||||
it.each([
|
||||
'https://example.com/team/project.git',
|
||||
'ssh://git@example.com/team/project.git',
|
||||
'/srv/project.git',
|
||||
'C:\\repos\\project.git',
|
||||
'C:/repos/project.git',
|
||||
'\\\\server\\share\\project.git'
|
||||
])('preserves repository names for URL and local path inputs: %s', (url) => {
|
||||
expect(deriveCloneRepoNameFromUrl(url)).toBe('project')
|
||||
})
|
||||
|
||||
it('preserves a colon in an explicitly local relative path', () => {
|
||||
expect(deriveCloneRepoNameFromUrl('./local:project.git')).toBe('local:project')
|
||||
})
|
||||
|
||||
it.each(['git@example.com:.', 'git@example.com:..'])(
|
||||
'rejects an unsafe repository basename in %s',
|
||||
(url) => {
|
||||
expect(() => deriveCloneRepoNameFromUrl(url)).toThrow('Invalid repository name')
|
||||
}
|
||||
)
|
||||
|
||||
it('allows safe repository names that start with two dots', async () => {
|
||||
const destination = await mkdtemp(join(tmpdir(), 'orca-clone-path-'))
|
||||
try {
|
||||
|
||||
@@ -19,7 +19,11 @@ export function deriveCloneRepoNameFromUrl(url: string): string {
|
||||
// be "." or ".."; rejecting them prevents parent/destination deletion.
|
||||
const source = url.replace(/\.git\/?$/, '')
|
||||
const isWindowsLocalSource = /^[A-Za-z]:[\\/]/.test(source) || source.startsWith('\\\\')
|
||||
const repoName = isWindowsLocalSource ? win32.basename(source) : posix.basename(source)
|
||||
const scpPath =
|
||||
!isWindowsLocalSource && !source.includes('://')
|
||||
? source.match(/^(?:[^@/:]+@)?(?:\[[^\]]+\]|[^:/\s]+):(.+)$/)?.[1]
|
||||
: undefined
|
||||
const repoName = isWindowsLocalSource ? win32.basename(source) : posix.basename(scpPath ?? source)
|
||||
if (!repoName || repoName === '.' || repoName === '..') {
|
||||
throw new Error('Invalid repository name derived from URL')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user