87 lines
1.5 KiB
Go
87 lines
1.5 KiB
Go
package exec
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
|
|
rpcv1 "code.icb4dc0.de/buildr/api/generated/rpc/v1"
|
|
"code.icb4dc0.de/buildr/wasi-module-sdk-go/mem"
|
|
)
|
|
|
|
func NewCommand(name string, args ...string) *Command {
|
|
return &Command{
|
|
Name: name,
|
|
Args: args,
|
|
}
|
|
}
|
|
|
|
type Command struct {
|
|
Name string
|
|
Args []string
|
|
WorkingDir string
|
|
Env map[string]string
|
|
StdIn io.Reader
|
|
}
|
|
|
|
func (c *Command) AddEnv(envToAdd map[string]string) {
|
|
if envToAdd == nil {
|
|
return
|
|
}
|
|
|
|
if c.Env == nil {
|
|
c.Env = make(map[string]string)
|
|
}
|
|
|
|
for k, v := range envToAdd {
|
|
c.Env[k] = v
|
|
}
|
|
}
|
|
|
|
func (c *Command) Run() error {
|
|
execReq := &rpcv1.ProcessStartRequest{
|
|
Command: c.Name,
|
|
Args: c.Args,
|
|
WorkingDirectory: c.WorkingDir,
|
|
Environment: c.Env,
|
|
}
|
|
|
|
if c.StdIn != nil {
|
|
if stdInData, err := io.ReadAll(c.StdIn); err != nil {
|
|
return err
|
|
} else {
|
|
execReq.Stdin = stdInData
|
|
}
|
|
}
|
|
|
|
data, err := execReq.MarshalVT()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
result := _exec(mem.DataToManagedPtr(data))
|
|
if result == 0 {
|
|
return fmt.Errorf("failed to execute command: %s", c.Name)
|
|
}
|
|
|
|
resultPtr := uint32(result >> 32)
|
|
resultSize := uint32(result)
|
|
|
|
if resultSize == 0 {
|
|
return nil
|
|
}
|
|
|
|
execResp := new(rpcv1.ProcessStartResponse)
|
|
if err := execResp.UnmarshalVT(mem.PtrToData(resultPtr, resultSize)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if execResp.ExitCode != 0 {
|
|
return &Error{
|
|
ExitCode: int(execResp.ExitCode),
|
|
Message: execResp.Error,
|
|
StdErr: execResp.Stderr,
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|