forked from mislav/hub
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapply.go
114 lines (93 loc) · 2.58 KB
/
apply.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package commands
import (
"io"
"io/ioutil"
"os"
"regexp"
"github.com/github/hub/v2/github"
"github.com/github/hub/v2/utils"
)
var cmdApply = &Command{
Run: apply,
GitExtension: true,
Usage: "apply <GITHUB-URL>",
Long: `Download a patch from GitHub and apply it locally.
## Options:
<GITHUB-URL>
A URL to a pull request or commit on GitHub.
## Examples:
$ hub apply https://github.com/jingweno/gh/pull/55
> curl https://github.com/jingweno/gh/pull/55.patch -o /tmp/55.patch
> git apply /tmp/55.patch
## See also:
hub-am(1), hub(1), git-apply(1)
`,
}
var cmdAm = &Command{
Run: apply,
GitExtension: true,
Usage: "am [-3] <GITHUB-URL>",
Long: `Replicate commits from a GitHub pull request locally.
## Options:
-3
(Recommended) See git-am(1).
<GITHUB-URL>
A URL to a pull request or commit on GitHub.
## Examples:
$ hub am -3 https://github.com/jingweno/gh/pull/55
> curl https://github.com/jingweno/gh/pull/55.patch -o /tmp/55.patch
> git am -3 /tmp/55.patch
## See also:
hub-apply(1), hub-cherry-pick(1), hub(1), git-am(1)
`,
}
func init() {
CmdRunner.Use(cmdApply)
CmdRunner.Use(cmdAm)
}
func apply(command *Command, args *Args) {
if !args.IsParamsEmpty() {
transformApplyArgs(args)
}
}
func transformApplyArgs(args *Args) {
gistRegexp := regexp.MustCompile("^https?://gist\\.github\\.com/([\\w.-]+/)?([a-f0-9]+)")
commitRegexp := regexp.MustCompile("^(commit|pull/[0-9]+/commits)/([0-9a-f]+)")
pullRegexp := regexp.MustCompile("^pull/([0-9]+)")
for idx, arg := range args.Params {
var (
patch io.ReadCloser
apiError error
)
projectURL, err := github.ParseURL(arg)
if err == nil {
gh := github.NewClient(projectURL.Project.Host)
if match := commitRegexp.FindStringSubmatch(projectURL.ProjectPath()); match != nil {
patch, apiError = gh.CommitPatch(projectURL.Project, match[2])
} else if match := pullRegexp.FindStringSubmatch(projectURL.ProjectPath()); match != nil {
patch, apiError = gh.PullRequestPatch(projectURL.Project, match[1])
}
} else {
match := gistRegexp.FindStringSubmatch(arg)
if match != nil {
// TODO: support Enterprise gist
gh := github.NewClient(github.GitHubHost)
patch, apiError = gh.GistPatch(match[2])
}
}
utils.Check(apiError)
if patch == nil {
continue
}
tempDir := os.TempDir()
err = os.MkdirAll(tempDir, 0775)
utils.Check(err)
patchFile, err := ioutil.TempFile(tempDir, "hub")
utils.Check(err)
_, err = io.Copy(patchFile, patch)
utils.Check(err)
patchFile.Close()
patch.Close()
args.ReplaceParam(idx, patchFile.Name())
}
}