fix(paths): Add cross-platform path normalization (#18939)

This commit is contained in:
Spencer
2026-02-17 17:52:55 -05:00
committed by GitHub
parent 4fe86dbd4f
commit 5e2f5df62c
3 changed files with 75 additions and 56 deletions
+44
View File
@@ -13,6 +13,7 @@ import {
unescapePath,
isSubpath,
shortenPath,
normalizePath,
resolveToRealPath,
} from './paths.js';
@@ -521,3 +522,46 @@ describe('resolveToRealPath', () => {
expect(resolveToRealPath(input)).toBe(expected);
});
});
describe('normalizePath', () => {
it('should resolve a relative path to an absolute path', () => {
const result = normalizePath('some/relative/path');
expect(result).toMatch(/^\/|^[a-z]:\//);
});
it('should convert all backslashes to forward slashes', () => {
const result = normalizePath(path.resolve('some', 'path'));
expect(result).not.toContain('\\');
});
describe.skipIf(process.platform !== 'win32')('on Windows', () => {
it('should lowercase the entire path', () => {
const result = normalizePath('C:\\Users\\TEST');
expect(result).toBe(result.toLowerCase());
});
it('should normalize drive letters to lowercase', () => {
const result = normalizePath('C:\\');
expect(result).toMatch(/^c:\//);
});
it('should handle mixed separators', () => {
const result = normalizePath('C:/Users\\Test/file.txt');
expect(result).not.toContain('\\');
expect(result).toMatch(/^c:\/users\/test\/file\.txt$/);
});
});
describe.skipIf(process.platform === 'win32')('on POSIX', () => {
it('should preserve case', () => {
const result = normalizePath('/usr/Local/Bin');
expect(result).toContain('Local');
expect(result).toContain('Bin');
});
it('should use forward slashes', () => {
const result = normalizePath('/usr/local/bin');
expect(result).toBe('/usr/local/bin');
});
});
});
+4 -2
View File
@@ -319,13 +319,15 @@ export function getProjectHash(projectRoot: string): string {
}
/**
* Normalizes a path for reliable comparison.
* Normalizes a path for reliable comparison across platforms.
* - Resolves to an absolute path.
* - Converts all path separators to forward slashes.
* - On Windows, converts to lowercase for case-insensitivity.
*/
export function normalizePath(p: string): string {
const resolved = path.resolve(p);
return process.platform === 'win32' ? resolved.toLowerCase() : resolved;
const normalized = resolved.replace(/\\/g, '/');
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
}
/**