Skip to content

Commit

Permalink
fix: enable paths with junction inside windows (#5245)
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Sawert <simon@sawert.se>
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
  • Loading branch information
3 people authored Dec 26, 2024
1 parent 1467bc0 commit 7806463
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
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)
}

0 comments on commit 7806463

Please sign in to comment.