github.com/trevoraustin/hub@v2.2.0-preview1.0.20141105230840-96d8bfc654cc+incompatible/commands/apply.go (about) 1 package commands 2 3 import ( 4 "io" 5 "io/ioutil" 6 "regexp" 7 8 "github.com/github/hub/github" 9 "github.com/github/hub/utils" 10 ) 11 12 var cmdApply = &Command{ 13 Run: apply, 14 GitExtension: true, 15 Usage: "apply GITHUB-URL", 16 Short: "Apply a patch to files and/or to the index", 17 Long: `Downloads the patch file for the pull request or commit at the URL and 18 applies that patch from disk with git am or git apply. Similar to 19 cherry-pick, but doesn't add new remotes. git am creates commits while 20 preserving authorship info while <code>apply</code> only applies the 21 patch to the working copy. 22 `, 23 } 24 25 var cmdAm = &Command{ 26 Run: apply, 27 GitExtension: true, 28 Usage: "am GITHUB-URL", 29 Short: "Apply a patch to files and/or to the index", 30 Long: `Downloads the patch file for the pull request or commit at the URL and 31 applies that patch from disk with git am or git apply. Similar to 32 cherry-pick, but doesn't add new remotes. git am creates commits while 33 preserving authorship info while <code>apply</code> only applies the 34 patch to the working copy. 35 `, 36 } 37 38 func init() { 39 CmdRunner.Use(cmdApply) 40 CmdRunner.Use(cmdAm) 41 } 42 43 /* 44 $ gh apply https://github.com/jingweno/gh/pull/55 45 > curl https://github.com/jingweno/gh/pull/55.patch -o /tmp/55.patch 46 > git apply /tmp/55.patch 47 48 $ git apply --ignore-whitespace https://github.com/jingweno/gh/commit/fdb9921 49 > curl https://github.com/jingweno/gh/commit/fdb9921.patch -o /tmp/fdb9921.patch 50 > git apply --ignore-whitespace /tmp/fdb9921.patch 51 52 $ git apply https://gist.github.com/8da7fb575debd88c54cf 53 > curl https://gist.github.com/8da7fb575debd88c54cf.txt -o /tmp/gist-8da7fb575debd88c54cf.txt 54 > git apply /tmp/gist-8da7fb575debd88c54cf.txt 55 */ 56 func apply(command *Command, args *Args) { 57 if !args.IsParamsEmpty() { 58 transformApplyArgs(args) 59 } 60 } 61 62 func transformApplyArgs(args *Args) { 63 gistRegexp := regexp.MustCompile("^https?://gist\\.github\\.com/([\\w.-]+/)?([a-f0-9]+)") 64 pullRegexp := regexp.MustCompile("^(pull|commit)/([0-9a-f]+)") 65 for _, arg := range args.Params { 66 var ( 67 patch io.ReadCloser 68 apiError error 69 ) 70 projectURL, err := github.ParseURL(arg) 71 if err == nil { 72 gh := github.NewClient(projectURL.Project.Host) 73 match := pullRegexp.FindStringSubmatch(projectURL.ProjectPath()) 74 if match != nil { 75 if match[1] == "pull" { 76 patch, apiError = gh.PullRequestPatch(projectURL.Project, match[2]) 77 } else { 78 patch, apiError = gh.CommitPatch(projectURL.Project, match[2]) 79 } 80 } 81 } else { 82 match := gistRegexp.FindStringSubmatch(arg) 83 if match != nil { 84 // TODO: support Enterprise gist 85 gh := github.NewClient(github.GitHubHost) 86 patch, apiError = gh.GistPatch(match[2]) 87 } 88 } 89 90 utils.Check(apiError) 91 if patch == nil { 92 continue 93 } 94 95 idx := args.IndexOfParam(arg) 96 patchFile, err := ioutil.TempFile("", "hub") 97 utils.Check(err) 98 99 _, err = io.Copy(patchFile, patch) 100 utils.Check(err) 101 102 patchFile.Close() 103 patch.Close() 104 105 args.Params[idx] = patchFile.Name() 106 } 107 }