package main import ( "flag" "net/url" "os/exec" "regexp" ) // MatchFunc is a signature for a function to match a URL type MatchFunc = func(url.URL) bool // A BrowserRule is a rule that will launch a browser, if matched type BrowserRule struct { matcher MatchFunc command string args []string } // IsMatched will check to see the rule matches the provied URL func (r BrowserRule) IsMatched(dest url.URL) bool { return r.matcher(dest) } // Launch will launch the browser with the provided URL func (r BrowserRule) Launch(dest url.URL) error { args := append(r.args, "--", dest.String()) cmd := exec.Command(r.command, args...) return cmd.Start() } // MaybeLaunch will lauch the browser with the provided URL if it matches the rule func (r BrowserRule) MaybeLaunch(dest url.URL) (bool, error) { if r.IsMatched(dest) { return true, r.Launch(dest) } return false, nil } func matchHostname(hostnames ...string) MatchFunc { return func(dest url.URL) bool { for _, host := range hostnames { if host == dest.Hostname() { return true } } return false } } func matchHostRegexp(hostRegexp ...string) MatchFunc { matchers := []*regexp.Regexp{} for _, s := range hostRegexp { matchers = append(matchers, regexp.MustCompile(s)) } return func(dest url.URL) bool { for _, matcher := range matchers { if matcher.MatchString(dest.Hostname()) { return true } } return false } } func matchRegexp(urlRegexp ...string) MatchFunc { matchers := []*regexp.Regexp{} for _, s := range urlRegexp { matchers = append(matchers, regexp.MustCompile(s)) } return func(dest url.URL) bool { for _, matcher := range matchers { if matcher.MatchString(dest.String()) { return true } } return false } } func matchAny(matchFuncs ...MatchFunc) MatchFunc { return func(dest url.URL) bool { for _, f := range matchFuncs { if f(dest) { return true } } return false } } // Always returns true func defaultBrowser(dest url.URL) bool { return true } // Never returns true func noop(dest url.URL) bool { return false } // Rules to evaluate var rules = []BrowserRule{ // Personal domains BrowserRule{ matcher: matchHostRegexp( `.*\.iamthefij\.com$`, `.*\.thefij\.rocks$`, `.*\.thefij$`, ), command: "firefox", }, // Work domains BrowserRule{ matcher: matchAny( matchHostname( "app.signalfx.com", "lever.co", "work.grubhub.com", "y", "yelp.rimeto.io", "yelp.slack.com", "yelplove.appspot.com", ), matchHostRegexp( `.*\.lifesize\.com$`, `.*\.myworkday\.com$`, `.*\.salesforce\.com$`, `.*\.yelpcorp\.com$`, ), ), command: "chromium-browser", }, // Googly domains BrowserRule{ matcher: matchAny( matchHostname( "google.com", "youtube.com", ), matchHostRegexp( `.*\.google\.com$`, `.*\.youtube\.com$`, ), ), command: "chromium-browser", }, // Default fallback browser BrowserRule{ matcher: defaultBrowser, command: "firefox", }, } func handleUrl(urlString string) error { dest, err := url.Parse(urlString) if err != nil { return err } var matched bool for _, rule := range rules { matched, err = rule.MaybeLaunch(*dest) if matched { break } } return nil } func main() { flag.Parse() urls := flag.Args() for _, urlString := range urls { err := handleUrl(urlString) if err != nil { panic(err) } } }