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
browse.go · 91 lines · 2.1 KBGo Blame HistoryRaw
Initial import of the rickub CLI as a standalone public project 1a1d430 Olivier Girardot 9h ago1package cmd
2
3import (
4 "fmt"
5 neturl "net/url"
6 "os/exec"
7 "runtime"
8 "strings"
9
10 "github.com/spf13/cobra"
11)
12
13var browsePrintOnly bool
14
15func init() {
16 browseCmd := &cobra.Command{
17 Use: "browse [owner/repo]",
18 Short: "Open a repository in your browser",
19 Long: `Open a repository's web page. With no argument the repo is inferred from the
20current directory's git remote. Use --print to only print the URL.`,
21 Args: cobra.RangeArgs(0, 1),
22 RunE: runBrowse,
23 }
24 browseCmd.Flags().BoolVarP(&browsePrintOnly, "print", "p", false, "print the URL instead of opening it")
25 rootCmd.AddCommand(browseCmd)
26}
27
28func runBrowse(cmd *cobra.Command, args []string) error {
29 cfg, err := loadConfig()
30 if err != nil {
31 return err
32 }
33 spec := ""
34 if len(args) == 1 {
35 spec = args[0]
36 }
37 owner, repo, err := resolveRepo(spec)
38 if err != nil {
39 return err
40 }
41 url := fmt.Sprintf("%s/%s/%s", hostFor(cfg), owner, repo)
42 if browsePrintOnly {
43 fmt.Fprintln(cmd.OutOrStdout(), url)
44 return nil
45 }
46 fmt.Fprintf(cmd.OutOrStdout(), "Opening %s\n", url)
47 return openBrowser(url)
48}
49
50// checkBrowserURL rejects anything the platform opener should not be handed.
51// The opener will launch whatever handler is registered for a scheme, so a URL
52// that came from a server (or a stale config) must be a plain web address
53// before we exec it.
54func checkBrowserURL(raw string) error {
55 u, err := neturl.Parse(raw)
56 if err != nil {
57 return fmt.Errorf("not a valid URL")
58 }
59 switch strings.ToLower(u.Scheme) {
60 case "http", "https":
61 default:
62 if u.Scheme == "" {
63 return fmt.Errorf("URL has no scheme; only http and https are opened")
64 }
65 return fmt.Errorf("refusing to open a %q URL; only http and https are opened", u.Scheme)
66 }
67 if u.Host == "" {
68 return fmt.Errorf("URL has no host")
69 }
70 return nil
71}
72
73func openBrowser(url string) error {
74 if err := checkBrowserURL(url); err != nil {
75 return err
76 }
77 var name string
78 var args []string
79 switch runtime.GOOS {
80 case "darwin":
81 name = "open"
82 args = []string{url}
83 case "windows":
84 name = "rundll32"
85 args = []string{"url.dll,FileProtocolHandler", url}
86 default:
87 name = "xdg-open"
88 args = []string{url}
89 }
90 return exec.Command(name, args...).Start()
91}