Merge pull request #38 from github/pr-create

Add `pr create` command

Closes #59
This commit is contained in:
Mislav Marohnić 2019-11-14 19:33:30 +01:00 committed by GitHub
commit 1479ff457a
13 changed files with 590 additions and 7 deletions

View file

@ -401,6 +401,45 @@ func PullRequestsForBranch(client *Client, ghRepo Repo, branch string) ([]PullRe
return prs, nil
}
func CreatePullRequest(client *Client, ghRepo Repo, params map[string]interface{}) (*PullRequest, error) {
repoID, err := GitHubRepoId(client, ghRepo)
if err != nil {
return nil, err
}
query := `
mutation CreatePullRequest($input: CreatePullRequestInput!) {
createPullRequest(input: $input) {
pullRequest {
url
}
}
}`
inputParams := map[string]interface{}{
"repositoryId": repoID,
}
for key, val := range params {
inputParams[key] = val
}
variables := map[string]interface{}{
"input": inputParams,
}
result := struct {
CreatePullRequest struct {
PullRequest PullRequest
}
}{}
err = client.GraphQL(query, variables, &result)
if err != nil {
return nil, err
}
return &result.CreatePullRequest.PullRequest, nil
}
func PullRequestList(client *Client, vars map[string]interface{}, limit int) ([]PullRequest, error) {
type response struct {
Repository struct {

View file

@ -13,6 +13,7 @@ import (
func init() {
RootCmd.AddCommand(prCmd)
prCmd.AddCommand(prCreateCmd)
prCmd.AddCommand(prListCmd)
prCmd.AddCommand(prStatusCmd)
prCmd.AddCommand(prViewCmd)

223
command/pr_create.go Normal file
View file

@ -0,0 +1,223 @@
package command
import (
"fmt"
"os"
"runtime"
"github.com/AlecAivazis/survey/v2"
"github.com/github/gh-cli/api"
"github.com/github/gh-cli/context"
"github.com/github/gh-cli/git"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
func prCreate(cmd *cobra.Command, _ []string) error {
ctx := contextForCommand(cmd)
ucc, err := git.UncommittedChangeCount()
if err != nil {
return err
}
if ucc > 0 {
noun := "change"
if ucc > 1 {
// TODO: use pluralize helper
noun = noun + "s"
}
cmd.Printf("Warning: %d uncommitted %s\n", ucc, noun)
}
head, err := ctx.Branch()
if err != nil {
return errors.Wrap(err, "could not determine current branch")
}
remote, err := guessRemote(ctx)
if err != nil {
return err
}
if err = git.Push(remote, fmt.Sprintf("HEAD:%s", head)); err != nil {
return fmt.Errorf("was not able to push to remote '%s': %s", remote, err)
}
title, err := cmd.Flags().GetString("title")
if err != nil {
return errors.Wrap(err, "could not parse title")
}
body, err := cmd.Flags().GetString("body")
if err != nil {
return errors.Wrap(err, "could not parse body")
}
interactive := title == "" || body == ""
inProgress := struct {
Body string
Title string
}{}
if interactive {
confirmed := false
editor := determineEditor()
for !confirmed {
titleQuestion := &survey.Question{
Name: "title",
Prompt: &survey.Input{
Message: "PR Title",
Default: inProgress.Title,
},
}
bodyQuestion := &survey.Question{
Name: "body",
Prompt: &survey.Editor{
Message: fmt.Sprintf("PR Body (%s)", editor),
FileName: "*.md",
Default: inProgress.Body,
AppendDefault: true,
Editor: editor,
},
}
qs := []*survey.Question{}
if title == "" {
qs = append(qs, titleQuestion)
}
if body == "" {
qs = append(qs, bodyQuestion)
}
err := survey.Ask(qs, &inProgress)
if err != nil {
return errors.Wrap(err, "could not prompt")
}
confirmAnswers := struct {
Confirmation string
}{}
confirmQs := []*survey.Question{
{
Name: "confirmation",
Prompt: &survey.Select{
Message: "Submit?",
Options: []string{
"Yes",
"Edit",
"Cancel",
},
},
},
}
err = survey.Ask(confirmQs, &confirmAnswers)
if err != nil {
return errors.Wrap(err, "could not prompt")
}
switch confirmAnswers.Confirmation {
case "Yes":
confirmed = true
case "Edit":
continue
case "Cancel":
cmd.Println("Discarding pull request")
return nil
}
}
}
if title == "" {
title = inProgress.Title
}
if body == "" {
body = inProgress.Body
}
base, err := cmd.Flags().GetString("base")
if err != nil {
return errors.Wrap(err, "could not parse base")
}
if base == "" {
// TODO: use default branch for the repo
base = "master"
}
client, err := apiClientForContext(ctx)
if err != nil {
return errors.Wrap(err, "could not initialize api client")
}
repo, err := ctx.BaseRepo()
if err != nil {
return errors.Wrap(err, "could not determine GitHub repo")
}
isDraft, err := cmd.Flags().GetBool("draft")
if err != nil {
return errors.Wrap(err, "could not parse draft")
}
params := map[string]interface{}{
"title": title,
"body": body,
"draft": isDraft,
"baseRefName": base,
"headRefName": head,
}
pr, err := api.CreatePullRequest(client, repo, params)
if err != nil {
return errors.Wrap(err, "failed to create PR")
}
fmt.Fprintln(cmd.OutOrStdout(), pr.URL)
return nil
}
func guessRemote(ctx context.Context) (string, error) {
remotes, err := ctx.Remotes()
if err != nil {
return "", errors.Wrap(err, "could not read git remotes")
}
// TODO: consolidate logic with fsContext.BaseRepo
// TODO: check if the GH repo that the remote points to is writeable
remote, err := remotes.FindByName("upstream", "github", "origin", "*")
if err != nil {
return "", errors.Wrap(err, "could not determine suitable remote")
}
return remote.Name, nil
}
func determineEditor() string {
if runtime.GOOS == "windows" {
return "notepad"
}
if v := os.Getenv("VISUAL"); v != "" {
return v
}
if e := os.Getenv("EDITOR"); e != "" {
return e
}
return "nano"
}
var prCreateCmd = &cobra.Command{
Use: "create",
Short: "Create a pull request",
RunE: prCreate,
}
func init() {
prCreateCmd.Flags().BoolP("draft", "d", false,
"Mark PR as a draft")
prCreateCmd.Flags().StringP("title", "t", "",
"Supply a title. Will prompt for one otherwise.")
prCreateCmd.Flags().StringP("body", "b", "",
"Supply a body. Will prompt for one otherwise.")
prCreateCmd.Flags().StringP("base", "T", "",
"The branch into which you want your code merged")
}

136
command/pr_create_test.go Normal file
View file

@ -0,0 +1,136 @@
package command
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"testing"
"github.com/github/gh-cli/context"
"github.com/github/gh-cli/git"
"github.com/github/gh-cli/test"
)
func TestPrCreateHelperProcess(*testing.T) {
if test.SkipTestHelperProcess() {
return
}
args := test.GetTestHelperProcessArgs()
switch args[1] {
case "status":
switch args[0] {
case "clean":
case "dirty":
fmt.Println(" M git/git.go")
default:
fmt.Fprintf(os.Stderr, "unknown scenario: %q", args[0])
os.Exit(1)
}
case "push":
default:
fmt.Fprintf(os.Stderr, "unknown command: %q", args[1])
os.Exit(1)
}
os.Exit(0)
}
func TestPRCreate(t *testing.T) {
ctx := context.NewBlank()
ctx.SetBranch("feature")
ctx.SetRemotes(map[string]string{
"origin": "OWNER/REPO",
})
initContext = func() context.Context {
return ctx
}
http := initFakeHTTP()
http.StubResponse(200, bytes.NewBufferString(`
{ "data": { "repository": {
"id": "REPOID"
} } }
`))
http.StubResponse(200, bytes.NewBufferString(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`))
origGitCommand := git.GitCommand
git.GitCommand = test.StubExecCommand("TestPrCreateHelperProcess", "clean")
defer func() {
git.GitCommand = origGitCommand
}()
out := bytes.Buffer{}
prCreateCmd.SetOut(&out)
RootCmd.SetArgs([]string{"pr", "create", "-t", "mytitle", "-b", "mybody"})
_, err := prCreateCmd.ExecuteC()
eq(t, err, nil)
bodyBytes, _ := ioutil.ReadAll(http.Requests[1].Body)
reqBody := struct {
Variables struct {
Input struct {
RepositoryID string
Title string
Body string
BaseRefName string
HeadRefName string
}
}
}{}
json.Unmarshal(bodyBytes, &reqBody)
eq(t, reqBody.Variables.Input.RepositoryID, "REPOID")
eq(t, reqBody.Variables.Input.Title, "mytitle")
eq(t, reqBody.Variables.Input.Body, "mybody")
eq(t, reqBody.Variables.Input.BaseRefName, "master")
eq(t, reqBody.Variables.Input.HeadRefName, "feature")
eq(t, out.String(), "https://github.com/OWNER/REPO/pull/12\n")
}
func TestPRCreate_ReportsUncommittedChanges(t *testing.T) {
ctx := context.NewBlank()
ctx.SetBranch("feature")
ctx.SetRemotes(map[string]string{
"origin": "OWNER/REPO",
})
initContext = func() context.Context {
return ctx
}
http := initFakeHTTP()
http.StubResponse(200, bytes.NewBufferString(`
{ "data": { "repository": {
"id": "REPOID"
} } }
`))
http.StubResponse(200, bytes.NewBufferString(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`))
origGitCommand := git.GitCommand
git.GitCommand = test.StubExecCommand("TestPrCreateHelperProcess", "dirty")
defer func() {
git.GitCommand = origGitCommand
}()
out := bytes.Buffer{}
prCreateCmd.SetOut(&out)
RootCmd.SetArgs([]string{"pr", "create", "-t", "mytitle", "-b", "mybody"})
_, err := prCreateCmd.ExecuteC()
eq(t, err, nil)
eq(t, out.String(), `Warning: 1 uncommitted change
https://github.com/OWNER/REPO/pull/12
`)
}

View file

@ -73,7 +73,8 @@ var apiClientForContext = func(ctx context.Context) (*api.Client, error) {
api.AddHeader("Authorization", fmt.Sprintf("token %s", token)),
api.AddHeader("User-Agent", fmt.Sprintf("GitHub CLI %s", Version)),
// antiope-preview: Checks
api.AddHeader("Accept", "application/vnd.github.antiope-preview+json"),
// shadow-cat-preview: Draft pull requests
api.AddHeader("Accept", "application/vnd.github.antiope-preview+json, application/vnd.github.shadow-cat-preview"),
}
if verbose := os.Getenv("DEBUG"); verbose != "" {
opts = append(opts, api.VerboseLog(os.Stderr))

View file

@ -3,10 +3,12 @@ package context
import (
"fmt"
"strings"
"github.com/github/gh-cli/git"
)
// NewBlank initializes a blank Context suitable for testing
func NewBlank() Context {
func NewBlank() *blankContext {
return &blankContext{}
}
@ -16,6 +18,7 @@ type blankContext struct {
authLogin string
branch string
baseRepo GitHubRepository
remotes Remotes
}
type ghRepo struct {
@ -54,14 +57,36 @@ func (c *blankContext) SetBranch(b string) {
}
func (c *blankContext) Remotes() (Remotes, error) {
return Remotes{}, nil
if c.remotes == nil {
return nil, fmt.Errorf("remotes were not initialized")
}
return c.remotes, nil
}
func (c *blankContext) SetRemotes(stubs map[string]string) {
c.remotes = Remotes{}
for remoteName, repo := range stubs {
ownerWithName := strings.SplitN(repo, "/", 2)
c.remotes = append(c.remotes, &Remote{
Remote: &git.Remote{Name: remoteName},
Owner: ownerWithName[0],
Repo: ownerWithName[1],
})
}
}
func (c *blankContext) BaseRepo() (GitHubRepository, error) {
if c.baseRepo == nil {
return nil, fmt.Errorf("base repo was not initialized")
if c.baseRepo != nil {
return c.baseRepo, nil
}
return c.baseRepo, nil
remotes, err := c.Remotes()
if err != nil {
return nil, err
}
if len(remotes) < 1 {
return nil, fmt.Errorf("remotes are empty")
}
return remotes[0], nil
}
func (c *blankContext) SetBaseRepo(nwo string) {

View file

@ -206,6 +206,34 @@ func LocalBranches() ([]string, error) {
return branches, nil
}
var GitCommand = func(args ...string) *exec.Cmd {
return exec.Command("git", args...)
}
func UncommittedChangeCount() (int, error) {
statusCmd := GitCommand("status", "--porcelain")
output, err := utils.PrepareCmd(statusCmd).Output()
if err != nil {
return 0, err
}
lines := strings.Split(string(output), "\n")
count := 0
for _, l := range lines {
if l != "" {
count++
}
}
return count, nil
}
func Push(remote string, ref string) error {
cmd := GitCommand("push", "--set-upstream", remote, ref)
return cmd.Run()
}
func outputLines(output []byte) []string {
lines := strings.TrimSuffix(string(output), "\n")
return strings.Split(lines, "\n")

57
git/git_test.go Normal file
View file

@ -0,0 +1,57 @@
package git
import (
"fmt"
"os"
"strings"
"testing"
"github.com/github/gh-cli/test"
)
func TestGitStatusHelperProcess(*testing.T) {
if test.SkipTestHelperProcess() {
return
}
args := test.GetTestHelperProcessArgs()
switch args[0] {
case "no changes":
case "one change":
fmt.Println(" M poem.txt")
case "untracked file":
fmt.Println(" M poem.txt")
fmt.Println("?? new.txt")
case "boom":
os.Exit(1)
}
os.Exit(0)
}
func Test_UncommittedChangeCount(t *testing.T) {
origGitCommand := GitCommand
defer func() {
GitCommand = origGitCommand
}()
cases := map[string]int{
"no changes": 0,
"one change": 1,
"untracked file": 2,
}
for k, v := range cases {
GitCommand = test.StubExecCommand("TestGitStatusHelperProcess", k)
ucc, _ := UncommittedChangeCount()
if ucc != v {
t.Errorf("got unexpected ucc value: %d for case %s", ucc, k)
}
}
GitCommand = test.StubExecCommand("TestGitStatusHelperProcess", "boom")
_, err := UncommittedChangeCount()
if !strings.HasSuffix(err.Error(), "git.test: exit status 1") {
t.Errorf("got unexpected error message: %s", err)
}
}

5
go.mod
View file

@ -3,12 +3,15 @@ module github.com/github/gh-cli
go 1.13
require (
github.com/AlecAivazis/survey/v2 v2.0.4
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/mattn/go-colorable v0.1.2
github.com/mattn/go-isatty v0.0.9
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b
github.com/mitchellh/go-homedir v1.1.0
github.com/pkg/errors v0.8.1
github.com/spf13/cobra v0.0.5
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9
github.com/stretchr/testify v1.3.0 // indirect
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5
gopkg.in/yaml.v3 v3.0.0-20191010095647-fc94e3f71652
)

22
go.sum
View file

@ -1,18 +1,27 @@
github.com/AlecAivazis/survey/v2 v2.0.4 h1:qzXnJSzXEvmUllWqMBWpZndvT2YfoAUzAMvZUax3L2M=
github.com/AlecAivazis/survey/v2 v2.0.4/go.mod h1:WYBhg6f0y/fNYUuesWQc0PKbJcEliGcYHB9sNT3Bg74=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ=
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@ -25,6 +34,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@ -36,13 +47,24 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

9
test/fixtures/createPr.json vendored Normal file
View file

@ -0,0 +1,9 @@
{
"data": {
"createPullRequest": {
"pullRequest": {
"url": "https://github.com/vilmibm/testing/pull/14"
}
}
}
}

7
test/fixtures/repoId.json vendored Normal file
View file

@ -0,0 +1,7 @@
{
"data": {
"repository": {
"id": "a repo id"
}
}
}

View file

@ -11,6 +11,38 @@ import (
"github.com/spf13/cobra"
)
func GetTestHelperProcessArgs() []string {
args := os.Args
for len(args) > 0 {
if args[0] == "--" {
args = args[1:]
break
}
args = args[1:]
}
return args
}
func SkipTestHelperProcess() bool {
return os.Getenv("GO_WANT_HELPER_PROCESS") != "1"
}
func StubExecCommand(testHelper string, desiredOutput string) func(...string) *exec.Cmd {
return func(args ...string) *exec.Cmd {
cs := []string{
fmt.Sprintf("-test.run=%s", testHelper),
"--", desiredOutput}
cs = append(cs, args...)
env := []string{
"GO_WANT_HELPER_PROCESS=1",
}
cmd := exec.Command(os.Args[0], cs...)
cmd.Env = append(env, os.Environ()...)
return cmd
}
}
type TempGitRepo struct {
Remote string
TearDown func()