package executor
import (
"context"
"io"
"os/exec"
"time"
)
type LocalExecutor struct {
defaultTimeout time.Duration
}
func NewLocalExecutor(timeout time.Duration) *LocalExecutor {
return &LocalExecutor{
defaultTimeout: timeout,
}
}
func (l *LocalExecutor) Exec(cmd string, opts ...ExecOption) (*ExecResult, error) {
ctx, cancel := context.WithTimeout(context.Background(), l.defaultTimeout)
defer cancel()
c := exec.CommandContext(ctx, "bash", "-c", cmd)
stdout, _ := c.StdoutPipe()
stderr, _ := c.StderrPipe()
if err := c.Start(); err != nil {
return nil, err
}
outBytes, _ := io.ReadAll(stdout)
errBytes, _ := io.ReadAll(stderr)
err := c.Wait()
exitCode := 0
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
exitCode = exitErr.ExitCode()
}
}
return &ExecResult{
Command: cmd,
Stdout: string(outBytes),
Stderr: string(errBytes),
ExitCode: exitCode,
}, err
}