aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorXe Iaso <me@xeiaso.net>2024-11-26 11:02:10 -0500
committerXe Iaso <me@xeiaso.net>2024-11-26 11:02:10 -0500
commit27eb123f7a4e3d1c94d297fb8706328a58a26acc (patch)
tree4d7fdae87bd76cbe862fa77bc9f2867ff9af746d /internal
parentcdba95496fd16baca8b6bcd7bb03302b73813dc1 (diff)
downloadx-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.go45
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
+}