1package commands 2 3import ( 4 "fmt" 5 "net/url" 6 "strings" 7 8 "github.com/github/hub/github" 9 "github.com/github/hub/utils" 10) 11 12var cmdBrowse = &Command{ 13 Run: browse, 14 Usage: "browse [-uc] [[<USER>/]<REPOSITORY>|--] [<SUBPAGE>]", 15 Long: `Open a GitHub repository in a web browser. 16 17## Options: 18 -u, --url 19 Print the URL instead of opening it. 20 21 -c, --copy 22 Put the URL in clipboard instead of opening it. 23 24 [<USER>/]<REPOSITORY> 25 Defaults to repository in the current working directory. 26 27 <SUBPAGE> 28 One of "wiki", "commits", "issues", or other (default: "tree"). 29 30## Examples: 31 $ hub browse 32 > open https://github.com/REPO 33 34 $ hub browse -- issues 35 > open https://github.com/REPO/issues 36 37 $ hub browse jingweno/gh 38 > open https://github.com/jingweno/gh 39 40 $ hub browse gh wiki 41 > open https://github.com/USER/gh/wiki 42 43## See also: 44 45hub-compare(1), hub(1) 46`, 47} 48 49func init() { 50 CmdRunner.Use(cmdBrowse) 51} 52 53func browse(command *Command, args *Args) { 54 var ( 55 dest string 56 subpage string 57 path string 58 project *github.Project 59 branch *github.Branch 60 err error 61 ) 62 63 if !args.IsParamsEmpty() { 64 dest = args.RemoveParam(0) 65 } 66 67 if !args.IsParamsEmpty() { 68 subpage = args.RemoveParam(0) 69 } 70 71 if args.Terminator { 72 subpage = dest 73 dest = "" 74 } 75 76 localRepo, _ := github.LocalRepo() 77 if dest != "" { 78 project = github.NewProject("", dest, "") 79 branch = localRepo.MasterBranch() 80 } else if subpage != "" && subpage != "commits" && subpage != "tree" && subpage != "blob" && subpage != "settings" { 81 project, err = localRepo.MainProject() 82 branch = localRepo.MasterBranch() 83 utils.Check(err) 84 } else { 85 currentBranch, err := localRepo.CurrentBranch() 86 if err != nil { 87 currentBranch = localRepo.MasterBranch() 88 } 89 90 var owner string 91 mainProject, err := localRepo.MainProject() 92 if err == nil { 93 host, err := github.CurrentConfig().PromptForHost(mainProject.Host) 94 if err != nil { 95 utils.Check(github.FormatError("in browse", err)) 96 } else { 97 owner = host.User 98 } 99 } 100 101 branch, project, _ = localRepo.RemoteBranchAndProject(owner, currentBranch.IsMaster()) 102 if branch == nil { 103 branch = localRepo.MasterBranch() 104 } 105 } 106 107 if project == nil { 108 utils.Check(command.UsageError("")) 109 } 110 111 if subpage == "commits" { 112 path = fmt.Sprintf("commits/%s", branchInURL(branch)) 113 } else if subpage == "tree" || subpage == "" { 114 if !branch.IsMaster() { 115 path = fmt.Sprintf("tree/%s", branchInURL(branch)) 116 } 117 } else { 118 path = subpage 119 } 120 121 pageUrl := project.WebURL("", "", path) 122 123 args.NoForward() 124 flagBrowseURLPrint := args.Flag.Bool("--url") 125 flagBrowseURLCopy := args.Flag.Bool("--copy") 126 printBrowseOrCopy(args, pageUrl, !flagBrowseURLPrint && !flagBrowseURLCopy, flagBrowseURLCopy) 127} 128 129func branchInURL(branch *github.Branch) string { 130 parts := strings.Split(branch.ShortName(), "/") 131 newPath := make([]string, len(parts)) 132 for i, s := range parts { 133 newPath[i] = url.QueryEscape(s) 134 } 135 return strings.Join(newPath, "/") 136} 137