github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/osx/wait.go (about) 1 package osx 2 3 import ( 4 "context" 5 "os" 6 "os/exec" 7 "runtime" 8 "time" 9 ) 10 11 // OpenBrowser go/src/cmd/internal/browser/browser.go 12 func OpenBrowser(url string) bool { 13 var cmds [][]string 14 if exe := os.Getenv("BROWSER"); exe != "" { 15 cmds = append(cmds, []string{exe}) 16 } 17 switch runtime.GOOS { 18 case "darwin": 19 cmds = append(cmds, []string{"/usr/bin/open"}) 20 case "windows": 21 cmds = append(cmds, []string{"cmd", "/c", "start"}) 22 default: 23 if os.Getenv("DISPLAY") != "" { 24 // xdg-open is only for use in a desktop environment. 25 cmds = append(cmds, []string{"xdg-open"}) 26 } 27 } 28 cmds = append(cmds, []string{"chrome"}, []string{"google-chrome"}, []string{"chromium"}, []string{"firefox"}) 29 for _, args := range cmds { 30 cmd := exec.Command(args[0], append(args[1:], url)...) 31 if cmd.Start() == nil && WaitTimeout(cmd, 3*time.Second) { 32 return true 33 } 34 } 35 return false 36 } 37 38 // WaitTimeout reports whether the command appears to have run successfully. 39 // If the command runs longer than the timeout, it's deemed successful. 40 // If the command runs within the timeout, it's deemed successful if it exited cleanly. 41 func WaitTimeout(cmd *exec.Cmd, timeout time.Duration) bool { 42 ch := make(chan error, 1) 43 go func() { 44 ch <- cmd.Wait() 45 }() 46 47 select { 48 case <-time.After(timeout): 49 return true 50 case err := <-ch: 51 return err == nil 52 } 53 } 54 55 func SleepContext(ctx context.Context, duration time.Duration) { 56 select { 57 case <-ctx.Done(): 58 case <-time.After(duration): 59 } 60 return 61 }