package exec import ( "fmt" "io" wasiv1 "code.icb4dc0.de/buildr/api/generated/wasi/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 := &wasiv1.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(wasiv1.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 }