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

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"regexp"
     8  )
     9  
    10  var cmdApply = &Command{
    11  	Run:          apply,
    12  	GitExtension: true,
    13  	Usage:        "apply GITHUB-URL",
    14  	Short:        "Apply a patch to files and/or to the index",
    15  	Long: `Downloads the patch file for the pull request or commit at the URL and
    16  applies that patch from disk with git am or git apply. Similar to
    17  cherry-pick, but doesn't add new remotes. git am creates commits while
    18  preserving authorship info while <code>apply</code> only applies the
    19  patch to the working copy.
    20  `,
    21  }
    22  
    23  func init() {
    24  	CmdRunner.Use(cmdApply)
    25  }
    26  
    27  /*
    28    $ gh apply https://github.com/jingweno/gh/pull/55
    29    > curl https://github.com/jingweno/gh/pull/55.patch -o /tmp/55.patch
    30    > git apply /tmp/55.patch
    31  
    32    $ git apply --ignore-whitespace https://github.com/jingweno/gh/commit/fdb9921
    33    > curl https://github.com/jingweno/gh/commit/fdb9921.patch -o /tmp/fdb9921.patch
    34    > git apply --ignore-whitespace /tmp/fdb9921.patch
    35  
    36    $ git apply https://gist.github.com/8da7fb575debd88c54cf
    37    > curl https://gist.github.com/8da7fb575debd88c54cf.txt -o /tmp/gist-8da7fb575debd88c54cf.txt
    38    > git apply /tmp/gist-8da7fb575debd88c54cf.txt
    39  */
    40  func apply(command *Command, args *Args) {
    41  	if !args.IsParamsEmpty() {
    42  		transformApplyArgs(args)
    43  	}
    44  }
    45  
    46  func transformApplyArgs(args *Args) {
    47  	urlRegexp := regexp.MustCompile("^https?://(gist\\.)?github\\.com/")
    48  	for _, url := range args.Params {
    49  		if urlRegexp.MatchString(url) {
    50  			idx := args.IndexOfParam(url)
    51  			gist := urlRegexp.FindStringSubmatch(url)[1] == "gist."
    52  
    53  			fragmentRegexp := regexp.MustCompile("#.+")
    54  			url = fragmentRegexp.ReplaceAllString(url, "")
    55  			pullRegexp := regexp.MustCompile("(/pull/\\d+)/\\w*$")
    56  			if !gist {
    57  				if pullRegexp.MatchString(url) {
    58  					pull := pullRegexp.FindStringSubmatch(url)[1]
    59  					url = pullRegexp.ReplaceAllString(url, pull)
    60  				}
    61  			}
    62  
    63  			var ext string
    64  			if gist {
    65  				ext = ".txt"
    66  			} else {
    67  				ext = ".patch"
    68  			}
    69  
    70  			if filepath.Ext(url) != ext {
    71  				url += ext
    72  			}
    73  
    74  			var prefix string
    75  			if gist {
    76  				prefix = "gist-"
    77  			}
    78  
    79  			patchFile := filepath.Join(os.TempDir(), prefix+filepath.Base(url))
    80  
    81  			args.Before("curl", "-#LA", fmt.Sprintf("gh %s", Version), url, "-o", patchFile)
    82  			args.Params[idx] = patchFile
    83  
    84  			break
    85  		}
    86  	}
    87  }