2013-07-11 22:23:59 +04:00
|
|
|
package commands
|
|
|
|
|
|
|
|
import (
|
2014-09-21 10:44:20 +04:00
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
2019-01-24 19:19:06 +03:00
|
|
|
"os"
|
2013-07-19 02:08:32 +04:00
|
|
|
"regexp"
|
2014-07-26 01:52:24 +04:00
|
|
|
|
|
|
|
"github.com/github/hub/github"
|
2014-09-21 10:44:20 +04:00
|
|
|
"github.com/github/hub/utils"
|
2013-07-11 22:23:59 +04:00
|
|
|
)
|
|
|
|
|
|
|
|
var cmdApply = &Command{
|
|
|
|
Run: apply,
|
|
|
|
GitExtension: true,
|
2016-01-24 11:56:18 +03:00
|
|
|
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
|
2016-01-24 18:50:01 +03:00
|
|
|
|
|
|
|
## See also:
|
|
|
|
|
|
|
|
hub-am(1), hub(1), git-apply(1)
|
2013-07-11 22:23:59 +04:00
|
|
|
`,
|
|
|
|
}
|
|
|
|
|
2014-07-26 01:55:12 +04:00
|
|
|
var cmdAm = &Command{
|
|
|
|
Run: apply,
|
|
|
|
GitExtension: true,
|
2016-01-24 11:56:18 +03:00
|
|
|
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
|
2016-01-24 18:50:01 +03:00
|
|
|
|
|
|
|
## See also:
|
|
|
|
|
|
|
|
hub-apply(1), hub-cherry-pick(1), hub(1), git-am(1)
|
2014-07-26 01:55:12 +04:00
|
|
|
`,
|
|
|
|
}
|
|
|
|
|
2013-12-30 02:18:14 +04:00
|
|
|
func init() {
|
|
|
|
CmdRunner.Use(cmdApply)
|
2014-07-26 01:55:12 +04:00
|
|
|
CmdRunner.Use(cmdAm)
|
2013-12-30 02:18:14 +04:00
|
|
|
}
|
|
|
|
|
2013-07-11 22:23:59 +04:00
|
|
|
func apply(command *Command, args *Args) {
|
2013-07-19 02:08:32 +04:00
|
|
|
if !args.IsParamsEmpty() {
|
|
|
|
transformApplyArgs(args)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func transformApplyArgs(args *Args) {
|
2014-09-21 10:44:20 +04:00
|
|
|
gistRegexp := regexp.MustCompile("^https?://gist\\.github\\.com/([\\w.-]+/)?([a-f0-9]+)")
|
2018-05-29 15:06:29 +03:00
|
|
|
commitRegexp := regexp.MustCompile("^(commit|pull/[0-9]+/commits)/([0-9a-f]+)")
|
|
|
|
pullRegexp := regexp.MustCompile("^pull/([0-9]+)")
|
2019-01-14 05:50:21 +03:00
|
|
|
for idx, arg := range args.Params {
|
2014-07-26 01:52:24 +04:00
|
|
|
var (
|
2014-09-21 10:44:20 +04:00
|
|
|
patch io.ReadCloser
|
|
|
|
apiError error
|
2014-07-26 01:52:24 +04:00
|
|
|
)
|
|
|
|
projectURL, err := github.ParseURL(arg)
|
|
|
|
if err == nil {
|
2014-09-21 10:44:20 +04:00
|
|
|
gh := github.NewClient(projectURL.Project.Host)
|
2018-05-29 15:06:29 +03:00
|
|
|
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])
|
2013-07-19 02:08:32 +04:00
|
|
|
}
|
2014-07-26 01:52:24 +04:00
|
|
|
} else {
|
2014-09-21 10:44:20 +04:00
|
|
|
match := gistRegexp.FindStringSubmatch(arg)
|
|
|
|
if match != nil {
|
|
|
|
// TODO: support Enterprise gist
|
|
|
|
gh := github.NewClient(github.GitHubHost)
|
|
|
|
patch, apiError = gh.GistPatch(match[2])
|
2013-07-19 02:08:32 +04:00
|
|
|
}
|
2014-07-26 01:52:24 +04:00
|
|
|
}
|
2013-07-19 02:08:32 +04:00
|
|
|
|
2014-09-21 10:44:20 +04:00
|
|
|
utils.Check(apiError)
|
|
|
|
if patch == nil {
|
2014-07-26 01:52:24 +04:00
|
|
|
continue
|
|
|
|
}
|
2013-07-19 02:08:32 +04:00
|
|
|
|
2019-01-24 19:19:06 +03:00
|
|
|
tempDir := os.TempDir()
|
|
|
|
err = os.MkdirAll(tempDir, 0775)
|
|
|
|
utils.Check(err)
|
|
|
|
patchFile, err := ioutil.TempFile(tempDir, "hub")
|
2014-09-21 10:44:20 +04:00
|
|
|
utils.Check(err)
|
2013-07-19 02:08:32 +04:00
|
|
|
|
2014-09-21 20:38:30 +04:00
|
|
|
_, err = io.Copy(patchFile, patch)
|
2014-09-21 10:44:20 +04:00
|
|
|
utils.Check(err)
|
2014-07-26 01:52:24 +04:00
|
|
|
|
2014-09-21 10:44:20 +04:00
|
|
|
patchFile.Close()
|
|
|
|
patch.Close()
|
2014-07-26 01:52:24 +04:00
|
|
|
|
2019-01-14 05:50:21 +03:00
|
|
|
args.ReplaceParam(idx, patchFile.Name())
|
2013-07-19 02:08:32 +04:00
|
|
|
}
|
2013-07-11 22:23:59 +04:00
|
|
|
}
|