fix(desktop): match a project to its cwd across Windows path spellings
Project ownership compared paths literally, so a nested cwd failed to match its project whenever the separator or drive-letter case differed — which on Windows is routine. Normalise both sides for comparison only, folding case for drive and UNC paths.
This commit is contained in:
committed by
Brooklyn Nicholson
parent
6dda0c91d9
commit
7ff9d7db91
@@ -22,6 +22,7 @@ import {
|
||||
exitProjectScope,
|
||||
openProjectCreate,
|
||||
pickProjectFolder,
|
||||
projectIdForCwd,
|
||||
projectNameForCwd,
|
||||
refreshProjects,
|
||||
refreshProjectTree,
|
||||
@@ -241,6 +242,13 @@ describe('projectNameForCwd', () => {
|
||||
expect(projectNameForCwd('/elsewhere/mono-feature/src')).toBe('Monorepo')
|
||||
})
|
||||
|
||||
it('matches nested Windows paths across separator and case differences', () => {
|
||||
$projectTree.set([treeNode({ id: 'p_win', label: 'Windows app', path: 'C:\\Repos\\App' })])
|
||||
|
||||
expect(projectIdForCwd('c:/repos/app/src')).toBe('p_win')
|
||||
expect(projectNameForCwd('c:/repos/app/src')).toBe('Windows app')
|
||||
})
|
||||
|
||||
it('ignores auto-projects and the No-project bucket (no named identity)', () => {
|
||||
$projectTree.set([
|
||||
treeNode({ id: '/repos/loose', label: 'loose', path: '/repos/loose', isAuto: true }),
|
||||
|
||||
@@ -229,8 +229,26 @@ export function resolveNewSessionCwd(): string {
|
||||
return workspaceCwdForNewSession()
|
||||
}
|
||||
|
||||
const underPath = (parent: string, child: string): boolean =>
|
||||
child === parent || child.startsWith(parent.endsWith('/') ? parent : `${parent}/`)
|
||||
// Comparison-only path spelling: accept either separator everywhere, trim a
|
||||
// trailing separator, and fold case for Windows drive/UNC paths. The backend
|
||||
// uses the same host-aware identity rule when assigning sessions to projects.
|
||||
const comparisonPath = (path: string): string => {
|
||||
const raw = path.trim()
|
||||
const windows = /^[A-Za-z]:[/\\]/.test(raw) || raw.startsWith('\\') || raw.startsWith('//')
|
||||
const normalized = raw.replace(/\\/g, '/').replace(/\/+$/, '')
|
||||
|
||||
return windows ? normalized.toLowerCase() : normalized
|
||||
}
|
||||
|
||||
const underPath = (parent: string, child: string): boolean => {
|
||||
const normalizedParent = comparisonPath(parent)
|
||||
const normalizedChild = comparisonPath(child)
|
||||
|
||||
return (
|
||||
normalizedChild === normalizedParent ||
|
||||
normalizedChild.startsWith(normalizedParent.endsWith('/') ? normalizedParent : `${normalizedParent}/`)
|
||||
)
|
||||
}
|
||||
|
||||
// The project (explicit or auto) that owns `cwd`, by longest path match across
|
||||
// the live tree. Null when no project covers it (it'll surface as a fresh
|
||||
|
||||
Reference in New Issue
Block a user