mirror of
https://github.com/foomo/posh.git
synced 2025-10-16 12:45:38 +00:00
135 lines
2.7 KiB
Go
135 lines
2.7 KiB
Go
package shell
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"github.com/foomo/posh/pkg/log"
|
|
)
|
|
|
|
// Shell struct
|
|
type Shell struct {
|
|
l log.Logger
|
|
cmd *exec.Cmd
|
|
quiet bool
|
|
args []string
|
|
Stdin io.Reader
|
|
Stdout io.Writer
|
|
Stderr io.Writer
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Constructor
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func New(ctx context.Context, l log.Logger, inputs ...interface{}) *Shell {
|
|
var args []string
|
|
for _, input := range inputs {
|
|
if value, ok := input.(string); ok {
|
|
args = append(args, value)
|
|
} else if value, ok := input.([]string); ok {
|
|
args = append(args, value...)
|
|
} else {
|
|
args = append(args, fmt.Sprintf("%v", args))
|
|
}
|
|
}
|
|
cmd := exec.CommandContext(ctx, "/bin/sh", "-c")
|
|
cmd.Env = os.Environ()
|
|
return &Shell{
|
|
l: l,
|
|
cmd: cmd,
|
|
args: args,
|
|
Stdin: os.Stdin,
|
|
Stdout: os.Stdout,
|
|
Stderr: os.Stderr,
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Public methods
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func (s *Shell) Args(args ...string) *Shell {
|
|
s.args = append(s.args, args...)
|
|
return s
|
|
}
|
|
|
|
func (s *Shell) Env(env []string) *Shell {
|
|
s.cmd.Env = append(s.cmd.Env, env...)
|
|
return s
|
|
}
|
|
|
|
func (s *Shell) Dir(dir string) *Shell {
|
|
s.cmd.Dir = dir
|
|
return s
|
|
}
|
|
|
|
func (s *Shell) Quiet() *Shell {
|
|
s.quiet = true
|
|
return s
|
|
}
|
|
|
|
func (s *Shell) Run() error {
|
|
args := s.args
|
|
s.cmd.Args = append(s.cmd.Args, strings.Join(args, " "))
|
|
s.cmd.Stdin = s.Stdin
|
|
if !s.quiet {
|
|
s.cmd.Stdout = s.Stdout
|
|
s.cmd.Stderr = s.Stderr
|
|
}
|
|
s.debug()
|
|
return s.cmd.Run()
|
|
}
|
|
|
|
func (s *Shell) Output() ([]byte, error) {
|
|
args := s.args
|
|
s.cmd.Args = append(s.cmd.Args, strings.Join(args, " "))
|
|
if !s.quiet {
|
|
s.cmd.Stdin = s.Stdin
|
|
s.cmd.Stderr = s.Stderr
|
|
}
|
|
s.debug()
|
|
return s.cmd.Output()
|
|
}
|
|
|
|
// Wait ...
|
|
func (s *Shell) Wait() error {
|
|
args := s.args
|
|
s.cmd.Args = append(s.cmd.Args, strings.Join(args, " "))
|
|
s.cmd.Stdin = s.Stdin
|
|
if !s.quiet {
|
|
s.cmd.Stdout = s.Stdout
|
|
s.cmd.Stderr = s.Stderr
|
|
}
|
|
s.debug()
|
|
// start the process and wait till it's finished
|
|
if err := s.cmd.Start(); err != nil {
|
|
return err
|
|
} else if err := s.cmd.Wait(); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Private methods
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func (s *Shell) debug() {
|
|
s.l.Debugf(`"Executing:
|
|
$ %s
|
|
|
|
Directory: %s
|
|
|
|
%s
|
|
`,
|
|
s.cmd.String(),
|
|
s.cmd.Dir,
|
|
strings.Join(s.cmd.Environ(), "\n"),
|
|
)
|
|
}
|