mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
fix(cli): resolve WSL mounted-drive worktree paths
This commit is contained in:
+10
-3
@@ -4,7 +4,11 @@ import type {
|
||||
RuntimeWorktreeListResult,
|
||||
RuntimeWorktreeRecord
|
||||
} from '../shared/runtime-types'
|
||||
import { isPathInsideOrEqual, isWslUncPathForCallerLinuxPath } from '../shared/cross-platform-path'
|
||||
import {
|
||||
isPathInsideOrEqual,
|
||||
isWslUncPathForCallerLinuxPath,
|
||||
isWslUncPathForLinuxMountedPath
|
||||
} from '../shared/cross-platform-path'
|
||||
import { parseWslUncPath } from '../shared/wsl-paths'
|
||||
import type { RuntimeClient } from './runtime-client'
|
||||
import { RuntimeClientError } from './runtime/types'
|
||||
@@ -49,8 +53,9 @@ export async function resolveCallerDistroPathSelector(
|
||||
// the WSL launcher always sets and which arrives here as the invocation cwd, proves it.
|
||||
const callerDistro = parseWslUncPath(cwd)?.distro
|
||||
const linuxPath = selector.startsWith('path:') ? selector.slice(5) : ''
|
||||
const isLinuxMountedPath = /^\/mnt\/[A-Za-z](?:\/|$)/.test(linuxPath)
|
||||
if (
|
||||
!callerDistro ||
|
||||
(!callerDistro && !isLinuxMountedPath) ||
|
||||
client.isRemote ||
|
||||
!linuxPath.startsWith('/') ||
|
||||
linuxPath.startsWith('//') ||
|
||||
@@ -63,7 +68,9 @@ export async function resolveCallerDistroPathSelector(
|
||||
limit: 10_000
|
||||
})
|
||||
const match = worktrees.result.worktrees.find((worktree) =>
|
||||
isWslUncPathForCallerLinuxPath(worktree.path, linuxPath, callerDistro)
|
||||
isLinuxMountedPath
|
||||
? isWslUncPathForLinuxMountedPath(worktree.path, linuxPath)
|
||||
: isWslUncPathForCallerLinuxPath(worktree.path, linuxPath, callerDistro!)
|
||||
)
|
||||
// Why the stored spelling rather than a synthesized UNC path: an unmatched selector must
|
||||
// reach the runtime verbatim and fail as the caller typed it, never as a guessed distro.
|
||||
|
||||
@@ -11,6 +11,7 @@ import { normalizeWorktreeSelectorForCaller } from './selectors'
|
||||
const UBUNTU = 'Ubuntu-24.04'
|
||||
const DEBIAN = 'Debian'
|
||||
const LINUX_PATH = '/home/neil/qa-repo'
|
||||
const MOUNTED_PATH = '/mnt/c/Users/neil/qa-repo'
|
||||
|
||||
function uncPath(distro: string, linuxPath: string): string {
|
||||
return `\\\\wsl.localhost\\${distro}${linuxPath.replace(/\//g, '\\')}`
|
||||
@@ -37,6 +38,15 @@ afterEach(() => {
|
||||
})
|
||||
|
||||
describe('normalizeWorktreeSelectorForCaller in a WSL shell (#16628)', () => {
|
||||
it('resolves a shared /mnt drive without requiring the caller distro', async () => {
|
||||
const storedPath = uncPath(UBUNTU, '/mnt/c/Users/neil/qa-repo')
|
||||
const { client } = makeClient([storedPath])
|
||||
|
||||
await expect(
|
||||
normalizeWorktreeSelectorForCaller(`path:${MOUNTED_PATH}`, '/mnt/c/Users/neil', client)
|
||||
).resolves.toBe(`path:${storedPath}`)
|
||||
})
|
||||
|
||||
it.each([
|
||||
['a backslash UNC registration', uncPath(UBUNTU, LINUX_PATH)],
|
||||
['a forward-slash UNC registration', `//wsl.localhost/${UBUNTU}${LINUX_PATH}`],
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
isPathInsideOrEqual,
|
||||
isRuntimePathAbsolute,
|
||||
isWslUncPathForCallerLinuxPath,
|
||||
isWslUncPathForLinuxMountedPath,
|
||||
normalizeRuntimePathForComparison,
|
||||
relativePathInsideRoot,
|
||||
resolveRuntimePath
|
||||
@@ -99,6 +100,32 @@ describe('isWslUncPathForCallerLinuxPath', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('isWslUncPathForLinuxMountedPath', () => {
|
||||
it('matches a shared /mnt drive regardless of distro', () => {
|
||||
expect(
|
||||
isWslUncPathForLinuxMountedPath(
|
||||
'\\\\wsl.localhost\\Ubuntu\\mnt\\c\\Users\\Neil\\repo',
|
||||
'/mnt/c/users/neil/repo'
|
||||
)
|
||||
).toBe(true)
|
||||
expect(
|
||||
isWslUncPathForLinuxMountedPath(
|
||||
'\\\\wsl.localhost\\Debian\\mnt\\c\\Users\\Neil\\repo',
|
||||
'/mnt/c/users/neil/repo'
|
||||
)
|
||||
).toBe(true)
|
||||
})
|
||||
|
||||
it('keeps non-mounted Linux paths out of the distro-independent match', () => {
|
||||
expect(
|
||||
isWslUncPathForLinuxMountedPath(
|
||||
'\\\\wsl.localhost\\Ubuntu\\home\\Neil\\repo',
|
||||
'/home/neil/repo'
|
||||
)
|
||||
).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('cross-platform path containment', () => {
|
||||
it('keeps POSIX sibling prefixes outside the root', () => {
|
||||
expect(isPathInsideOrEqual('/repo/app', '/repo/app')).toBe(true)
|
||||
|
||||
@@ -81,6 +81,26 @@ export function isWslUncPathForCallerLinuxPath(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a WSL UNC path fronts the same Windows-mounted `/mnt/<drive>` path.
|
||||
*
|
||||
* `/mnt/<drive>` is backed by the host drive and is shared across distros, so
|
||||
* matching it does not require the caller's distro proof used for Linux paths.
|
||||
*/
|
||||
export function isWslUncPathForLinuxMountedPath(uncPath: string, linuxPath: string): boolean {
|
||||
const parsed = parseWslUncPath(uncPath)
|
||||
if (!parsed || !/^\/mnt\/[A-Za-z](?:\/|$)/.test(parsed.linuxPath)) {
|
||||
return false
|
||||
}
|
||||
if (!/^\/mnt\/[A-Za-z](?:\/|$)/.test(linuxPath)) {
|
||||
return false
|
||||
}
|
||||
return (
|
||||
normalizeRuntimePathForComparison(toWindowsWslPath(parsed.linuxPath, parsed.distro)) ===
|
||||
normalizeRuntimePathForComparison(toWindowsWslPath(linuxPath, parsed.distro))
|
||||
)
|
||||
}
|
||||
|
||||
export function areLocalWindowsWslPathAliases(left: string, right: string): boolean {
|
||||
const leftIdentity = getLocalWindowsWslPathIdentity(left)
|
||||
const rightIdentity = getLocalWindowsWslPathIdentity(right)
|
||||
|
||||
Reference in New Issue
Block a user