From c443bcf7897b76fa21f360677baf483eff0059f5 Mon Sep 17 00:00:00 2001 From: Matt Landis Date: Fri, 16 Apr 2021 16:33:19 -0400 Subject: [PATCH] Add functional options to allow configuring the underlying Cmd --- browser.go | 22 +++++++++++++++------- browser_darwin.go | 4 ++-- browser_freebsd.go | 4 ++-- browser_linux.go | 4 ++-- browser_openbsd.go | 4 ++-- browser_unsupported.go | 2 +- browser_windows.go | 2 +- example_test.go | 17 ++++++++++++++++- go.mod | 2 ++ go.sum | 2 ++ 10 files changed, 45 insertions(+), 18 deletions(-) create mode 100644 go.sum diff --git a/browser.go b/browser.go index 3e59690..d5d8fcc 100644 --- a/browser.go +++ b/browser.go @@ -18,18 +18,22 @@ var Stdout io.Writer = os.Stdout // Stderr is the io.Writer to which executed commands write standard error. var Stderr io.Writer = os.Stderr +type CmdOption func (*exec.Cmd) + // OpenFile opens new browser window for the file path. -func OpenFile(path string) error { +// options can be used to configure the underlying exec.Cmd, if any +func OpenFile(path string, options ...CmdOption) error { path, err := filepath.Abs(path) if err != nil { return err } - return OpenURL("file://" + path) + return OpenURL("file://" + path, options...) } // OpenReader consumes the contents of r and presents the // results in a new browser window. -func OpenReader(r io.Reader) error { +// options can be used to configure the underlying exec.Cmd, if any +func OpenReader(r io.Reader, options ...CmdOption) error { f, err := ioutil.TempFile("", "browser") if err != nil { return fmt.Errorf("browser: could not create temporary file: %v", err) @@ -46,18 +50,22 @@ func OpenReader(r io.Reader) error { if err := os.Rename(oldname, newname); err != nil { return fmt.Errorf("browser: renaming temporary file failed: %v", err) } - return OpenFile(newname) + return OpenFile(newname, options...) } // OpenURL opens a new browser window pointing to url. -func OpenURL(url string) error { - return openBrowser(url) +// options can be used to configure the underlying exec.Cmd, if any +func OpenURL(url string, options ...CmdOption) error { + return openBrowser(url, options) } -func runCmd(prog string, args ...string) error { +func runCmd(prog string, args []string, options []CmdOption) error { cmd := exec.Command(prog, args...) cmd.Stdout = Stdout cmd.Stderr = Stderr setFlags(cmd) + for _, o := range options { + o(cmd) + } return cmd.Run() } diff --git a/browser_darwin.go b/browser_darwin.go index 6dff040..9fe6e68 100644 --- a/browser_darwin.go +++ b/browser_darwin.go @@ -2,8 +2,8 @@ package browser import "os/exec" -func openBrowser(url string) error { - return runCmd("open", url) +func openBrowser(url string, cmdOptions []CmdOption) error { + return runCmd("open", []string{url}, cmdOptions) } func setFlags(cmd *exec.Cmd) {} diff --git a/browser_freebsd.go b/browser_freebsd.go index 8cc0a7f..0063794 100644 --- a/browser_freebsd.go +++ b/browser_freebsd.go @@ -5,8 +5,8 @@ import ( "os/exec" ) -func openBrowser(url string) error { - err := runCmd("xdg-open", url) +func openBrowser(url string, cmdOptions []CmdOption) error { + err := runCmd("xdg-open", []string{url}, cmdOptions) if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound { return errors.New("xdg-open: command not found - install xdg-utils from ports(8)") } diff --git a/browser_linux.go b/browser_linux.go index ab9b4f6..b972535 100644 --- a/browser_linux.go +++ b/browser_linux.go @@ -5,7 +5,7 @@ import ( "strings" ) -func openBrowser(url string) error { +func openBrowser(url string, cmdOptions []CmdOption) error { providers := []string{"xdg-open", "x-www-browser", "www-browser"} // There are multiple possible providers to open a browser on linux @@ -13,7 +13,7 @@ func openBrowser(url string) error { // Look for one that exists and run it for _, provider := range providers { if _, err := exec.LookPath(provider); err == nil { - return runCmd(provider, url) + return runCmd(provider, []string{url}, cmdOptions) } } diff --git a/browser_openbsd.go b/browser_openbsd.go index 8cc0a7f..0063794 100644 --- a/browser_openbsd.go +++ b/browser_openbsd.go @@ -5,8 +5,8 @@ import ( "os/exec" ) -func openBrowser(url string) error { - err := runCmd("xdg-open", url) +func openBrowser(url string, cmdOptions []CmdOption) error { + err := runCmd("xdg-open", []string{url}, cmdOptions) if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound { return errors.New("xdg-open: command not found - install xdg-utils from ports(8)") } diff --git a/browser_unsupported.go b/browser_unsupported.go index 5eb17b0..1766c74 100644 --- a/browser_unsupported.go +++ b/browser_unsupported.go @@ -8,7 +8,7 @@ import ( "runtime" ) -func openBrowser(url string) error { +func openBrowser(url string, cmdOptions []CmdOption) error { return fmt.Errorf("openBrowser: unsupported operating system: %v", runtime.GOOS) } diff --git a/browser_windows.go b/browser_windows.go index a2b30d3..b028af1 100644 --- a/browser_windows.go +++ b/browser_windows.go @@ -5,7 +5,7 @@ package browser import "os/exec" const SW_SHOWNORMAL = 1 -func openBrowser(url string) error { +func openBrowser(url string, cmdOptions []CmdOption) error { return ShellExecute(0, "", url, "", "", SW_SHOWNORMAL) } diff --git a/example_test.go b/example_test.go index a6fbe16..ed07cc1 100644 --- a/example_test.go +++ b/example_test.go @@ -1,6 +1,11 @@ package browser -import "strings" +import ( + "bytes" + "fmt" + "os/exec" + "strings" +) func ExampleOpenFile() { OpenFile("index.html") @@ -21,3 +26,13 @@ func ExampleOpenURL() { const url = "http://golang.org/" OpenURL(url) } + +func ExampleOpenURLWithOptions() { + out := &bytes.Buffer{} + const url = "http://golang.org/" + OpenURL(url, func(cmd *exec.Cmd) { + cmd.Stdout = out + cmd.Stderr = out + }) + fmt.Printf("browser open output: %q\n", out.String()) +} diff --git a/go.mod b/go.mod index 04355d2..cd17fda 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/pkg/browser go 1.14 + +require golang.org/x/sys v0.0.0-20210415045647-66c3f260301c diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..0c07c25 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.0.0-20210415045647-66c3f260301c h1:6L+uOeS3OQt/f4eFHXZcTxeZrGCuz+CLElgEBjbcTA4= +golang.org/x/sys v0.0.0-20210415045647-66c3f260301c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=