rickub/clipublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/rickub/cli.git
git clone ssh://git@rickub.com/rickub/cli.git
Initial import of the rickub CLI as a standalone public project 1a1d430Unverified · on main · Olivier Girardot · 7h ago
browse.go · 91 lines · 2.1 KBGo Blame HistoryRaw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package cmd

import (
	"fmt"
	neturl "net/url"
	"os/exec"
	"runtime"
	"strings"

	"github.com/spf13/cobra"
)

var browsePrintOnly bool

func init() {
	browseCmd := &cobra.Command{
		Use:   "browse [owner/repo]",
		Short: "Open a repository in your browser",
		Long: `Open a repository's web page. With no argument the repo is inferred from the
current directory's git remote. Use --print to only print the URL.`,
		Args: cobra.RangeArgs(0, 1),
		RunE: runBrowse,
	}
	browseCmd.Flags().BoolVarP(&browsePrintOnly, "print", "p", false, "print the URL instead of opening it")
	rootCmd.AddCommand(browseCmd)
}

func runBrowse(cmd *cobra.Command, args []string) error {
	cfg, err := loadConfig()
	if err != nil {
		return err
	}
	spec := ""
	if len(args) == 1 {
		spec = args[0]
	}
	owner, repo, err := resolveRepo(spec)
	if err != nil {
		return err
	}
	url := fmt.Sprintf("%s/%s/%s", hostFor(cfg), owner, repo)
	if browsePrintOnly {
		fmt.Fprintln(cmd.OutOrStdout(), url)
		return nil
	}
	fmt.Fprintf(cmd.OutOrStdout(), "Opening %s\n", url)
	return openBrowser(url)
}

// checkBrowserURL rejects anything the platform opener should not be handed.
// The opener will launch whatever handler is registered for a scheme, so a URL
// that came from a server (or a stale config) must be a plain web address
// before we exec it.
func checkBrowserURL(raw string) error {
	u, err := neturl.Parse(raw)
	if err != nil {
		return fmt.Errorf("not a valid URL")
	}
	switch strings.ToLower(u.Scheme) {
	case "http", "https":
	default:
		if u.Scheme == "" {
			return fmt.Errorf("URL has no scheme; only http and https are opened")
		}
		return fmt.Errorf("refusing to open a %q URL; only http and https are opened", u.Scheme)
	}
	if u.Host == "" {
		return fmt.Errorf("URL has no host")
	}
	return nil
}

func openBrowser(url string) error {
	if err := checkBrowserURL(url); err != nil {
		return err
	}
	var name string
	var args []string
	switch runtime.GOOS {
	case "darwin":
		name = "open"
		args = []string{url}
	case "windows":
		name = "rundll32"
		args = []string{"url.dll,FileProtocolHandler", url}
	default:
		name = "xdg-open"
		args = []string{url}
	}
	return exec.Command(name, args...).Start()
}