diff options
| author | Xe Iaso <me@xeiaso.net> | 2024-11-26 11:02:10 -0500 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2024-11-26 11:02:10 -0500 |
| commit | 27eb123f7a4e3d1c94d297fb8706328a58a26acc (patch) | |
| tree | 4d7fdae87bd76cbe862fa77bc9f2867ff9af746d /internal | |
| parent | cdba95496fd16baca8b6bcd7bb03302b73813dc1 (diff) | |
| download | x-27eb123f7a4e3d1c94d297fb8706328a58a26acc.tar.xz x-27eb123f7a4e3d1c94d297fb8706328a58a26acc.zip | |
internal: add a crime
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/runjson.go | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/internal/runjson.go b/internal/runjson.go new file mode 100644 index 0000000..54fb6eb --- /dev/null +++ b/internal/runjson.go @@ -0,0 +1,45 @@ +package internal + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "os" + "os/exec" +) + +// Zilch returns the zero value of a given type. +func Zilch[T any]() T { return *new(T) } + +func RunJSON[T any](ctx context.Context, program string, args ...any) (T, error) { + exePath, err := exec.LookPath(program) + if err != nil { + return Zilch[T](), fmt.Errorf("can't find %s: %w", program, err) + } + + var argStr []string + + for _, arg := range args { + argStr = append(argStr, fmt.Sprint(arg)) + } + + var stdout bytes.Buffer + var stderr bytes.Buffer + + cmd := exec.CommandContext(ctx, exePath, argStr...) + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + if err := cmd.Run(); err != nil { + os.Stderr.Write(stderr.Bytes()) + return Zilch[T](), fmt.Errorf("can't run %s: %w", program, err) + } + + var result T + if err := json.NewDecoder(&stdout).Decode(&result); err != nil { + return Zilch[T](), fmt.Errorf("can't decode json: %w", err) + } + + return result, nil +} |
