resources.relativePath needs a ignoreCase argument. Fixes #76421

This commit is contained in:
Martin Aeschlimann 2019-07-04 12:36:15 +02:00
parent 3a87cea73d
commit 05f8ca5b40
2 changed files with 22 additions and 4 deletions

View file

@ -221,7 +221,7 @@ export function addTrailingPathSeparator(resource: URI, sep: string = paths.sep)
* Returns a relative path between two URIs. If the URIs don't have the same schema or authority, `undefined` is returned.
* The returned relative path always uses forward slashes.
*/
export function relativePath(from: URI, to: URI): string | undefined {
export function relativePath(from: URI, to: URI, ignoreCase = hasToIgnoreCase(from)): string | undefined {
if (from.scheme !== to.scheme || !isEqualAuthority(from.authority, to.authority)) {
return undefined;
}
@ -229,7 +229,20 @@ export function relativePath(from: URI, to: URI): string | undefined {
const relativePath = paths.relative(from.path, to.path);
return isWindows ? extpath.toSlashes(relativePath) : relativePath;
}
return paths.posix.relative(from.path || '/', to.path || '/');
let fromPath = from.path || '/', toPath = to.path || '/';
if (ignoreCase) {
// make casing of fromPath match toPath
let i = 0;
for (const len = Math.min(fromPath.length, toPath.length); i < len; i++) {
if (fromPath.charCodeAt(i) !== toPath.charCodeAt(i)) {
if (fromPath.charAt(i).toLowerCase() !== toPath.charAt(i).toLowerCase()) {
break;
}
}
}
fromPath = toPath.substr(0, i) + fromPath.substr(i);
}
return paths.posix.relative(fromPath, toPath);
}
/**

View file

@ -237,8 +237,8 @@ suite('Resources', () => {
}
}
function assertRelativePath(u1: URI, u2: URI, expectedPath: string | undefined, ignoreJoin?: boolean) {
assert.equal(relativePath(u1, u2), expectedPath, `from ${u1.toString()} to ${u2.toString()}`);
function assertRelativePath(u1: URI, u2: URI, expectedPath: string | undefined, ignoreJoin?: boolean, ignoreCase?: boolean) {
assert.equal(relativePath(u1, u2, ignoreCase), expectedPath, `from ${u1.toString()} to ${u2.toString()}`);
if (expectedPath !== undefined && !ignoreJoin) {
assertEqualURI(removeTrailingPathSeparator(joinPath(u1, expectedPath)), removeTrailingPathSeparator(u2), 'joinPath on relativePath should be equal');
}
@ -263,6 +263,11 @@ suite('Resources', () => {
assertRelativePath(URI.parse('foo://a2/b'), URI.parse('foo://a/b'), undefined);
assertRelativePath(URI.parse('goo://a/b'), URI.parse('foo://a/b'), undefined);
assertRelativePath(URI.parse('foo://a/foo'), URI.parse('foo://A/FOO/bar/goo'), 'bar/goo', false, true);
assertRelativePath(URI.parse('foo://a/foo'), URI.parse('foo://A/FOO/BAR/GOO'), 'BAR/GOO', false, true);
assertRelativePath(URI.parse('foo://a/foo/xoo'), URI.parse('foo://A/FOO/BAR/GOO'), '../BAR/GOO', false, true);
assertRelativePath(URI.parse('foo:///c:/a/foo'), URI.parse('foo:///C:/a/foo/xoo/'), 'xoo', false, true);
if (isWindows) {
assertRelativePath(URI.file('c:\\foo\\bar'), URI.file('c:\\foo\\bar'), '');
assertRelativePath(URI.file('c:\\foo\\bar\\huu'), URI.file('c:\\foo\\bar'), '..');