提交 a440fb47 编写于 作者: J Jingwen Owen Ou

Merge branch 'apply'

package commands
import (
"fmt"
"os"
"path/filepath"
"regexp"
)
var cmdApply = &Command{
Run: apply,
GitExtension: true,
Usage: "apply GITHUB-URL",
Short: "Apply a patch to files and/or to the index",
Long: `Downloads the patch file for the pull request or commit at the URL and
applies that patch from disk with git am or git apply. Similar to
cherry-pick, but doesn't add new remotes. git am creates commits while
preserving authorship info while <code>apply</code> only applies the
patch to the working copy.
`,
}
/*
$ gh 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
$ git apply --ignore-whitespace https://github.com/jingweno/gh/commit/fdb9921
> curl https://github.com/jingweno/gh/commit/fdb9921.patch -o /tmp/fdb9921.patch
> git apply --ignore-whitespace /tmp/fdb9921.patch
$ git apply https://gist.github.com/8da7fb575debd88c54cf
> curl https://gist.github.com/8da7fb575debd88c54cf.txt -o /tmp/gist-8da7fb575debd88c54cf.txt
> git apply /tmp/gist-8da7fb575debd88c54cf.txt
*/
func apply(command *Command, args *Args) {
if !args.IsParamsEmpty() {
transformApplyArgs(args)
}
}
func transformApplyArgs(args *Args) {
urlRegexp := regexp.MustCompile("^https?://(gist\\.)?github\\.com/")
for _, url := range args.Params {
if urlRegexp.MatchString(url) {
idx := args.IndexOfParam(url)
gist := urlRegexp.FindStringSubmatch(url)[1] == "gist."
fragmentRegexp := regexp.MustCompile("#.+")
url = fragmentRegexp.ReplaceAllString(url, "")
pullRegexp := regexp.MustCompile("(/pull/\\d+)/\\w*$")
if !gist {
if pullRegexp.MatchString(url) {
pull := pullRegexp.FindStringSubmatch(url)[1]
url = pullRegexp.ReplaceAllString(url, pull)
}
}
var ext string
if gist {
ext = ".txt"
} else {
ext = ".patch"
}
if filepath.Ext(url) != ext {
url += ext
}
var prefix string
if gist {
prefix = "gist-"
}
patchFile := filepath.Join(os.TempDir(), prefix+filepath.Base(url))
args.Before("curl", "-#LA", fmt.Sprintf("gh %s", Version), url, "-o", patchFile)
args.Params[idx] = patchFile
break
}
}
}
package commands
import (
"fmt"
"github.com/bmizerany/assert"
"regexp"
"strings"
"testing"
)
func TestTransformApplyArgs(t *testing.T) {
args := NewArgs([]string{"apply", "https://github.com/jingweno/gh/pull/55"})
transformApplyArgs(args)
cmds := args.Commands()
assert.Equal(t, 2, len(cmds))
curlString := fmt.Sprintf("curl -#LA %s https://github.com/jingweno/gh/pull/55.patch -o .+/55.patch", fmt.Sprintf("gh %s", Version))
curlRegexp := regexp.MustCompile(curlString)
applyString := "git apply"
assert.T(t, curlRegexp.MatchString(cmds[0].String()))
assert.T(t, strings.Contains(cmds[1].String(), applyString))
args = NewArgs([]string{"apply", "--ignore-whitespace", "https://github.com/jingweno/gh/commit/fdb9921"})
transformApplyArgs(args)
cmds = args.Commands()
assert.Equal(t, 2, len(cmds))
curlString = fmt.Sprintf("curl -#LA %s https://github.com/jingweno/gh/commit/fdb9921.patch -o .+/fdb9921.patch", fmt.Sprintf("gh %s", Version))
curlRegexp = regexp.MustCompile(curlString)
applyString = "git apply --ignore-whitespace"
assert.T(t, curlRegexp.MatchString(cmds[0].String()))
assert.T(t, strings.Contains(cmds[1].String(), applyString))
args = NewArgs([]string{"apply", "https://gist.github.com/8da7fb575debd88c54cf"})
transformApplyArgs(args)
cmds = args.Commands()
assert.Equal(t, 2, len(cmds))
curlString = fmt.Sprintf("curl -#LA %s https://gist.github.com/8da7fb575debd88c54cf.txt -o .+8da7fb575debd88c54cf.txt", fmt.Sprintf("gh %s", Version))
curlRegexp = regexp.MustCompile(curlString)
applyString = "git apply"
assert.T(t, curlRegexp.MatchString(cmds[0].String()))
assert.T(t, strings.Contains(cmds[1].String(), applyString))
}
......@@ -54,6 +54,7 @@ var Basic = []*Command{
var Branching = []*Command{
cmdCheckout,
cmdMerge,
cmdApply,
}
var Remote = []*Command{
......
......@@ -35,13 +35,16 @@ remotes are only added if they correspond to valid forks on GitHub.
*/
func fetch(command *Command, args *Args) {
if !args.IsParamsEmpty() {
tranformFetchArgs(args)
err := tranformFetchArgs(args)
utils.Check(err)
}
}
func tranformFetchArgs(args *Args) {
func tranformFetchArgs(args *Args) error {
remotes, err := git.Remotes()
utils.Check(err)
if err != nil {
return err
}
names := parseRemoteNames(args)
gh := github.New()
......@@ -67,6 +70,8 @@ func tranformFetchArgs(args *Args) {
}
args.Before("git", "remote", "add", project.Owner, project.GitURL("", "", isSSH))
}
return nil
}
func parseRemoteNames(args *Args) (names []string) {
......
......@@ -181,17 +181,19 @@ func readTitleAndBodyFrom(reader *bufio.Reader) (title, body string, err error)
r := regexp.MustCompile("\\S")
var titleParts, bodyParts []string
line, err := readln(reader)
line, err := readLine(reader)
for err == nil {
if strings.HasPrefix(line, "#") {
break
}
if len(bodyParts) == 0 && r.MatchString(line) {
titleParts = append(titleParts, line)
} else {
bodyParts = append(bodyParts, line)
}
line, err = readln(reader)
line, err = readLine(reader)
}
title = strings.Join(titleParts, " ")
......@@ -203,12 +205,13 @@ func readTitleAndBodyFrom(reader *bufio.Reader) (title, body string, err error)
return title, body, nil
}
func readln(r *bufio.Reader) (string, error) {
func readLine(r *bufio.Reader) (string, error) {
var (
isPrefix = true
err error
line, ln []byte
)
for isPrefix && err == nil {
line, isPrefix, err = r.ReadLine()
ln = append(ln, line...)
......
......@@ -40,15 +40,20 @@ func transformRemoteArgs(args *Args) {
if !match {
return
}
isPriavte := parseRemotePrivateFlag(args)
var err error
if name == "" {
name, err = utils.DirName()
utils.Check(err)
}
isPriavte := parseRemotePrivateFlag(args)
if owner == "origin" {
owner = github.CurrentConfig().FetchUser()
} else if args.ParamsSize() > 2 {
// `git remote add jingweno foo/bar`
args.RemoveParam(args.ParamsSize() - 1)
}
project := github.Project{Owner: owner, Name: name}
......
......@@ -49,4 +49,12 @@ func TestTransformRemoteArgs(t *testing.T) {
assert.Equal(t, "jingweno", args.GetParam(1))
assert.Equal(t, "add", args.FirstParam())
assert.Equal(t, "git@github.com:jingweno/gh.git", args.GetParam(2))
args = NewArgs([]string{"remote", "add", "-p", "origin", "org/foo"})
transformRemoteArgs(args)
assert.Equal(t, 3, args.ParamsSize())
assert.Equal(t, "origin", args.GetParam(1))
assert.Equal(t, "add", args.FirstParam())
assert.Equal(t, "git@github.com:org/foo.git", args.GetParam(2))
}
package commands
import (
"flag"
"fmt"
"github.com/jingweno/gh/cmd"
"github.com/jingweno/gh/git"
......@@ -26,7 +27,11 @@ func (r *Runner) Execute() error {
cmd.PrintUsage()
}
if err := cmd.Flag.Parse(args.Params); err != nil {
return err
if err == flag.ErrHelp {
return nil
} else {
return err
}
}
args.Params = cmd.Flag.Args()
......
......@@ -60,7 +60,7 @@ func convertToGitURL(pullRequest *octokat.PullRequest) (string, error) {
return project.GitURL("", user, isSSH), nil
}
func parseRepoNameOwner(nameWithOwner string) (owner, repo string, match bool) {
func parseRepoNameOwner(nameWithOwner string) (owner, name string, match bool) {
ownerRe := fmt.Sprintf("^(%s)$", OwnerRe)
ownerRegexp := regexp.MustCompile(ownerRe)
if ownerRegexp.MatchString(nameWithOwner) {
......@@ -74,7 +74,7 @@ func parseRepoNameOwner(nameWithOwner string) (owner, repo string, match bool) {
if nameWithOwnerRegexp.MatchString(nameWithOwner) {
result := nameWithOwnerRegexp.FindStringSubmatch(nameWithOwner)
owner = result[1]
repo = result[2]
name = result[2]
match = true
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册