| 10 | ) |
| 11 | |
| 12 | func RunShell(ctx context.Context, dir, bindir, script string, stdin io.Reader, useenvs, extraenvs []string) (string, string, error) { |
| 13 | // "-e -o pipefile" ensures a test will fail if any command |
| 14 | // fails unexpectedly. |
| 15 | cmd := exec.CommandContext(ctx, "bash", "-e", "-o", "pipefail", "-c", script) |
| 16 | cmd.Dir = dir |
| 17 | cmd.Env = []string{ |
| 18 | "AppData=" + dir, // For os.UserConfigDir on Windows. |
| 19 | "HOME=" + dir, // For os.User*Dir on Unix. |
| 20 | "LocalAppData=" + dir, // For os.UserCacheDir on Windows. |
| 21 | "PATH=" + bindir + string(os.PathListSeparator) + os.Getenv("PATH"), |
| 22 | "USERPROFILE=" + dir, // For os.UserHomeDir on Windows. |
| 23 | } |
| 24 | // Forward TMPDIR, TMP, and TEMP for os.TempDir. |
| 25 | for _, env := range append(useenvs, "TMPDIR", "TMP", "TEMP") { |
| 26 | if v, ok := os.LookupEnv(env); ok { |
| 27 | cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", env, v)) |
| 28 | } |
| 29 | } |
| 30 | cmd.Env = append(cmd.Env, extraenvs...) |
| 31 | cmd.Stdin = stdin |
| 32 | var stdout, stderr bytes.Buffer |
| 33 | cmd.Stdout = &stdout |
| 34 | cmd.Stderr = &stderr |
| 35 | err := cmd.Run() |
| 36 | return stdout.String(), stderr.String(), err |
| 37 | } |