Skip to content

fix: enable paths with junction inside windows #5245

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

Merged
merged 11 commits into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/fsutils/fsutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func EvalSymlinks(path string) (string, error) {
}

var er evalSymlinkRes
er.path, er.err = filepath.EvalSymlinks(path)
er.path, er.err = evalSymlinks(path)
evalSymlinkCache.Store(path, er)

return er.path, er.err
Expand Down
9 changes: 9 additions & 0 deletions pkg/fsutils/fsutils_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//go:build !windows

package fsutils

import "path/filepath"

func evalSymlinks(path string) (string, error) {
return filepath.EvalSymlinks(path)
}
39 changes: 39 additions & 0 deletions pkg/fsutils/fsutils_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//go:build windows

package fsutils

import (
"errors"
"os"
"path/filepath"
"syscall"
)

// This is a workaround for the behavior of [filepath.EvalSymlinks],
// which fails with [syscall.ENOTDIR] if the specified path contains a junction on Windows.
// Junctions can occur, for example, when a volume is mounted as a subdirectory inside another drive.
// This can usually happen when using the Dev Drives feature and replacing existing directories.
// See: https://github.com/golang/go/issues/40180
//
// Since [syscall.ENOTDIR] is only returned when calling [filepath.EvalSymlinks] on Windows
// if part of the presented path is a junction and nothing before was a symlink,
// we simply treat this as NOT symlink,
// because a symlink over the junction makes no sense at all.
func evalSymlinks(path string) (string, error) {
resolved, err := filepath.EvalSymlinks(path)
if err == nil {
return resolved, nil
}

if !errors.Is(err, syscall.ENOTDIR) {
return "", err
}

_, err = os.Stat(path)
if err != nil {
return "", err
}

// If exists, we make the path absolute, to be sure...
return filepath.Abs(path)
}
Loading