aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2021-09-10 18:26:55 +0200
committerMartin Polden <mpolden@mpolden.no>2021-09-10 18:26:55 +0200
commit438d1a57510f9756362f2a8e84f7e55ff6a9ff68 (patch)
tree36934e9258c23b7c8b1b13b78e01809cd3d913fd
parent48ada0316c9e79957d7ad2ccf5b87e274fa74c40 (diff)
executil: Extract package
-rw-r--r--executil/executil.go49
-rw-r--r--executil/executil_test.go44
-rw-r--r--rar/rar.go42
-rw-r--r--rar/rar_test.go38
4 files changed, 96 insertions, 77 deletions
diff --git a/executil/executil.go b/executil/executil.go
new file mode 100644
index 0000000..0617910
--- /dev/null
+++ b/executil/executil.go
@@ -0,0 +1,49 @@
+package executil
+
+import (
+ "bytes"
+ "fmt"
+ "html/template"
+ "os/exec"
+ "strings"
+)
+
+type CommandData struct {
+ Base string
+ Dir string
+ Name string
+}
+
+func compileCommand(tmpl string, data CommandData) (*exec.Cmd, error) {
+ t, err := template.New("cmd").Parse(tmpl)
+ if err != nil {
+ return nil, err
+ }
+ var b bytes.Buffer
+ if err := t.Execute(&b, data); err != nil {
+ return nil, err
+ }
+ argv := strings.Split(b.String(), " ")
+ if len(argv) == 0 {
+ return nil, fmt.Errorf("template compiled to empty command")
+ }
+ cmd := exec.Command(argv[0], argv[1:]...)
+ cmd.Dir = data.Dir
+ return cmd, nil
+}
+
+func Run(command string, data CommandData) error {
+ if command == "" {
+ return nil
+ }
+ cmd, err := compileCommand(command, data)
+ if err != nil {
+ return err
+ }
+ var stderr bytes.Buffer
+ cmd.Stderr = &stderr
+ if err := cmd.Run(); err != nil {
+ return fmt.Errorf("stderr: %q: %w", stderr.String(), err)
+ }
+ return nil
+}
diff --git a/executil/executil_test.go b/executil/executil_test.go
new file mode 100644
index 0000000..f2633ab
--- /dev/null
+++ b/executil/executil_test.go
@@ -0,0 +1,44 @@
+package executil
+
+import (
+ "os"
+ "strings"
+ "testing"
+)
+
+func TestCompileCommand(t *testing.T) {
+ tmpl := "tar -xf {{.Name}} {{.Base}} {{.Dir}}"
+ data := CommandData{
+ Name: "/foo/bar/baz.rar",
+ Base: "baz.rar",
+ Dir: "/foo/bar",
+ }
+ cmd, err := compileCommand(tmpl, data)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if cmd.Dir != data.Dir {
+ t.Fatalf("want %q, got %q", data.Dir, cmd.Dir)
+ }
+ if !strings.Contains(cmd.Path, string(os.PathSeparator)) {
+ t.Fatalf("want %q to contain a path separator", cmd.Path)
+ }
+ if cmd.Args[0] != "tar" {
+ t.Fatalf("want %q, got %q", "tar", cmd.Args[0])
+ }
+ if cmd.Args[1] != "-xf" {
+ t.Fatalf("want %q, got %q", "-xf", cmd.Args[1])
+ }
+ if cmd.Args[2] != data.Name {
+ t.Fatalf("want %q, got %q", data.Name, cmd.Args[2])
+ }
+ if cmd.Args[3] != data.Base {
+ t.Fatalf("want %q, got %q", data.Base, cmd.Args[3])
+ }
+ if cmd.Args[4] != data.Dir {
+ t.Fatalf("want %q, got %q", data.Base, cmd.Args[4])
+ }
+ if _, err := compileCommand("tar -xf {{.Bar}}", data); err == nil {
+ t.Fatal("want error")
+ }
+}
diff --git a/rar/rar.go b/rar/rar.go
index 89b7a92..7576214 100644
--- a/rar/rar.go
+++ b/rar/rar.go
@@ -1,18 +1,15 @@
package rar
import (
- "bytes"
"fmt"
"io"
"os"
- "os/exec"
"path/filepath"
"regexp"
- "strings"
"sync"
- "text/template"
"github.com/mpolden/sfv"
+ "github.com/mpolden/unp/executil"
"github.com/nwaples/rardecode"
)
@@ -142,40 +139,6 @@ func (h *Handler) remove(sfv *sfv.SFV) error {
return os.Remove(sfv.Path)
}
-func cmdFrom(tmpl string, ev event) (*exec.Cmd, error) {
- t, err := template.New("cmd").Parse(tmpl)
- if err != nil {
- return nil, err
- }
- var b bytes.Buffer
- if err := t.Execute(&b, ev); err != nil {
- return nil, err
- }
- argv := strings.Split(b.String(), " ")
- if len(argv) == 0 {
- return nil, fmt.Errorf("template compiled to empty command")
- }
- cmd := exec.Command(argv[0], argv[1:]...)
- cmd.Dir = ev.Dir
- return cmd, nil
-}
-
-func runCmd(command string, e event) error {
- if command == "" {
- return nil
- }
- cmd, err := cmdFrom(command, e)
- if err != nil {
- return err
- }
- var stderr bytes.Buffer
- cmd.Stderr = &stderr
- if err := cmd.Run(); err != nil {
- return fmt.Errorf("stderr: %q: %w", stderr.String(), err)
- }
- return nil
-}
-
func NewHandler() *Handler { return &Handler{cache: make(map[string]bool)} }
func (h *Handler) verify(sfv *sfv.SFV) (int, int, error) {
@@ -219,7 +182,8 @@ func (h *Handler) Handle(name, postCommand string, removeRARs bool) error {
return fmt.Errorf("removal failed: %s: %w", ev.Dir, err)
}
}
- if err := runCmd(postCommand, ev); err != nil {
+ cd := executil.CommandData{Base: ev.Base, Dir: ev.Dir, Name: ev.Name}
+ if err := executil.Run(postCommand, cd); err != nil {
return fmt.Errorf("post-process command failed: %s: %w", ev.Dir, err)
}
return nil
diff --git a/rar/rar_test.go b/rar/rar_test.go
index d273f27..95642b5 100644
--- a/rar/rar_test.go
+++ b/rar/rar_test.go
@@ -4,7 +4,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
- "strings"
"testing"
"time"
@@ -25,43 +24,6 @@ func testDir(t *testing.T) string {
return filepath.Join(wd, "testdata")
}
-func TestCmdFrom(t *testing.T) {
- tmpl := "tar -xf {{.Name}} {{.Base}} {{.Dir}}"
- values := event{
- Name: "/foo/bar/baz.rar",
- Base: "baz.rar",
- Dir: "/foo/bar",
- }
- cmd, err := cmdFrom(tmpl, values)
- if err != nil {
- t.Fatal(err)
- }
- if cmd.Dir != values.Dir {
- t.Fatalf("want %q, got %q", values.Dir, cmd.Dir)
- }
- if !strings.Contains(cmd.Path, string(os.PathSeparator)) {
- t.Fatalf("want %q to contain a path separator", cmd.Path)
- }
- if cmd.Args[0] != "tar" {
- t.Fatalf("want %q, got %q", "tar", cmd.Args[0])
- }
- if cmd.Args[1] != "-xf" {
- t.Fatalf("want %q, got %q", "-xf", cmd.Args[1])
- }
- if cmd.Args[2] != values.Name {
- t.Fatalf("want %q, got %q", values.Name, cmd.Args[2])
- }
- if cmd.Args[3] != values.Base {
- t.Fatalf("want %q, got %q", values.Base, cmd.Args[3])
- }
- if cmd.Args[4] != values.Dir {
- t.Fatalf("want %q, got %q", values.Base, cmd.Args[4])
- }
- if _, err := cmdFrom("tar -xf {{.Bar}}", values); err == nil {
- t.Fatal("want error")
- }
-}
-
func TestFindFirstRAR(t *testing.T) {
var tests = []struct {
sfv *sfv.SFV