blob: 728fe3f2f78f84846317ca431c7c7dc10cfcc992 [file] [log] [blame]
Josh Bleecher Snyder78707d62025-04-30 21:06:49 +00001// Package browser provides functions for opening URLs in a web browser.
2package browser
3
4import (
Josh Bleecher Snyderd0a3cd62025-05-03 15:46:45 -07005 "log/slog"
Philip Zeyligercecba062025-06-06 18:40:16 +00006 "os"
Josh Bleecher Snyder78707d62025-04-30 21:06:49 +00007 "os/exec"
8 "runtime"
Josh Bleecher Snyder11c97f22025-05-02 16:36:46 -07009 "strings"
Josh Bleecher Snyder78707d62025-04-30 21:06:49 +000010)
11
12// Open opens the specified URL in the system's default browser.
13// It detects the OS and uses the appropriate command:
Philip Zeyligercecba062025-06-06 18:40:16 +000014// - 'open' for macOS (with optional -a flag if SKETCH_BROWSER is set)
15// - 'cmd /c start' for Windows (or direct browser executable if SKETCH_BROWSER is set)
16// - 'xdg-open' for Linux and other Unix-like systems (or direct browser executable if SKETCH_BROWSER is set)
17//
18// If SKETCH_BROWSER environment variable is set, it will be used as the browser application:
19// - On macOS: passed to 'open -a'
20// - On Windows/Linux: used as direct executable
Josh Bleecher Snydere54b00a2025-04-30 16:48:02 -070021func Open(url string) {
Josh Bleecher Snyder11c97f22025-05-02 16:36:46 -070022 if strings.TrimSpace(url) == "" {
23 return
24 }
Philip Zeyligercecba062025-06-06 18:40:16 +000025
26 browser := os.Getenv("SKETCH_BROWSER")
Josh Bleecher Snyder78707d62025-04-30 21:06:49 +000027 var cmd *exec.Cmd
Philip Zeyligercecba062025-06-06 18:40:16 +000028
Josh Bleecher Snyder78707d62025-04-30 21:06:49 +000029 switch runtime.GOOS {
30 case "darwin":
Philip Zeyligercecba062025-06-06 18:40:16 +000031 if browser != "" {
32 cmd = exec.Command("open", "-a", browser, url)
33 } else {
34 cmd = exec.Command("open", url)
35 }
Josh Bleecher Snyder78707d62025-04-30 21:06:49 +000036 case "windows":
Philip Zeyligercecba062025-06-06 18:40:16 +000037 if browser != "" {
38 cmd = exec.Command(browser, url)
39 } else {
40 cmd = exec.Command("cmd", "/c", "start", url)
41 }
Josh Bleecher Snyder78707d62025-04-30 21:06:49 +000042 default: // Linux and other Unix-like systems
Philip Zeyligercecba062025-06-06 18:40:16 +000043 if browser != "" {
44 cmd = exec.Command(browser, url)
45 } else {
46 cmd = exec.Command("xdg-open", url)
47 }
Josh Bleecher Snyder78707d62025-04-30 21:06:49 +000048 }
Philip Zeyligercecba062025-06-06 18:40:16 +000049
Josh Bleecher Snyder78707d62025-04-30 21:06:49 +000050 if b, err := cmd.CombinedOutput(); err != nil {
Philip Zeyligercecba062025-06-06 18:40:16 +000051 slog.Debug("failed to open browser", "err", err, "url", url, "output", string(b), "browser", browser)
Josh Bleecher Snyder78707d62025-04-30 21:06:49 +000052 }
53}