aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'internal/executor/executor.go')
-rw-r--r--internal/executor/executor.go101+27 −74
1 files changed, 27 insertions, 74 deletions
diff --git a/internal/executor/executor.go b/internal/executor/executor.go
index 7ce8770..d0e749f 100644
--- a/internal/executor/executor.go
+++ b/internal/executor/executor.go
@@ -1,15 +1,14 @@
// Copyright (c) 2026 Nikolay Govorov
// SPDX-License-Identifier: AGPL-3.0-or-later
+// Runtime executing the Starlark pipeline in one of the supported runtimes
package executor
import (
"bytes"
+ "context"
"fmt"
"log/slog"
- "os"
- "os/exec"
- "path/filepath"
"go.starlark.net/starlark"
"go.starlark.net/syntax"
@@ -17,85 +16,39 @@ import (
const entry = ".mirum/project.star"
-func RunCmd(dir, name string, args ...string) (string, error) {
- cmd := exec.Command(name, args...)
- cmd.Dir = dir
-
- var buf bytes.Buffer
- cmd.Stdout = &buf
- cmd.Stderr = &buf
-
- err := cmd.Run()
- return buf.String(), err
-}
-
-type SOTaskCtx struct {
- dir string
-}
-
-var _ starlark.HasAttrs = (*SOTaskCtx)(nil)
-
-func (c *SOTaskCtx) String() string { return "ctx" }
-func (c *SOTaskCtx) Type() string { return "ctx" }
-func (c *SOTaskCtx) Freeze() {}
-func (c *SOTaskCtx) Truth() starlark.Bool { return true }
-func (c *SOTaskCtx) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: ctx") }
-func (c *SOTaskCtx) AttrNames() []string { return []string{"shell"} }
-
-func (c *SOTaskCtx) Attr(name string) (starlark.Value, error) {
- switch name {
- case "shell":
- return starlark.NewBuiltin("ctx.shell", c.shell), nil
- }
- return nil, nil
-}
-
-func (c *SOTaskCtx) shell(
- thread *starlark.Thread,
- fn *starlark.Builtin,
- args starlark.Tuple,
- kwargs []starlark.Tuple,
-) (starlark.Value, error) {
- var cmd string
- if err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &cmd); err != nil {
- return nil, err
- }
-
- proc := exec.Command("bash", "-c", cmd)
- proc.Dir = c.dir
- proc.Stdout = os.Stdout
- proc.Stderr = os.Stderr
- err := proc.Run()
+// Run selects a Runtime, clones the repository into it, runs the Starlark
+// build script, and discards the Runtime afterwards.
+func Run(ctx context.Context, cloneURL, branch string) error {
+ rt, err := NewRuntime()
if err != nil {
- return nil, err
- }
-
- return starlark.None, nil
-}
-
-// Run clones the repository into a temporary directory, runs the Starlark
-// build script, and cleans up afterwards.
-func Run(cloneURL, branch string) error {
- dir, err := os.MkdirTemp("", "mirum-*")
- if err != nil {
- return fmt.Errorf("create workdir: %w", err)
+ return fmt.Errorf("create runtime: %w", err)
}
defer func() {
- if err := os.RemoveAll(dir); err != nil {
- slog.Warn("executor: cleanup failed", "dir", dir, "err", err)
+ if err := rt.Close(); err != nil {
+ slog.Warn("executor: runtime cleanup failed", "err", err)
}
}()
- if out, err := RunCmd(dir, "git", "clone", "--depth=1", "--branch", branch, cloneURL, "."); err != nil {
- return fmt.Errorf("git clone: %s: %w", out, err)
+ var clone bytes.Buffer
+ res, err := rt.Exec(ctx, Command{
+ Args: []string{"git", "clone", "--depth=1", "--branch", branch, cloneURL, "."},
+ Stdout: &clone,
+ Stderr: &clone,
+ })
+ if err != nil {
+ return fmt.Errorf("git clone: %w", err)
+ }
+ if res.Code != 0 {
+ return fmt.Errorf("git clone exited with code %d: %s", res.Code, clone.String())
}
- return runStarlark(dir)
-}
+ var script bytes.Buffer
+ if err := rt.FileRecv(ctx, entry, &script); err != nil {
+ return fmt.Errorf("read %s: %w", entry, err)
+ }
-func runStarlark(dir string) error {
thread := &starlark.Thread{Name: "mirum"}
- globals, err := starlark.ExecFileOptions(&syntax.FileOptions{}, thread, filepath.Join(dir, entry), nil, nil)
+ globals, err := starlark.ExecFileOptions(&syntax.FileOptions{}, thread, entry, script.Bytes(), nil)
if err != nil {
return err
}
@@ -109,7 +62,7 @@ func runStarlark(dir string) error {
return fmt.Errorf("%s: project is not a function", entry)
}
- ctx := &SOTaskCtx{dir: dir}
- _, err = starlark.Call(thread, fn, starlark.Tuple{ctx}, nil)
+ tctx := &SOTaskCtx{ctx: ctx, rt: rt}
+ _, err = starlark.Call(thread, fn, starlark.Tuple{tctx}, nil)
return err
}