Files
task/execext/exec.go

73 lines
1.2 KiB
Go
Raw Normal View History

2017-03-12 17:18:59 -03:00
package execext
import (
"context"
"errors"
"io"
"strings"
"sync"
"mvdan.cc/sh/interp"
"mvdan.cc/sh/syntax"
2017-03-12 17:18:59 -03:00
)
var (
parserPool = sync.Pool{
New: func() interface{} {
return syntax.NewParser()
},
}
runnerPool = sync.Pool{
New: func() interface{} {
return &interp.Runner{}
},
}
)
2017-04-24 10:25:38 -03:00
// RunCommandOptions is the options for the RunCommand func
type RunCommandOptions struct {
Context context.Context
Command string
Dir string
Env []string
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
}
2017-03-12 17:18:59 -03:00
var (
// ErrNilOptions is returned when a nil options is given
ErrNilOptions = errors.New("execext: nil options given")
2017-03-12 17:18:59 -03:00
)
// RunCommand runs a shell command
func RunCommand(opts *RunCommandOptions) error {
if opts == nil {
return ErrNilOptions
}
parser := parserPool.Get().(*syntax.Parser)
defer parserPool.Put(parser)
p, err := parser.Parse(strings.NewReader(opts.Command), "")
if err != nil {
return err
}
2017-03-12 17:18:59 -03:00
r := runnerPool.Get().(*interp.Runner)
defer runnerPool.Put(r)
r.Context = opts.Context
r.Dir = opts.Dir
r.Env = opts.Env
r.Stdin = opts.Stdin
r.Stdout = opts.Stdout
r.Stderr = opts.Stderr
2017-08-05 14:20:44 -03:00
if err = r.Reset(); err != nil {
return err
}
return r.Run(p)
2017-03-12 17:18:59 -03:00
}