diff --git a/util/gitutil/gitutil.go b/util/gitutil/gitutil.go index c781311e..3347415e 100644 --- a/util/gitutil/gitutil.go +++ b/util/gitutil/gitutil.go @@ -66,7 +66,11 @@ func (c *Git) IsDirty() bool { } func (c *Git) RootDir() (string, error) { - return c.clean(c.run("rev-parse", "--show-toplevel")) + root, err := c.clean(c.run("rev-parse", "--show-toplevel")) + if err != nil { + return "", err + } + return sanitizePath(root), nil } func (c *Git) GitDir() (string, error) { diff --git a/util/gitutil/gitpath_unix.go b/util/gitutil/path_unix.go similarity index 60% rename from util/gitutil/gitpath_unix.go rename to util/gitutil/path_unix.go index 898cb654..41b4bd61 100644 --- a/util/gitutil/gitpath_unix.go +++ b/util/gitutil/path_unix.go @@ -7,6 +7,8 @@ import ( "os" "os/exec" "path/filepath" + "regexp" + "strings" "github.com/moby/sys/mountinfo" ) @@ -40,3 +42,18 @@ func gitPath(wd string) (string, error) { } return exec.LookPath("git") } + +var windowsPathRegex = regexp.MustCompile(`^[A-Za-z]:[\\/].*$`) + +func sanitizePath(path string) string { + // If we're running in WSL, we need to convert Windows paths to Unix paths. + // This is because the git binary can be invoked through `git.exe` and + // therefore returns Windows paths. + if os.Getenv("WSL_DISTRO_NAME") != "" && windowsPathRegex.MatchString(path) { + unixPath := strings.ReplaceAll(path, "\\", "/") + drive := strings.ToLower(string(unixPath[0])) + rest := filepath.Clean(unixPath[3:]) + return filepath.Join("/mnt", drive, rest) + } + return filepath.Clean(path) +} diff --git a/util/gitutil/path_unix_test.go b/util/gitutil/path_unix_test.go new file mode 100644 index 00000000..591d5fcd --- /dev/null +++ b/util/gitutil/path_unix_test.go @@ -0,0 +1,19 @@ +//go:build !windows +// +build !windows + +package gitutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSanitizePathUnix(t *testing.T) { + assert.Equal(t, "/home/foobar", sanitizePath("/home/foobar")) +} + +func TestSanitizePathWSL(t *testing.T) { + t.Setenv("WSL_DISTRO_NAME", "Ubuntu") + assert.Equal(t, "/mnt/c/Users/foobar", sanitizePath("C:\\Users\\foobar")) +} diff --git a/util/gitutil/gitpath_windows.go b/util/gitutil/path_windows.go similarity index 52% rename from util/gitutil/gitpath_windows.go rename to util/gitutil/path_windows.go index a1a91538..050895f4 100644 --- a/util/gitutil/gitpath_windows.go +++ b/util/gitutil/path_windows.go @@ -2,8 +2,13 @@ package gitutil import ( "os/exec" + "path/filepath" ) func gitPath(wd string) (string, error) { return exec.LookPath("git.exe") } + +func sanitizePath(path string) string { + return filepath.ToSlash(filepath.Clean(path)) +} diff --git a/util/gitutil/path_windows_test.go b/util/gitutil/path_windows_test.go new file mode 100644 index 00000000..5326e305 --- /dev/null +++ b/util/gitutil/path_windows_test.go @@ -0,0 +1,11 @@ +package gitutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSanitizePathWindows(t *testing.T) { + assert.Equal(t, "C:\\Users\\foobar", sanitizePath("C:/Users/foobar")) +}