diff --git a/libs/exec/exec.go b/libs/exec/exec.go index 9767c199..8e463327 100644 --- a/libs/exec/exec.go +++ b/libs/exec/exec.go @@ -90,18 +90,25 @@ func NewCommandExecutorWithExecutable(dir string, execType ExecutableType) (*Exe }, nil } -func (e *Executor) StartCommand(ctx context.Context, command string) (Command, error) { +func (e *Executor) prepareCommand(ctx context.Context, command string) (*osexec.Cmd, *execContext, error) { ec, err := e.shell.prepare(command) + if err != nil { + return nil, nil, err + } + cmd := osexec.CommandContext(ctx, ec.executable, ec.args...) + cmd.Dir = e.dir + return cmd, ec, nil +} + +func (e *Executor) StartCommand(ctx context.Context, command string) (Command, error) { + cmd, ec, err := e.prepareCommand(ctx, command) if err != nil { return nil, err } - return e.start(ctx, ec) + return e.start(ctx, cmd, ec) } -func (e *Executor) start(ctx context.Context, ec *execContext) (Command, error) { - cmd := osexec.CommandContext(ctx, ec.executable, ec.args...) - cmd.Dir = e.dir - +func (e *Executor) start(ctx context.Context, cmd *osexec.Cmd, ec *execContext) (Command, error) { stdout, err := cmd.StdoutPipe() if err != nil { return nil, err @@ -116,17 +123,12 @@ func (e *Executor) start(ctx context.Context, ec *execContext) (Command, error) } func (e *Executor) Exec(ctx context.Context, command string) ([]byte, error) { - cmd, err := e.StartCommand(ctx, command) + cmd, ec, err := e.prepareCommand(ctx, command) if err != nil { return nil, err } - - res, err := io.ReadAll(io.MultiReader(cmd.Stdout(), cmd.Stderr())) - if err != nil { - return nil, err - } - - return res, cmd.Wait() + defer os.Remove(ec.scriptFile) + return cmd.CombinedOutput() } func (e *Executor) ShellType() ExecutableType { diff --git a/libs/exec/exec_test.go b/libs/exec/exec_test.go index 0730638e..ad54601d 100644 --- a/libs/exec/exec_test.go +++ b/libs/exec/exec_test.go @@ -32,6 +32,15 @@ func TestExecutorWithComplexInput(t *testing.T) { assert.Equal(t, "Hello\nWorld\n", string(out)) } +func TestExecutorWithStderr(t *testing.T) { + executor, err := NewCommandExecutor(".") + assert.NoError(t, err) + out, err := executor.Exec(context.Background(), "echo 'Hello' && >&2 echo 'Error'") + assert.NoError(t, err) + assert.NotNil(t, out) + assert.Equal(t, "Hello\nError\n", string(out)) +} + func TestExecutorWithInvalidCommand(t *testing.T) { executor, err := NewCommandExecutor(".") assert.NoError(t, err) @@ -108,16 +117,16 @@ func TestExecutorCleanupsTempFiles(t *testing.T) { executor, err := NewCommandExecutor(".") assert.NoError(t, err) - ec, err := executor.shell.prepare("echo 'Hello'") + cmd, ec, err := executor.prepareCommand(context.Background(), "echo 'Hello'") assert.NoError(t, err) - cmd, err := executor.start(context.Background(), ec) + command, err := executor.start(context.Background(), cmd, ec) assert.NoError(t, err) fileName := ec.args[1] assert.FileExists(t, fileName) - err = cmd.Wait() + err = command.Wait() assert.NoError(t, err) assert.NoFileExists(t, fileName) }