feat
- implemented spellcaster
This commit is contained in:
1 parent
478ac2fc7b
commit
0e0a4d34ac
4 files changed
+70
No files matched your search
@@ -1 +1,5 @@
|
|||||||
module spellbook
|
module spellbook
|
||||||
|
|
||||||
|
go 1.26.0
|
||||||
|
|
||||||
|
require github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||||
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||||
@@ -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())
|
||||||
|
}
|
||||||
@@ -14,12 +14,14 @@ type Spell struct {
|
|||||||
type SpellCast struct {
|
type SpellCast struct {
|
||||||
Spell Spell
|
Spell Spell
|
||||||
Args map[string]string
|
Args map[string]string
|
||||||
|
Stdin io.Reader
|
||||||
Stdout io.Writer
|
Stdout io.Writer
|
||||||
Stderr io.Writer
|
Stderr io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
type CastResult struct {
|
type CastResult struct {
|
||||||
ExitCode int
|
ExitCode int
|
||||||
|
Err error
|
||||||
Duration time.Duration
|
Duration time.Duration
|
||||||
Meta map[string]any
|
Meta map[string]any
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user