Skip to content
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
28 changes: 28 additions & 0 deletions cmd/miqt-docker/filepath.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"path/filepath"
"regexp"
"runtime"
"strings"
)
Expand Down Expand Up @@ -62,3 +63,30 @@ func highestCommonParent(paths []string) (string, error) {

return strings.Join(parts, string(filepath.Separator)), nil
}

// maybeTransformCygpath converts a Cygwin or MSYS2 path to a Windows path
// that the path/filepath package will understand.
// This is to handle the case where `git` in $PATH is a Cygwin binary instead
// of a native one.
func maybeTransformCygpath(s string) string {
if runtime.GOOS == "windows" {

// Cygwin
// Paths of the form /cygdrive/c/Users/username/Desktop/
if strings.HasPrefix(s, `/cygdrive/`) {
parts := strings.Split(s[1:], `/`) // skip first slash
return strings.ToUpper(parts[1]) + `:\` + strings.Join(parts[2:], `\`)
}

// MSYS2
// Paths of the form /c/Users/username/Desktop/
if regexp.MustCompile(`^/[a-z]/`).MatchString(s) {
parts := strings.Split(s[1:], `/`) // skip first slash
return strings.ToUpper(parts[0]) + `:\` + strings.Join(parts[1:], `\`)
}

}

// Not an affected path, or, non-Windows OS
return s
}
58 changes: 58 additions & 0 deletions cmd/miqt-docker/filepath_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,61 @@ func TestHighestCommonParent(t *testing.T) {
}
}
}

func TestTransformCygpath(t *testing.T) {
if runtime.GOOS != "windows" {
t.Skip("Cygpath transforms are GOOS=windows only")
}

type testCase struct {
input string
expect string
}

cases := []testCase{

// No transform, no trailing slash
testCase{
input: `C:\normal\windows\path`,
expect: `C:\normal\windows\path`,
},

// No transform, has trailing slash
testCase{
input: `C:\normal\windows\path\`,
expect: `C:\normal\windows\path\`,
},

// Cygwin, no trailing slash
testCase{
input: `/cygdrive/c/normal/windows/path`,
expect: `C:\normal\windows\path`,
},

// Cygwin, has trailing slash
testCase{
input: `/cygdrive/c/normal/windows/path/`,
expect: `C:\normal\windows\path\`,
},

// MSYS2, no trailing slash
testCase{
input: `/f/normal/windows/path`,
expect: `F:\normal\windows\path`,
},

// MSYS2, has trailing slash
testCase{
input: `/f/normal/windows/path/`,
expect: `F:\normal\windows\path\`,
},
}

for idx, tc := range cases {
got := maybeTransformCygpath(tc.input)
if got != tc.expect {
t.Errorf("test %d: input(%v) got %q, want %q", idx, tc.input, got, tc.expect)
}
}

}
4 changes: 3 additions & 1 deletion cmd/miqt-docker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,9 @@ func getDockerRunArgsForGlob(dockerfiles []fs.DirEntry, containerNameGlob string
// Don't panic
} else {
if gitroot_sz := strings.TrimSpace(string(gitroot)); len(gitroot_sz) > 0 {
parentPaths = append(parentPaths, gitroot_sz)
// On Windows, sometimes Cygwin/MSYS git is in $PATH, which returns
// a special kind of filepath that requires conversion to use
parentPaths = append(parentPaths, maybeTransformCygpath(gitroot_sz))
}
}

Expand Down