func runCommand()

in integration_test/gce-testing-internal/gce/gce_testing.go [708:745]


func runCommand(ctx context.Context, logger *log.Logger, stdin io.Reader, args []string, env map[string]string) (CommandOutput, error) {
	var output CommandOutput
	if len(args) < 1 {
		return output, fmt.Errorf("runCommand() needs a nonempty argument slice, got %v", args)
	}
	cmd := exec.CommandContext(ctx, args[0], args[1:]...)

	cmd.Stdin = stdin

	var stdoutBuilder strings.Builder
	var stderrBuilder strings.Builder
	var interleavedBuilder strings.Builder

	interleavedWriter := &ThreadSafeWriter{guarded: &interleavedBuilder}
	cmd.Stdout = io.MultiWriter(&stdoutBuilder, interleavedWriter)
	cmd.Stderr = io.MultiWriter(&stderrBuilder, interleavedWriter)
	if len(env) > 0 {
		environment := []string{}
		for k, v := range env {
			environment = append(environment, fmt.Sprintf("%s=%s", k, v))
		}
		cmd.Env = environment
	}

	err := cmd.Run()

	if err != nil {
		err = fmt.Errorf("Command failed: %v\n%v\nstdout+stderr: %s", args, err, interleavedBuilder.String())
	}

	logger.Printf("exit code: %v", cmd.ProcessState.ExitCode())
	logger.Printf("stdout+stderr: %s", interleavedBuilder.String())

	output.Stdout = stdoutBuilder.String()
	output.Stderr = stderrBuilder.String()

	return output, err
}