github.hscsec.cn/openshift/source-to-image@v1.2.0/pkg/util/cmd/cmd.go (about)

     1  package cmd
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"os/exec"
     7  )
     8  
     9  // CommandOpts contains options to attach Stdout/err to a command to run
    10  // or set its initial directory
    11  type CommandOpts struct {
    12  	Stdout    io.Writer
    13  	Stderr    io.Writer
    14  	Dir       string
    15  	EnvAppend []string
    16  }
    17  
    18  // CommandRunner executes OS commands with the given parameters and options
    19  type CommandRunner interface {
    20  	RunWithOptions(opts CommandOpts, name string, arg ...string) error
    21  	Run(name string, arg ...string) error
    22  	StartWithStdoutPipe(opts CommandOpts, name string, arg ...string) (io.ReadCloser, error)
    23  	Wait() error
    24  }
    25  
    26  // NewCommandRunner creates a new instance of the default implementation of
    27  // CommandRunner
    28  func NewCommandRunner() CommandRunner {
    29  	return &runner{}
    30  }
    31  
    32  type runner struct {
    33  	cmd *exec.Cmd
    34  }
    35  
    36  // RunWithOptions runs a command with the provided options
    37  func (c *runner) RunWithOptions(opts CommandOpts, name string, arg ...string) error {
    38  	cmd := exec.Command(name, arg...)
    39  	if opts.Stdout != nil {
    40  		cmd.Stdout = opts.Stdout
    41  	}
    42  	if opts.Stderr != nil {
    43  		cmd.Stderr = opts.Stderr
    44  	}
    45  	if opts.Dir != "" {
    46  		cmd.Dir = opts.Dir
    47  	}
    48  	if len(opts.EnvAppend) > 0 {
    49  		cmd.Env = os.Environ()
    50  		cmd.Env = append(cmd.Env, opts.EnvAppend...)
    51  	}
    52  	return cmd.Run()
    53  }
    54  
    55  // Run executes a command with default options
    56  func (c *runner) Run(name string, arg ...string) error {
    57  	return c.RunWithOptions(CommandOpts{}, name, arg...)
    58  }
    59  
    60  // StartWithStdoutPipe executes a command returning a ReadCloser connected to
    61  // the command's stdout.
    62  func (c *runner) StartWithStdoutPipe(opts CommandOpts, name string, arg ...string) (io.ReadCloser, error) {
    63  	c.cmd = exec.Command(name, arg...)
    64  	if opts.Stderr != nil {
    65  		c.cmd.Stderr = opts.Stderr
    66  	}
    67  	if opts.Dir != "" {
    68  		c.cmd.Dir = opts.Dir
    69  	}
    70  	if len(opts.EnvAppend) > 0 {
    71  		c.cmd.Env = os.Environ()
    72  		c.cmd.Env = append(c.cmd.Env, opts.EnvAppend...)
    73  	}
    74  	r, err := c.cmd.StdoutPipe()
    75  	if err != nil {
    76  		return nil, err
    77  	}
    78  	return r, c.cmd.Start()
    79  }
    80  
    81  // Wait waits for the command to exit.
    82  func (c *runner) Wait() error {
    83  	return c.cmd.Wait()
    84  }