diff options
author | Martin Polden <mpolden@mpolden.no> | 2021-09-10 18:26:55 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2021-09-10 18:26:55 +0200 |
commit | 438d1a57510f9756362f2a8e84f7e55ff6a9ff68 (patch) | |
tree | 36934e9258c23b7c8b1b13b78e01809cd3d913fd | |
parent | 48ada0316c9e79957d7ad2ccf5b87e274fa74c40 (diff) |
executil: Extract package
-rw-r--r-- | executil/executil.go | 49 | ||||
-rw-r--r-- | executil/executil_test.go | 44 | ||||
-rw-r--r-- | rar/rar.go | 42 | ||||
-rw-r--r-- | rar/rar_test.go | 38 |
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") + } +} @@ -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 |