-
Notifications
You must be signed in to change notification settings - Fork 634
Treat Windows junctions as symlinks in Realpath #186
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
Conversation
It may also be the case that we need more of this for other things, specifically I believe we use |
de16b2e
to
8998046
Compare
I've updated the PR to instead use the Windows API It's also what go-winio does: https://github.com/microsoft/go-winio/blob/3c9576c9346a1892dee136329e7e15309e82fb4f/pkg/fs/resolve.go#L85 But, we want the DOS path, not some sort of GUID volume path thingy, which is what importing the above would do, so I had to do it myself. |
Long paths strike again:
It seems like I'll need to go back to the non-syscall version... |
Oddly, this implies that the temp path I'm starting with is the But, I added something which calls out to node, and:
So, using the non-native resolver does the same as the old Go code, but it's also not less than 260 characters, so TS proper would have seen the |
This reverts commit f05c99d.
37dd04a
to
933f112
Compare
I've reverted back to the |
I'm actually going to revert it back again to the syscall based version; that's what Node is doing, and I think the actual difference here is that the tempdir given to us by Go is actually not a realpath itself. |
This reverts commit 933f112.
_FILE_ANY_ACCESS = 0 | ||
|
||
_FILE_SHARE_READ = 0x01 | ||
_FILE_SHARE_WRITE = 0x02 | ||
_FILE_SHARE_DELETE = 0x04 | ||
|
||
_OPEN_EXISTING = 0x03 | ||
|
||
_FILE_FLAG_BACKUP_SEMANTICS = 0x0200_0000 |
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 the naming convention used within the Go stdlib for Windows code that uses constants not defined elsewhere.
For a long time, Windows did not have real symlinks (now available in dev mode), so effectively every tool (e.g., pnpm) uses junctions instead.
CL 565136 (released in Go 1.23) changed Go's handling of Windows junctions such that they are no longer treated as symlinks, but as irregular files. This breaks
Realpath
in our code because we want to treat junctions as symlinks, which is how Node behaves.With pnpm on a path like
D:/project/node_modules/package/index.d.ts
, aRealpath
implementation might do something like this:D:/project/node_modules/package/index.d.ts
D:/project
is not a symlink, but is a dir. Continue.D:/project/node_modules
is not a symlink, but is a dir. Continue.D:/project/node_modules/package
is a symlink toD:/project/node_modules/.pnpm/[email protected]/node_modules/package
.D:/project/node_modules/.pnpm/[email protected]/node_modules/package/index.d.ts
D:/project
is not a symlink, but is a dir. Continue.D:/project/node_modules
is not a symlink, but is a dir. Continue.D:/project/node_modules/.pnpm
is not a symlink, but is a dir. Continue.D:/project/node_modules/.pnpm/[email protected]
is not a symlink, but is a dir. Continue.D:/project/node_modules/.pnpm/[email protected]/node_modules
is not a symlink, but is a dir. Continue.D:/project/node_modules/.pnpm/[email protected]/node_modules/package
is not a symlink, but is a dir. Continue.D:/project/node_modules/.pnpm/[email protected]/node_modules/package/index.d.ts
is not a symlink, nor is it a dir, but we're at the end.CL 565136 throws a wrench in things in that at step 4, it's not a symlink. But, since it's also not a dir, but an irregular file, the process bails because it doesn't make sense that there's a non-directory thing in the middle of a path.This PR copies the implementation ofEvalSymlinks
, modifying it slightly so tat on Windows, we treat a junction like a symlink. The rest of the code works fine after that.Another option is to setGODEBUG=winsymlink=0
(in env at build, or maybe ingo.mod
?), which restores the pre Go-1.23 behavior. But, I'm moderately wary of setting that at startup, or using it at all lest it be removed.I've instead looked for another way to do this via the Windows API, emulating what libuv and other packages like go-winio and the stdlib do; the PR now does that instead.
This deserves a test, but, that would require me knowing how to programmatically make a junction so that will take some more effort to figure out.Wrote a test.