diff --git a/core/BUILD b/core/BUILD index fee6d3a0..2f5ec601 100644 --- a/core/BUILD +++ b/core/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", @@ -16,3 +16,9 @@ go_library( "@com_github_mitchellh_go_homedir//:go_default_library", ], ) + +go_test( + name = "go_default_test", + srcs = ["core_test.go"], + embed = [":go_default_library"], +) diff --git a/core/core.go b/core/core.go index 0fa1f7e5..0b68a924 100644 --- a/core/core.go +++ b/core/core.go @@ -14,6 +14,7 @@ import ( "os/signal" "path/filepath" "regexp" + "runtime" "sort" "strings" "sync" @@ -456,23 +457,39 @@ func linkLocalBazel(baseDirectory string, bazelPath string) (string, error) { return destinationPath, nil } -func maybeDelegateToWrapper(bazel string) string { - if GetEnvOrConfig(skipWrapperEnv) != "" { - return bazel - } - - wd, err := os.Getwd() - if err != nil { +func maybeDelegateToWrapperFromDir(bazel string, wd string, ignoreEnv bool) string { + if !ignoreEnv && GetEnvOrConfig(skipWrapperEnv) != "" { return bazel } root := findWorkspaceRoot(wd) wrapper := filepath.Join(root, wrapperPath) - if stat, err := os.Stat(wrapper); err != nil || stat.IsDir() || stat.Mode().Perm()&0111 == 0 { + if stat, err := os.Stat(wrapper); err == nil && !stat.Mode().IsDir() && stat.Mode().Perm()&0111 != 0 { + return wrapper + } + + if runtime.GOOS == "windows" { + powershell_wrapper := filepath.Join(root, wrapperPath + ".ps1") + if stat, err := os.Stat(powershell_wrapper); err == nil && !stat.Mode().IsDir() { + return powershell_wrapper + } + + batch_wrapper := filepath.Join(root, wrapperPath + ".bat") + if stat, err := os.Stat(batch_wrapper); err == nil && !stat.Mode().IsDir() { + return batch_wrapper + } + } + + return bazel +} + +func maybeDelegateToWrapper(bazel string) string { + wd, err := os.Getwd() + if err != nil { return bazel } - return wrapper + return maybeDelegateToWrapperFromDir(bazel, wd, false) } func prependDirToPathList(cmd *exec.Cmd, dir string) { diff --git a/core/core_test.go b/core/core_test.go new file mode 100644 index 00000000..2ae1a803 --- /dev/null +++ b/core/core_test.go @@ -0,0 +1,155 @@ +package core + +import ( + "io/ioutil" + "log" + "os" + "path/filepath" + "runtime" + "testing" +) + +func TestMaybeDelegateToNoWrapper(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "TestMaybeDelegateToNoWrapper") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + os.MkdirAll(tmpDir, os.ModeDir | 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "WORKSPACE"), []byte(""), 0600) + ioutil.WriteFile(filepath.Join(tmpDir, "BUILD"), []byte(""), 0600) + + entrypoint := maybeDelegateToWrapperFromDir("bazel_real", tmpDir, true) + expected := "bazel_real" + + if entrypoint != expected { + t.Fatalf("Expected to delegate bazel to %q, but got %q", expected, entrypoint) + } +} + +func TestMaybeDelegateToNoNonExecutableWrapper(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "TestMaybeDelegateToNoNonExecutableWrapper") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + os.MkdirAll(tmpDir, os.ModeDir | 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "WORKSPACE"), []byte(""), 0600) + ioutil.WriteFile(filepath.Join(tmpDir, "BUILD"), []byte(""), 0600) + + os.MkdirAll(filepath.Join(tmpDir, "tools"), os.ModeDir | 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "tools", "bazel"), []byte(""), 0600) + + entrypoint := maybeDelegateToWrapperFromDir("bazel_real", tmpDir, true) + expected := "bazel_real" + + if entrypoint != expected { + t.Fatalf("Expected to delegate bazel to %q, but got %q", expected, entrypoint) + } +} + +func TestMaybeDelegateToStandardWrapper(t *testing.T) { + var tmpDir, err = ioutil.TempDir("", "TestMaybeDelegateToStandardWrapper") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + os.MkdirAll(tmpDir, os.ModeDir | 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "WORKSPACE"), []byte(""), 0600) + ioutil.WriteFile(filepath.Join(tmpDir, "BUILD"), []byte(""), 0600) + + os.MkdirAll(filepath.Join(tmpDir, "tools"), os.ModeDir | 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "tools", "bazel"), []byte(""), 0700) + + entrypoint := maybeDelegateToWrapperFromDir("bazel_real", tmpDir, true) + expected := filepath.Join(tmpDir, "tools", "bazel") + + if entrypoint != expected { + t.Fatalf("Expected to delegate bazel to %q, but got %q", expected, entrypoint) + } +} + +func TestMaybeDelegateToPowershellWrapper(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "TestMaybeDelegateToPowershellWrapper") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + os.MkdirAll(tmpDir, os.ModeDir | 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "WORKSPACE"), []byte(""), 0600) + ioutil.WriteFile(filepath.Join(tmpDir, "BUILD"), []byte(""), 0600) + + os.MkdirAll(filepath.Join(tmpDir, "tools"), os.ModeDir | 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "tools", "bazel.ps1"), []byte(""), 0700) + + entrypoint := maybeDelegateToWrapperFromDir("bazel_real", tmpDir, true) + expected := filepath.Join(tmpDir, "tools", "bazel.ps1") + + // Only windows platforms use powershell wrappers + if runtime.GOOS != "windows" { + expected = "bazel_real" + } + + if entrypoint != expected { + t.Fatalf("Expected to delegate bazel to %q, but got %q", expected, entrypoint) + } +} + +func TestMaybeDelegateToBatchWrapper(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "TestMaybeDelegateToBatchWrapper") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + os.MkdirAll(tmpDir, os.ModeDir | 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "WORKSPACE"), []byte(""), 0600) + ioutil.WriteFile(filepath.Join(tmpDir, "BUILD"), []byte(""), 0600) + + os.MkdirAll(filepath.Join(tmpDir, "tools"), os.ModeDir | 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "tools", "bazel.bat"), []byte(""), 0700) + + entrypoint := maybeDelegateToWrapperFromDir("bazel_real", tmpDir, true) + expected := filepath.Join(tmpDir, "tools", "bazel.bat") + + // Only windows platforms use batch wrappers + if runtime.GOOS != "windows" { + expected = "bazel_real" + } + + if entrypoint != expected { + t.Fatalf("Expected to delegate bazel to %q, but got %q", expected, entrypoint) + } +} + +func TestMaybeDelegateToPowershellOverBatchWrapper(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "TestMaybeDelegateToPowershellOverBatchWrapper") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + os.MkdirAll(tmpDir, os.ModeDir | 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "WORKSPACE"), []byte(""), 0600) + ioutil.WriteFile(filepath.Join(tmpDir, "BUILD"), []byte(""), 0600) + + os.MkdirAll(filepath.Join(tmpDir, "tools"), os.ModeDir | 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "tools", "bazel.ps1"), []byte(""), 0700) + ioutil.WriteFile(filepath.Join(tmpDir, "tools", "bazel.bat"), []byte(""), 0700) + + entrypoint := maybeDelegateToWrapperFromDir("bazel_real", tmpDir, true) + expected := filepath.Join(tmpDir, "tools", "bazel.ps1") + + // Only windows platforms use powershell or batch wrappers + if runtime.GOOS != "windows" { + expected = "bazel_real" + } + + if entrypoint != expected { + t.Fatalf("Expected to delegate bazel to %q, but got %q", expected, entrypoint) + } +}