-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve Windows drive letter URI handling #1816
base: main
Are you sure you want to change the base?
Conversation
sailingKieler
commented
Feb 21, 2025
- added additional test cases
… platform regarding drive letter cases * added additional test cases
@@ -16,6 +16,8 @@ export namespace UriUtils { | |||
export const joinPath = Utils.joinPath; | |||
export const resolvePath = Utils.resolvePath; | |||
|
|||
const isWindows = process?.platform === 'win32'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not portable. Here's a good reference for how to make it work both in Node.js and browser:
https://github.com/eclipse-theia/theia/blob/master/packages/core/src/common/os.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we actually need to distinguish the browser case here?
Do we have to deal with windows drive letters in that scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't matter. Calling process?.platform
will result in an error which will crash the language server in the browser. You need to specifically test for typeof === 'undefined'
. See:
langium/packages/langium/src/utils/promise-utils.ts
Lines 19 to 23 in fa8371b
if (typeof setImmediate === 'undefined') { | |
setTimeout(resolve, 0); | |
} else { | |
setImmediate(resolve); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, I'd be in favor of calling URI.parse
on the input in case the input is a string. It isn't obvious we are expecting a path, and should much rather expect a stringified URI, like we're doing in the other methods. This alleviates te need to perform that kind of normalization ourselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, I'd be in favor of calling URI.parse on the input in case the input is a string. It isn't obvious we are expecting a path, and should much rather expect a stringified URI, like we're doing in the other methods.
I full agree. I just came up with the proposed change after I realized the painful way that the current implementation has an issue with differing drive letter cases. (It fits very well for a use case in a commercial project.)
Beyond the test cases we have so far, how should relativize
act in case of a call like
UriUtils.relativize(
URI.file('C:\\a'),
URI.file('D:\\b')
)
Return undefined
? Throwing an exception would be very mean...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should follow/emulate whatever node:path
is doing there. It will simply return D:\b
.
@@ -36,6 +36,10 @@ export namespace UriUtils { | |||
if (toParts[0] && upperCaseDriveLetter.test(toParts[0])) { | |||
toParts[0] = toParts[0].toLowerCase(); | |||
} | |||
if (fromParts[0] !== toParts[0]) { | |||
// in case of different drive letters, we cannot compute a relative path, so... | |||
return toPath.toLowerCase(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Why lowercase the whole string? We can just keep the original capitalization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True.
0422556
to
189a937
Compare
189a937
to
02fd044
Compare
Some tests with string input to |