- implemented spellcaster
This commit is contained in:
abelith committed 2026-08-03 05:09:16 +05:00
1 parent 478ac2fc7b
commit 0e0a4d34ac
4 files changed
+70

No files matched your search

+62
View File
@@ -0,0 +1,62 @@
package caster
import (
"bytes"
"context"
"errors"
"fmt"
"github.com/google/shlex"
"os/exec"
"spellbook/internal/models"
"text/template"
"time"
)
type SpellCaster struct{}
func (sc *SpellCaster) Cast(ctx context.Context, cast models.SpellCast) (models.CastResult, error) {
args, err := renderSpell(cast)
if err != nil {
return models.CastResult{}, err
}
cmd := exec.CommandContext(ctx, args[0], args[1:]...)
cmd.Stdin = cast.Stdin
cmd.Stdout = cast.Stdout
cmd.Stderr = cast.Stderr
start := time.Now()
err = cmd.Run()
duration := time.Since(start)
res := models.CastResult{
Duration: duration,
}
if err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
res.ExitCode = exitErr.ExitCode()
res.Err = err
return res, nil
}
return res, fmt.Errorf("failed to cast spell: %w", err)
}
res.ExitCode = 0
return res, nil
}
func renderSpell(cast models.SpellCast) ([]string, error) {
tmpl, err := template.New(cast.Spell.Name).Option("missingkey=error").Parse(cast.Spell.Spell)
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(nil)
if err := tmpl.Execute(buf, cast.Args); err != nil {
return nil, err
}
return shlex.Split(buf.String())
}
+2
View File
@@ -14,12 +14,14 @@ type Spell struct {
type SpellCast struct {
Spell Spell
Args map[string]string
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
}
type CastResult struct {
ExitCode int
Err error
Duration time.Duration
Meta map[string]any
}