From 92ba132d70fe1d9afabe3cf4f23376025ccff897 Mon Sep 17 00:00:00 2001 From: Robin Jarry Date: Fri, 30 Sep 2022 10:52:49 +0200 Subject: [PATCH] open: simplify code There is no need for convoluted channels and other async fanciness. Expose a single XDGOpen static function that runs a command and returns an error if any. Caller is responsible of running this in an async goroutine if needed. Signed-off-by: Robin Jarry Tested-by: Tim Culverhouse Acked-by: Moritz Poldrack --- commands/msg/unsubscribe.go | 8 +++-- commands/msgview/open.go | 26 ++++------------- lib/open.go | 58 ++++++------------------------------- 3 files changed, 19 insertions(+), 73 deletions(-) diff --git a/commands/msg/unsubscribe.go b/commands/msg/unsubscribe.go index 3982f7b..a9116e9 100644 --- a/commands/msg/unsubscribe.go +++ b/commands/msg/unsubscribe.go @@ -183,9 +183,11 @@ func unsubscribeHTTP(aerc *widgets.Aerc, u *url.URL) error { aerc.CloseDialog() switch option { case "Yes": - if err := lib.NewXDGOpen(u.String()).Start(); err != nil { - aerc.PushError("Unsubscribe:" + err.Error()) - } + go func() { + if err := lib.XDGOpen(u.String()); err != nil { + aerc.PushError("Unsubscribe:" + err.Error()) + } + }() default: aerc.PushError("Unsubscribe: link will not be opened") } diff --git a/commands/msgview/open.go b/commands/msgview/open.go index f3723fb..82c1acc 100644 --- a/commands/msgview/open.go +++ b/commands/msgview/open.go @@ -5,11 +5,9 @@ import ( "io" "mime" "os" - "time" "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib" - "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/widgets" ) @@ -40,8 +38,8 @@ func (Open) Execute(aerc *widgets.Aerc, args []string) error { if args[0] == "open-link" && len(args) > 1 { if link := args[1]; link != "" { go func() { - if err := lib.NewXDGOpen(link).Start(); err != nil { - aerc.PushError(fmt.Sprintf("%s: %s", args[0], err.Error())) + if err := lib.XDGOpen(link); err != nil { + aerc.PushError("open: " + err.Error()) } }() } @@ -64,34 +62,20 @@ func (Open) Execute(aerc *widgets.Aerc, args []string) error { aerc.PushError(err.Error()) return } - defer tmpFile.Close() _, err = io.Copy(tmpFile, reader) + tmpFile.Close() if err != nil { aerc.PushError(err.Error()) return } - xdg := lib.NewXDGOpen(tmpFile.Name()) - // pass through any arguments the user provided to the underlying handler - if len(args) > 1 { - xdg.SetArgs(args[1:]) - } - err = xdg.Start() - if err != nil { - aerc.PushError(err.Error()) - return - } go func() { - defer logging.PanicHandler() - - err := xdg.Wait() + err = lib.XDGOpen(tmpFile.Name()) if err != nil { - aerc.PushError(err.Error()) + aerc.PushError("open: " + err.Error()) } }() - - aerc.PushStatus("Opened", 10*time.Second) }) return nil diff --git a/lib/open.go b/lib/open.go index c29ed00..a189980 100644 --- a/lib/open.go +++ b/lib/open.go @@ -1,65 +1,25 @@ package lib import ( + "fmt" "os/exec" "runtime" "git.sr.ht/~rjarry/aerc/logging" ) -var openBin string = "xdg-open" - -func init() { +func XDGOpen(uri string) error { + openBin := "xdg-open" if runtime.GOOS == "darwin" { openBin = "open" } -} - -type xdgOpen struct { - args []string - errCh chan (error) - cmd *exec.Cmd -} - -// NewXDGOpen returns a handler for opening a file via the system handler xdg-open -// or comparable tools on other OSs than Linux -func NewXDGOpen(filename string) *xdgOpen { - errch := make(chan error, 1) - return &xdgOpen{ - errCh: errch, - args: []string{filename}, - } -} - -// SetArgs sets additional arguments to the open command prior to the filename -func (xdg *xdgOpen) SetArgs(args []string) { - args = append([]string{}, args...) // don't overwrite array of caller - filename := xdg.args[len(xdg.args)-1] - xdg.args = append(args, filename) //nolint:gocritic // intentional append to different slice -} - -// Start the open handler. -// Returns an error if the command could not be started. -// Use Wait to wait for the commands completion and to check the error. -func (xdg *xdgOpen) Start() error { - xdg.cmd = exec.Command(openBin, xdg.args...) - err := xdg.cmd.Start() + args := []string{openBin, uri} + logging.Infof("running command: %v", args) + cmd := exec.Command(args[0], args[1:]...) + out, err := cmd.CombinedOutput() + logging.Debugf("command: %v exited. err=%v out=%s", args, err, out) if err != nil { - xdg.errCh <- err // for callers that just check the error from Wait() - close(xdg.errCh) - return err + return fmt.Errorf("%v: %w", args, err) } - go func() { - defer logging.PanicHandler() - - xdg.errCh <- xdg.cmd.Wait() - close(xdg.errCh) - }() return nil } - -// Wait for the xdg-open command to complete -// The xdgOpen must have been started -func (xdg *xdgOpen) Wait() error { - return <-xdg.errCh -}