add support for streaming to cmd stdin
Some checks are pending
Lint / golangci-lint (push) Waiting to run
Declarative Tests / test (push) Waiting to run
Declarative Tests / build-fedora (push) Waiting to run
Declarative Tests / build-ubuntu-focal (push) Waiting to run

This commit is contained in:
Matthew Rich 2024-09-19 05:32:22 +00:00
parent 2288f4edd0
commit a38bd8a4d7
2 changed files with 45 additions and 3 deletions

View File

@ -32,9 +32,11 @@ type Command struct {
Env []string `json:"env" yaml:"env"`
Split bool `json:"split" yaml:"split"`
FailOnError bool `json:"failonerror" yaml:"failonerror"`
StdinAvailable bool `json:"stdinavailable,omitempty" yaml:"stdinavailable,omitempty"`
Executor CommandExecutor `json:"-" yaml:"-"`
Extractor CommandExtractAttributes `json:"-" yaml:"-"`
CommandExists CommandExists `json:"-" yaml:"-"`
stdin io.Reader `json:"-" yaml:"-"`
}
func NewCommand() *Command {
@ -59,6 +61,10 @@ func (c *Command) Defaults() {
}
cmd := exec.Command(c.Path, args...)
c.SetCmdEnv(cmd)
if c.stdin != nil {
cmd.Stdin = c.stdin
}
slog.Info("execute() - cmd", "path", c.Path, "args", args)
output, stdoutPipeErr := cmd.StdoutPipe()
@ -78,11 +84,18 @@ func (c *Command) Defaults() {
slog.Info("execute() - start", "cmd", cmd)
stdOutOutput, _ := io.ReadAll(output)
stdErrOutput, _ := io.ReadAll(stderr)
slog.Info("execute() - io", "stdout", string(stdOutOutput), "stderr", string(stdErrOutput))
if len(stdOutOutput) > 100 {
slog.Info("execute() - io", "stdout", string(stdOutOutput[:100]), "stderr", string(stdErrOutput))
} else {
slog.Info("execute() - io", "stdout", string(stdOutOutput), "stderr", string(stdErrOutput))
}
waitErr := cmd.Wait()
slog.Info("execute()", "path", c.Path, "args", args, "output", string(stdOutOutput), "error", string(stdErrOutput))
if len(stdOutOutput) > 100 {
slog.Info("execute()", "path", c.Path, "args", args, "output", string(stdOutOutput[:100]), "error", string(stdErrOutput))
} else {
slog.Info("execute()", "path", c.Path, "args", args, "output", string(stdOutOutput), "error", string(stdErrOutput))
}
if len(stdErrOutput) > 0 && c.FailOnError {
return stdOutOutput, fmt.Errorf("%w %s", waitErr, string(stdErrOutput))
@ -103,6 +116,12 @@ func (c *Command) SetCmdEnv(cmd *exec.Cmd) {
cmd.Env = append(os.Environ(), c.Env...)
}
func (c *Command) SetStdinReader(r io.Reader) {
if c.StdinAvailable {
c.stdin = r
}
}
func (c *Command) Exists() bool {
return c.CommandExists() == nil
}

View File

@ -9,6 +9,7 @@ _ "fmt"
_ "os"
_ "strings"
"testing"
"bytes"
)
func TestNewCommand(t *testing.T) {
@ -58,3 +59,25 @@ args:
assert.Nil(t, err)
assert.Greater(t, len(out), 0)
}
func TestCommandStdin(t *testing.T) {
var expected string = "stdin test data"
var stdinBuffer bytes.Buffer
stdinBuffer.WriteString(expected)
c := NewCommand()
assert.NotNil(t, c)
decl := `
path: cat
stdinavailable: true
`
assert.Nil(t, c.LoadDecl(decl))
assert.Equal(t, "cat", c.Path)
c.SetStdinReader(&stdinBuffer)
out, err := c.Execute(nil)
assert.Nil(t, err)
assert.Equal(t, expected, string(out))
}