From a38bd8a4d73e0e35de7c32382128da18a0b2ff10 Mon Sep 17 00:00:00 2001 From: Matthew Rich Date: Thu, 19 Sep 2024 05:32:22 +0000 Subject: [PATCH] add support for streaming to cmd stdin --- internal/command/command.go | 25 ++++++++++++++++++++++--- internal/command/command_test.go | 23 +++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/internal/command/command.go b/internal/command/command.go index 0f98e78..d6d0ed5 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -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 } diff --git a/internal/command/command_test.go b/internal/command/command_test.go index 6fb43c9..73b7925 100644 --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -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)) +}