Skip to content

Commit 7806463

Browse files
blaubaerbombsimonldez
authored
fix: enable paths with junction inside windows (#5245)
Co-authored-by: Simon Sawert <[email protected]> Co-authored-by: Fernandez Ludovic <[email protected]>
1 parent 1467bc0 commit 7806463

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

pkg/fsutils/fsutils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func EvalSymlinks(path string) (string, error) {
6161
}
6262

6363
var er evalSymlinkRes
64-
er.path, er.err = filepath.EvalSymlinks(path)
64+
er.path, er.err = evalSymlinks(path)
6565
evalSymlinkCache.Store(path, er)
6666

6767
return er.path, er.err

pkg/fsutils/fsutils_unix.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//go:build !windows
2+
3+
package fsutils
4+
5+
import "path/filepath"
6+
7+
func evalSymlinks(path string) (string, error) {
8+
return filepath.EvalSymlinks(path)
9+
}

pkg/fsutils/fsutils_windows.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//go:build windows
2+
3+
package fsutils
4+
5+
import (
6+
"errors"
7+
"os"
8+
"path/filepath"
9+
"syscall"
10+
)
11+
12+
// This is a workaround for the behavior of [filepath.EvalSymlinks],
13+
// which fails with [syscall.ENOTDIR] if the specified path contains a junction on Windows.
14+
// Junctions can occur, for example, when a volume is mounted as a subdirectory inside another drive.
15+
// This can usually happen when using the Dev Drives feature and replacing existing directories.
16+
// See: https://github.com/golang/go/issues/40180
17+
//
18+
// Since [syscall.ENOTDIR] is only returned when calling [filepath.EvalSymlinks] on Windows
19+
// if part of the presented path is a junction and nothing before was a symlink,
20+
// we simply treat this as NOT symlink,
21+
// because a symlink over the junction makes no sense at all.
22+
func evalSymlinks(path string) (string, error) {
23+
resolved, err := filepath.EvalSymlinks(path)
24+
if err == nil {
25+
return resolved, nil
26+
}
27+
28+
if !errors.Is(err, syscall.ENOTDIR) {
29+
return "", err
30+
}
31+
32+
_, err = os.Stat(path)
33+
if err != nil {
34+
return "", err
35+
}
36+
37+
// If exists, we make the path absolute, to be sure...
38+
return filepath.Abs(path)
39+
}

0 commit comments

Comments
 (0)