From f0ce7984ced36f9578317b896079fb3af3566289 Mon Sep 17 00:00:00 2001 From: mappu Date: Wed, 30 Apr 2025 16:29:50 +1200 Subject: [PATCH] miqt-docker: windows compatibility --- cmd/miqt-docker/filepath.go | 16 +++++++++++++--- cmd/miqt-docker/main.go | 23 ++++++++++++++++++----- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/cmd/miqt-docker/filepath.go b/cmd/miqt-docker/filepath.go index 5a5661c8..662aff57 100644 --- a/cmd/miqt-docker/filepath.go +++ b/cmd/miqt-docker/filepath.go @@ -2,6 +2,7 @@ package main import ( "errors" + "fmt" "path/filepath" "runtime" "strings" @@ -16,6 +17,8 @@ func highestCommonParent(paths []string) (string, error) { parts := strings.Split(paths[0], string(filepath.Separator)) + caseSensitive := runtime.GOOS != "windows" + for _, check := range paths { checkn := strings.Split(check, string(filepath.Separator)) @@ -25,8 +28,15 @@ func highestCommonParent(paths []string) (string, error) { } for i, checkpart := range checkn[0:len(parts)] { // len(parts) is now <= len(checkn) so this is safe - if parts[i] == checkpart { - continue + if caseSensitive { + if parts[i] == checkpart { + continue + } + } else { + // case insensitive comparison + if strings.EqualFold(parts[i], checkpart) { + continue + } } // Divergence from i: onwards @@ -45,7 +55,7 @@ func highestCommonParent(paths []string) (string, error) { if isEmpty { if runtime.GOOS == "windows" { - return "", errors.New("Selected paths have no common ancestor") + return "", fmt.Errorf("Selected paths have no common ancestor: %v", paths) } return `/`, nil } diff --git a/cmd/miqt-docker/main.go b/cmd/miqt-docker/main.go index ffb1a100..5b9b2bb0 100644 --- a/cmd/miqt-docker/main.go +++ b/cmd/miqt-docker/main.go @@ -9,6 +9,7 @@ import ( "os" "os/exec" "os/user" + "path" "path/filepath" "regexp" "runtime" @@ -224,15 +225,27 @@ func getDockerRunArgsForGlob(dockerfiles []fs.DirEntry, containerNameGlob string return nil, err } - mountDir := `/src/` + filepath.Base(cwd) // Don't use /src directly, otherwise -android-build will not know the package name for top-level builds + // Don't mount directly on /src , otherwise -android-build will not know + // the package name for top-level builds. Use a subfolder within it + mountDir := `/src/` + filepath.Base(cwd) - fullCommand = append(fullCommand, `-v`, basedir+`:`+mountDir, `-w`, filepath.Join(mountDir, relCwd)) + if runtime.GOOS == "windows" { + // convert C:\foo\bar paths to /c/foo/bar that Docker understands + // Otherwise, you experience "invalid mode" when the : is parsed + basedir = `/` + strings.ToLower(string(basedir[0])) + `/` + strings.ReplaceAll(basedir[3:], `\`, `/`) - fullCommand = append(fullCommand, `-e`, `HOME=/tmp`) + // Always forwardslashes for in-docker paths, even on Windows OS + mountDir = strings.ReplaceAll(mountDir, `\`, `/`) + } - // Final standard docker commands + fullCommand = append(fullCommand, + `-v`, basedir+`:`+mountDir, + `-w`, path.Join(mountDir, relCwd), - fullCommand = append(fullCommand, containerName+`:`+dockerfileHash) // , `/bin/bash`, `-c`) + // Final standard docker commands + `-e`, `HOME=/tmp`, + containerName+`:`+dockerfileHash, + ) return fullCommand, nil }