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 }