github.com/jingweno/gh@v2.1.1-0.20221007190738-04a7985fa9a1+incompatible/commands/compare.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  
     7  	"github.com/jingweno/gh/github"
     8  	"github.com/jingweno/gh/utils"
     9  )
    10  
    11  var cmdCompare = &Command{
    12  	Run:   compare,
    13  	Usage: "compare [-u] [USER] [<START>...]<END>",
    14  	Short: "Open a compare page on GitHub",
    15  	Long: `Open a GitHub compare view page in the system's default web browser.
    16  <START> to <END> are branch names, tag names, or commit SHA1s specifying
    17  the range of history to compare. If a range with two dots ("a..b") is given,
    18  it will be transformed into one with three dots. If <START> is omitted,
    19  GitHub will compare against the base branch (the default is "master").
    20  If <END> is omitted, GitHub compare view is opened for the current branch.
    21  With "-u", outputs the URL rather than opening the browser.
    22  `,
    23  }
    24  
    25  var (
    26  	flagCompareURLOnly bool
    27  )
    28  
    29  func init() {
    30  	cmdCompare.Flag.BoolVarP(&flagCompareURLOnly, "url-only", "u", false, "URL only")
    31  
    32  	CmdRunner.Use(cmdCompare)
    33  }
    34  
    35  /*
    36    $ gh compare refactor
    37    > open https://github.com/CURRENT_REPO/compare/refactor
    38  
    39    $ gh compare 1.0..1.1
    40    > open https://github.com/CURRENT_REPO/compare/1.0...1.1
    41  
    42    $ gh compare -u other-user patch
    43    > open https://github.com/other-user/REPO/compare/patch
    44  */
    45  func compare(command *Command, args *Args) {
    46  	localRepo := github.LocalRepo()
    47  	var (
    48  		branch  *github.Branch
    49  		project *github.Project
    50  		r       string
    51  		err     error
    52  	)
    53  
    54  	branch, project, err = localRepo.RemoteBranchAndProject("")
    55  	utils.Check(err)
    56  
    57  	if args.IsParamsEmpty() {
    58  		master := localRepo.MasterBranch()
    59  		if master.ShortName() == branch.ShortName() {
    60  			err = fmt.Errorf(command.FormattedUsage())
    61  			utils.Check(err)
    62  		} else {
    63  			r = branch.ShortName()
    64  		}
    65  	} else {
    66  		r = parseCompareRange(args.RemoveParam(args.ParamsSize() - 1))
    67  		if args.IsParamsEmpty() {
    68  			project, err = localRepo.CurrentProject()
    69  			utils.Check(err)
    70  		} else {
    71  			project = github.NewProject(args.RemoveParam(args.ParamsSize()-1), "", "")
    72  		}
    73  	}
    74  
    75  	subpage := utils.ConcatPaths("compare", r)
    76  	url := project.WebURL("", "", subpage)
    77  	launcher, err := utils.BrowserLauncher()
    78  	utils.Check(err)
    79  
    80  	if flagCompareURLOnly {
    81  		args.Replace("echo", url)
    82  	} else {
    83  		args.Replace(launcher[0], "", launcher[1:]...)
    84  		args.AppendParams(url)
    85  	}
    86  }
    87  
    88  func parseCompareRange(r string) string {
    89  	shaOrTag := fmt.Sprintf("((?:%s:)?\\w[\\w.-]+\\w)", OwnerRe)
    90  	shaOrTagRange := fmt.Sprintf("^%s\\.\\.%s$", shaOrTag, shaOrTag)
    91  	shaOrTagRangeRegexp := regexp.MustCompile(shaOrTagRange)
    92  	return shaOrTagRangeRegexp.ReplaceAllString(r, "$1...$2")
    93  }