cmd/buildlet: execute shell scripts through bash on mobile platforms

iOS and Android can't execute shell directly. Use bash instead.

Updates golang/go#31722

Change-Id: I288f4af2abe2bed268b7c219608067047d2e0d9c
Reviewed-on: https://go-review.googlesource.com/c/build/+/174997
Run-TryBot: Elias Naur <mail@eliasnaur.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/cmd/buildlet/buildlet.go b/cmd/buildlet/buildlet.go
index 70bc24c..0c4a831 100644
--- a/cmd/buildlet/buildlet.go
+++ b/cmd/buildlet/buildlet.go
@@ -943,7 +943,13 @@
 	}
 	env = setPathEnv(env, r.PostForm["path"], *workDir)
 
-	cmd := exec.Command(absCmd, r.PostForm["cmdArg"]...)
+	var cmd *exec.Cmd
+	if needsBashWrapper(absCmd) {
+		cmd = exec.Command("bash", absCmd)
+	} else {
+		cmd = exec.Command(absCmd)
+	}
+	cmd.Args = append(cmd.Args, r.PostForm["cmdArg"]...)
 	cmd.Dir = dir
 	cmdOutput := flushWriter{w}
 	cmd.Stdout = cmdOutput
@@ -986,6 +992,17 @@
 	log.Printf("[%p] Run = %s, after %v", cmd, state, time.Since(t0))
 }
 
+// needsBashWrappers reports whether the given command needs to
+// run through bash.
+func needsBashWrapper(cmd string) bool {
+	if !strings.HasSuffix(cmd, ".bash") {
+		return false
+	}
+	// The mobile platforms can't execute shell scripts directly.
+	ismobile := runtime.GOOS == "android" || runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64")
+	return ismobile
+}
+
 // pathNotExist reports whether path does not exist.
 func pathNotExist(path string) bool {
 	_, err := os.Stat(path)