github.com/trevoraustin/hub@v2.2.0-preview1.0.20141105230840-96d8bfc654cc+incompatible/commands/browse.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"strings"
     7  
     8  	"github.com/github/hub/github"
     9  	"github.com/github/hub/utils"
    10  )
    11  
    12  var cmdBrowse = &Command{
    13  	Run:          browse,
    14  	GitExtension: true,
    15  	Usage:        "browse [-u] [[<USER>/]<REPOSITORY>|--] [SUBPAGE]",
    16  	Short:        "Open a GitHub page in the default browser",
    17  	Long: `Open repository's GitHub page in the system's default web browser using
    18  "open(1)" or the "BROWSER" env variable. If the repository isn't
    19  specified, "browse" opens the page of the repository found in the current
    20  directory. If SUBPAGE is specified, the browser will open on the specified
    21  subpage: one of "wiki", "commits", "issues" or other (the default is
    22  "tree"). With "-u", outputs the URL rather than opening the browser.
    23  `,
    24  }
    25  
    26  func init() {
    27  	CmdRunner.Use(cmdBrowse)
    28  }
    29  
    30  /*
    31    $ gh browse
    32    > open https://github.com/CURRENT_REPO
    33  
    34    $ gh browse -- issues
    35    > open https://github.com/CURRENT_REPO/issues
    36  
    37    $ gh browse jingweno/gh
    38    > open https://github.com/jingweno/gh
    39  
    40    $ gh browse gh
    41    > open https://github.com/YOUR_LOGIN/gh
    42  
    43    $ gh browse gh wiki
    44    > open https://github.com/YOUR_LOGIN/gh/wiki
    45  */
    46  func browse(command *Command, args *Args) {
    47  	var (
    48  		dest    string
    49  		subpage string
    50  		path    string
    51  		project *github.Project
    52  		branch  *github.Branch
    53  		err     error
    54  	)
    55  
    56  	flagBrowseURLOnly := parseFlagBrowseURLOnly(args)
    57  
    58  	if !args.IsParamsEmpty() {
    59  		dest = args.RemoveParam(0)
    60  	}
    61  
    62  	if dest == "--" {
    63  		dest = ""
    64  	}
    65  
    66  	if !args.IsParamsEmpty() {
    67  		subpage = args.RemoveParam(0)
    68  	}
    69  
    70  	localRepo, _ := github.LocalRepo()
    71  	if dest != "" {
    72  		project = github.NewProject("", dest, "")
    73  		branch = localRepo.MasterBranch()
    74  	} else if subpage != "" && subpage != "commits" && subpage != "tree" && subpage != "blob" && subpage != "settings" {
    75  		project, err = localRepo.MainProject()
    76  		branch = localRepo.MasterBranch()
    77  		utils.Check(err)
    78  	} else {
    79  		currentBranch, err := localRepo.CurrentBranch()
    80  		if err != nil {
    81  			currentBranch = localRepo.MasterBranch()
    82  		}
    83  
    84  		branch, project, _ = localRepo.RemoteBranchAndProject("", currentBranch.IsMaster())
    85  		if branch == nil {
    86  			branch = localRepo.MasterBranch()
    87  		}
    88  	}
    89  
    90  	if project == nil {
    91  		err := fmt.Errorf(command.FormattedUsage())
    92  		utils.Check(err)
    93  	}
    94  
    95  	if subpage == "commits" {
    96  		path = fmt.Sprintf("commits/%s", branchInURL(branch))
    97  	} else if subpage == "tree" || subpage == "" {
    98  		if !branch.IsMaster() {
    99  			path = fmt.Sprintf("tree/%s", branchInURL(branch))
   100  		}
   101  	} else {
   102  		path = subpage
   103  	}
   104  
   105  	pageUrl := project.WebURL("", "", path)
   106  	launcher, err := utils.BrowserLauncher()
   107  	utils.Check(err)
   108  
   109  	if flagBrowseURLOnly {
   110  		args.Replace("echo", pageUrl)
   111  	} else {
   112  		args.Replace(launcher[0], "", launcher[1:]...)
   113  		args.AppendParams(pageUrl)
   114  	}
   115  }
   116  
   117  func parseFlagBrowseURLOnly(args *Args) bool {
   118  	if i := args.IndexOfParam("-u"); i != -1 {
   119  		args.RemoveParam(i)
   120  		return true
   121  	}
   122  
   123  	return false
   124  }
   125  
   126  func branchInURL(branch *github.Branch) string {
   127  	parts := strings.Split(branch.ShortName(), "/")
   128  	newPath := make([]string, len(parts))
   129  	for i, s := range parts {
   130  		newPath[i] = url.QueryEscape(s)
   131  	}
   132  	return strings.Join(newPath, "/")
   133  }