github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/scripts/try-merge/execute.go (about)

     1  // Copyright 2023 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package main
     5  
     6  import (
     7  	"bytes"
     8  	"errors"
     9  	"fmt"
    10  	"os/exec"
    11  )
    12  
    13  type executeArgs struct {
    14  	command string
    15  	args    []string
    16  	dir     string
    17  }
    18  
    19  type executeResults struct {
    20  	runError error
    21  	exitCode int
    22  
    23  	stdout, stderr []byte
    24  }
    25  
    26  func (res executeResults) String() string {
    27  	var str string
    28  	str += fmt.Sprintf("runError: %v\n", res.runError)
    29  	str += fmt.Sprintf("exitCode: %d\n", res.exitCode)
    30  	str += fmt.Sprintf("stdout: %s\n", res.stdout)
    31  	str += fmt.Sprintf("stderr: %s", res.stderr)
    32  	return str
    33  }
    34  
    35  func execute(args executeArgs) (res executeResults) {
    36  	cmd := exec.Command(args.command, args.args...)
    37  	cmd.Dir = args.dir
    38  
    39  	stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
    40  	cmd.Stdout, cmd.Stderr = stdout, stderr
    41  
    42  	err := cmd.Run()
    43  	res.runError = err
    44  	if e := (&exec.ExitError{}); errors.As(err, &e) {
    45  		res.exitCode = e.ProcessState.ExitCode()
    46  	}
    47  	res.stdout, res.stderr = stdout.Bytes(), stderr.Bytes()
    48  	return
    49  }
    50  
    51  func handleExecuteError(res executeResults) {
    52  	if res.exitCode > 0 {
    53  		stderrf("command failed with exit code %d\n", res.exitCode)
    54  	}
    55  	if err := res.runError; err != nil {
    56  		stderrf("stderr: %s\n", res.stderr)
    57  		panic(err)
    58  	}
    59  }