package run import ( "io" "os" "os/exec" "syscall" ) const helmBin = "/usr/bin/helm" // The cmd interface provides a generic form of exec.Cmd so that it can be mocked out in tests. type cmd interface { // methods that exist on exec.Cmd Output() ([]byte, error) Run() error CombinedOutput() ([]byte, error) Start() error StderrPipe() (io.ReadCloser, error) StdinPipe() (io.WriteCloser, error) StdoutPipe() (io.ReadCloser, error) String() string Wait() error // setters for struct fields set by callers of exec.Cmd Path(string) Args([]string) Env([]string) Dir(string) Stdin(io.Reader) Stdout(io.Writer) Stderr(io.Writer) ExtraFiles([]*os.File) SysProcAttr(*syscall.SysProcAttr) // getters for struct fields generated by exec.Cmd Process() *os.Process ProcessState() *os.ProcessState } // execCmd wraps exec.Cmd along with setters for exec.Cmd's struct fields, implementing the cmd interface. type execCmd struct { *exec.Cmd } var command = func(path string, args ...string) cmd { return &execCmd{ Cmd: exec.Command(path, args...), } } func (c *execCmd) Path(p string) { c.Cmd.Path = p } func (c *execCmd) Args(a []string) { c.Cmd.Args = a } func (c *execCmd) Env(e []string) { c.Cmd.Env = e } func (c *execCmd) Dir(d string) { c.Cmd.Dir = d } func (c *execCmd) Stdin(s io.Reader) { c.Cmd.Stdin = s } func (c *execCmd) Stdout(s io.Writer) { c.Cmd.Stdout = s } func (c *execCmd) Stderr(s io.Writer) { c.Cmd.Stderr = s } func (c *execCmd) ExtraFiles(f []*os.File) { c.Cmd.ExtraFiles = f } func (c *execCmd) SysProcAttr(s *syscall.SysProcAttr) { c.Cmd.SysProcAttr = s } func (c *execCmd) Process() *os.Process { return c.Cmd.Process } func (c *execCmd) ProcessState() *os.ProcessState { return c.Cmd.ProcessState }