Merge pull request #8423 from guerinoni/autofill-with-body

autofill with body
This commit is contained in:
Andy Feller 2024-02-01 15:17:01 -05:00 committed by GitHub
commit 201842d75c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 240 additions and 154 deletions

View file

@ -227,8 +227,14 @@ func (c *Client) UncommittedChangeCount(ctx context.Context) (int, error) {
return count, nil
}
func isGitSha(s string) bool {
shaRegex := regexp.MustCompile(`^[0-9a-fA-F]{7,40}$`)
ret := shaRegex.MatchString(s)
return ret
}
func (c *Client) Commits(ctx context.Context, baseRef, headRef string) ([]*Commit, error) {
args := []string{"-c", "log.ShowSignature=false", "log", "--pretty=format:%H,%s", "--cherry", fmt.Sprintf("%s...%s", baseRef, headRef)}
args := []string{"-c", "log.ShowSignature=false", "log", "--pretty=format:%H,%s,%b", "--cherry", fmt.Sprintf("%s...%s", baseRef, headRef)}
cmd, err := c.Command(ctx, args...)
if err != nil {
return nil, err
@ -240,15 +246,39 @@ func (c *Client) Commits(ctx context.Context, baseRef, headRef string) ([]*Commi
commits := []*Commit{}
sha := 0
title := 1
for _, line := range outputLines(out) {
split := strings.SplitN(line, ",", 2)
if len(split) != 2 {
continue
body := 2
lines := outputLines(out)
for i := 0; i < len(lines); i++ {
split := strings.SplitN(lines[i], ",", 3)
if isGitSha(split[sha]) {
c := &Commit{
Sha: split[sha],
Title: split[title],
}
if len(split) == 2 {
commits = append(commits, c)
continue
}
c.Body = split[body]
// This consumes all lines until the next commit and adds them to the body.
for {
i++
if i >= len(lines) {
break
}
possibleSplit := strings.SplitN(lines[i], ",", 3)
if len(possibleSplit) > 2 && isGitSha(possibleSplit[sha]) {
i--
break
}
c.Body += "\n"
c.Body += lines[i]
}
commits = append(commits, c)
}
commits = append(commits, &Commit{
Sha: split[sha],
Title: split[title],
})
}
if len(commits) == 0 {
return nil, fmt.Errorf("could not find any commits between %s and %s", baseRef, headRef)

View file

@ -471,22 +471,32 @@ func TestClientCommits(t *testing.T) {
{
name: "get commits",
cmdStdout: "6a6872b918c601a0e730710ad8473938a7516d30,testing testability test",
wantCmdArgs: `path/to/git -c log.ShowSignature=false log --pretty=format:%H,%s --cherry SHA1...SHA2`,
wantCmdArgs: `path/to/git -c log.ShowSignature=false log --pretty=format:%H,%s,%b --cherry SHA1...SHA2`,
wantCommits: []*Commit{{
Sha: "6a6872b918c601a0e730710ad8473938a7516d30",
Title: "testing testability test",
}},
},
{
name: "get commits with body",
cmdStdout: "6a6872b918c601a0e730710ad8473938a7516d30,testing testability test,This is the body",
wantCmdArgs: `path/to/git -c log.ShowSignature=false log --pretty=format:%H,%s,%b --cherry SHA1...SHA2`,
wantCommits: []*Commit{{
Sha: "6a6872b918c601a0e730710ad8473938a7516d30",
Title: "testing testability test",
Body: "This is the body",
}},
},
{
name: "no commits between SHAs",
wantCmdArgs: `path/to/git -c log.ShowSignature=false log --pretty=format:%H,%s --cherry SHA1...SHA2`,
wantCmdArgs: `path/to/git -c log.ShowSignature=false log --pretty=format:%H,%s,%b --cherry SHA1...SHA2`,
wantErrorMsg: "could not find any commits between SHA1 and SHA2",
},
{
name: "git error",
cmdExitStatus: 1,
cmdStderr: "git error message",
wantCmdArgs: `path/to/git -c log.ShowSignature=false log --pretty=format:%H,%s --cherry SHA1...SHA2`,
wantCmdArgs: `path/to/git -c log.ShowSignature=false log --pretty=format:%H,%s,%b --cherry SHA1...SHA2`,
wantErrorMsg: "failed to run git: git error message",
},
}

View file

@ -67,6 +67,7 @@ func (r TrackingRef) String() string {
type Commit struct {
Sha string
Title string
Body string
}
type BranchConfig struct {

View file

@ -45,6 +45,7 @@ type CreateOptions struct {
RepoOverride string
Autofill bool
FillVerbose bool
FillFirst bool
WebMode bool
RecoverFile string
@ -163,6 +164,14 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
return cmdutil.FlagErrorf("`--fill` is not supported with `--fill-first`")
}
if opts.FillVerbose && opts.FillFirst {
return cmdutil.FlagErrorf("`--fill-verbose` is not supported with `--fill-first`")
}
if opts.FillVerbose && opts.Autofill {
return cmdutil.FlagErrorf("`--fill-verbose` is not supported with `--fill`")
}
opts.BodyProvided = cmd.Flags().Changed("body")
if bodyFile != "" {
b, err := cmdutil.ReadFile(bodyFile, opts.IO.In)
@ -177,8 +186,8 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
return cmdutil.FlagErrorf("`--template` is not supported when using `--body` or `--body-file`")
}
if !opts.IO.CanPrompt() && !opts.WebMode && !(opts.Autofill || opts.FillFirst) && (!opts.TitleProvided || !opts.BodyProvided) {
return cmdutil.FlagErrorf("must provide `--title` and `--body` (or `--fill` or `fill-first`) when not running interactively")
if !opts.IO.CanPrompt() && !opts.WebMode && !(opts.FillVerbose || opts.Autofill || opts.FillFirst) && (!opts.TitleProvided || !opts.BodyProvided) {
return cmdutil.FlagErrorf("must provide `--title` and `--body` (or `--fill` or `fill-first` or `--fillverbose`) when not running interactively")
}
if runF != nil {
@ -196,6 +205,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
fl.StringVarP(&opts.BaseBranch, "base", "B", "", "The `branch` into which you want your code merged")
fl.StringVarP(&opts.HeadBranch, "head", "H", "", "The `branch` that contains commits for your pull request (default: current branch)")
fl.BoolVarP(&opts.WebMode, "web", "w", false, "Open the web browser to create a pull request")
fl.BoolVarP(&opts.FillVerbose, "fill-verbose", "", false, "Use commits msg+body for description")
fl.BoolVarP(&opts.Autofill, "fill", "f", false, "Use commit info for title and body")
fl.BoolVar(&opts.FillFirst, "fill-first", false, "Use first commit info for title and body")
fl.StringSliceVarP(&opts.Reviewers, "reviewer", "r", nil, "Request reviews from people or teams by their `handle`")
@ -292,7 +302,7 @@ func createRun(opts *CreateOptions) (err error) {
ghrepo.FullName(ctx.BaseRepo))
}
if opts.Autofill || opts.FillFirst || (opts.TitleProvided && opts.BodyProvided) {
if opts.FillVerbose || opts.Autofill || opts.FillFirst || (opts.TitleProvided && opts.BodyProvided) {
err = handlePush(*opts, *ctx)
if err != nil {
return
@ -403,7 +413,9 @@ func createRun(opts *CreateOptions) (err error) {
return
}
func initDefaultTitleBody(ctx CreateContext, state *shared.IssueMetadataState, useFirstCommit bool) error {
var regexPattern = regexp.MustCompile(`(?m)^`)
func initDefaultTitleBody(ctx CreateContext, state *shared.IssueMetadataState, useFirstCommit bool, addBody bool) error {
baseRef := ctx.BaseTrackingBranch
headRef := ctx.HeadBranch
gitClient := ctx.GitClient
@ -412,19 +424,24 @@ func initDefaultTitleBody(ctx CreateContext, state *shared.IssueMetadataState, u
if err != nil {
return err
}
if len(commits) == 1 || useFirstCommit {
commitIndex := len(commits) - 1
state.Title = commits[commitIndex].Title
body, err := gitClient.CommitBody(context.Background(), commits[commitIndex].Sha)
if err != nil {
return err
}
state.Body = body
if useFirstCommit {
state.Title = commits[len(commits)-1].Title
state.Body = commits[len(commits)-1].Body
} else {
state.Title = humanize(headRef)
var body strings.Builder
for i := len(commits) - 1; i >= 0; i-- {
fmt.Fprintf(&body, "- %s\n", commits[i].Title)
fmt.Fprintf(&body, "- **%s**\n", commits[i].Title)
if addBody {
x := regexPattern.ReplaceAllString(commits[i].Body, " ")
fmt.Fprintf(&body, "%s", x)
if i > 0 {
fmt.Fprintln(&body)
fmt.Fprintln(&body)
}
}
}
state.Body = body.String()
}
@ -495,9 +512,9 @@ func NewIssueState(ctx CreateContext, opts CreateOptions) (*shared.IssueMetadata
Draft: opts.IsDraft,
}
if opts.Autofill || opts.FillFirst || !opts.TitleProvided || !opts.BodyProvided {
err := initDefaultTitleBody(ctx, state, opts.FillFirst)
if err != nil && (opts.Autofill || opts.FillFirst) {
if opts.FillVerbose || opts.Autofill || opts.FillFirst || !opts.TitleProvided || !opts.BodyProvided {
err := initDefaultTitleBody(ctx, state, opts.FillFirst, opts.FillVerbose)
if err != nil && (opts.FillVerbose || opts.Autofill || opts.FillFirst) {
return nil, fmt.Errorf("could not compute title or body defaults: %w", err)
}
}
@ -659,7 +676,6 @@ func NewCreateContext(opts *CreateOptions) (*CreateContext, error) {
Client: client,
GitClient: gitClient,
}, nil
}
func getRemotes(opts *CreateOptions) (ghContext.Remotes, error) {
@ -716,7 +732,6 @@ func previewPR(opts CreateOptions, openURL string) error {
fmt.Fprintf(opts.IO.ErrOut, "Opening %s in your browser.\n", text.DisplayURL(openURL))
}
return opts.Browser.Browse(openURL)
}
func handlePush(opts CreateOptions, ctx CreateContext) error {

View file

@ -279,9 +279,9 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }`,
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }`,
func(input map[string]interface{}) {
assert.Equal(t, "REPOID", input["repositoryId"])
assert.Equal(t, "my title", input["title"])
@ -318,9 +318,9 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }`, func(input map[string]interface{}) {
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }`, func(input map[string]interface{}) {
assert.Equal(t, "REPOID", input["repositoryId"].(string))
assert.Equal(t, "my title", input["title"].(string))
assert.Equal(t, "my body", input["body"].(string))
@ -366,11 +366,11 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{ "data": { "createPullRequest": { "pullRequest": {
"id": "PullRequest#1",
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
{ "data": { "createPullRequest": { "pullRequest": {
"id": "PullRequest#1",
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
assert.Equal(t, "REPOID", input["repositoryId"].(string))
assert.Equal(t, "my title", input["title"].(string))
assert.Equal(t, "my body", input["body"].(string))
@ -381,10 +381,10 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`mutation UpdateProjectV2Items\b`),
httpmock.GraphQLQuery(`
{ "data": { "add_000": { "item": {
"id": "1"
} } } }
`, func(mutations string, inputs map[string]interface{}) {
{ "data": { "add_000": { "item": {
"id": "1"
} } } }
`, func(mutations string, inputs map[string]interface{}) {
variables, err := json.Marshal(inputs)
assert.NoError(t, err)
expectedMutations := "mutation UpdateProjectV2Items($input_000: AddProjectV2ItemByIdInput!) {add_000: addProjectV2ItemById(input: $input_000) { item { id } }}"
@ -428,10 +428,10 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
assert.Equal(t, false, input["maintainerCanModify"].(bool))
assert.Equal(t, "REPOID", input["repositoryId"].(string))
assert.Equal(t, "my title", input["title"].(string))
@ -475,16 +475,16 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.REST("POST", "repos/OWNER/REPO/forks"),
httpmock.StatusStringResponse(201, `
{ "node_id": "NODEID",
"name": "REPO",
"owner": {"login": "monalisa"}
}`))
{ "node_id": "NODEID",
"name": "REPO",
"owner": {"login": "monalisa"}
}`))
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
}}}}`, func(input map[string]interface{}) {
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
}}}}`, func(input map[string]interface{}) {
assert.Equal(t, "REPOID", input["repositoryId"].(string))
assert.Equal(t, "master", input["baseRefName"].(string))
assert.Equal(t, "monalisa:feature", input["headRefName"].(string))
@ -541,9 +541,9 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }`, func(input map[string]interface{}) {
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }`, func(input map[string]interface{}) {
assert.Equal(t, "REPOID", input["repositoryId"].(string))
assert.Equal(t, "master", input["baseRefName"].(string))
assert.Equal(t, "monalisa:feature", input["headRefName"].(string))
@ -552,9 +552,9 @@ func Test_createRun(t *testing.T) {
cmdStubs: func(cs *run.CommandStubber) {
cs.Register(`git config --get-regexp \^branch\\\.feature\\\.`, 1, "") // determineTrackingBranch
cs.Register("git show-ref --verify", 0, heredoc.Doc(`
deadbeef HEAD
deadb00f refs/remotes/upstream/feature
deadbeef refs/remotes/origin/feature`)) // determineTrackingBranch
deadbeef HEAD
deadb00f refs/remotes/upstream/feature
deadbeef refs/remotes/origin/feature`)) // determineTrackingBranch
},
expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
expectedErrOut: "\nCreating pull request for monalisa:feature into master in OWNER/REPO\n\n",
@ -573,10 +573,10 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
assert.Equal(t, "REPOID", input["repositoryId"].(string))
assert.Equal(t, "master", input["baseRefName"].(string))
assert.Equal(t, "my-feat2", input["headRefName"].(string))
@ -584,13 +584,13 @@ func Test_createRun(t *testing.T) {
},
cmdStubs: func(cs *run.CommandStubber) {
cs.Register(`git config --get-regexp \^branch\\\.feature\\\.`, 0, heredoc.Doc(`
branch.feature.remote origin
branch.feature.merge refs/heads/my-feat2
`)) // determineTrackingBranch
branch.feature.remote origin
branch.feature.merge refs/heads/my-feat2
`)) // determineTrackingBranch
cs.Register("git show-ref --verify", 0, heredoc.Doc(`
deadbeef HEAD
deadbeef refs/remotes/origin/my-feat2
`)) // determineTrackingBranch
deadbeef HEAD
deadbeef refs/remotes/origin/my-feat2
`)) // determineTrackingBranch
},
expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
expectedErrOut: "\nCreating pull request for my-feat2 into master in OWNER/REPO\n\n",
@ -609,25 +609,25 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`query PullRequestTemplates\b`),
httpmock.StringResponse(`
{ "data": { "repository": { "pullRequestTemplates": [
{ "filename": "template1",
"body": "this is a bug" },
{ "filename": "template2",
"body": "this is a enhancement" }
] } } }`))
{ "data": { "repository": { "pullRequestTemplates": [
{ "filename": "template1",
"body": "this is a bug" },
{ "filename": "template2",
"body": "this is a enhancement" }
] } } }`))
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
assert.Equal(t, "my title", input["title"].(string))
assert.Equal(t, "- commit 1\n- commit 0\n\nthis is a bug", input["body"].(string))
assert.Equal(t, "- **commit 1**\n- **commit 0**\n\nthis is a bug", input["body"].(string))
}))
},
cmdStubs: func(cs *run.CommandStubber) {
cs.Register(`git( .+)? log( .+)? origin/master\.\.\.feature`, 0, "1234567890,commit 0\n2345678901,commit 1")
cs.Register(`git( .+)? log( .+)? origin/master\.\.\.feature`, 0, "d3476a1,commit 0\n7a6ea13,commit 1")
},
promptStubs: func(pm *prompter.PrompterMock) {
pm.MarkdownEditorFunc = func(p, d string, ba bool) (string, error) {
@ -671,39 +671,39 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`query RepositoryResolveMetadataIDs\b`),
httpmock.StringResponse(`
{ "data": {
"u000": { "login": "MonaLisa", "id": "MONAID" },
"u001": { "login": "hubot", "id": "HUBOTID" },
"repository": {
"l000": { "name": "bug", "id": "BUGID" },
"l001": { "name": "TODO", "id": "TODOID" }
},
"organization": {
"t000": { "slug": "core", "id": "COREID" },
"t001": { "slug": "robots", "id": "ROBOTID" }
}
} }
`))
{ "data": {
"u000": { "login": "MonaLisa", "id": "MONAID" },
"u001": { "login": "hubot", "id": "HUBOTID" },
"repository": {
"l000": { "name": "bug", "id": "BUGID" },
"l001": { "name": "TODO", "id": "TODOID" }
},
"organization": {
"t000": { "slug": "core", "id": "COREID" },
"t001": { "slug": "robots", "id": "ROBOTID" }
}
} }
`))
reg.Register(
httpmock.GraphQL(`query RepositoryMilestoneList\b`),
httpmock.StringResponse(`
{ "data": { "repository": { "milestones": {
"nodes": [
{ "title": "GA", "id": "GAID" },
{ "title": "Big One.oh", "id": "BIGONEID" }
],
"pageInfo": { "hasNextPage": false }
} } } }
`))
{ "data": { "repository": { "milestones": {
"nodes": [
{ "title": "GA", "id": "GAID" },
{ "title": "Big One.oh", "id": "BIGONEID" }
],
"pageInfo": { "hasNextPage": false }
} } } }
`))
mockRetrieveProjects(t, reg)
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{ "data": { "createPullRequest": { "pullRequest": {
"id": "NEWPULLID",
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(inputs map[string]interface{}) {
{ "data": { "createPullRequest": { "pullRequest": {
"id": "NEWPULLID",
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(inputs map[string]interface{}) {
assert.Equal(t, "TITLE", inputs["title"])
assert.Equal(t, "BODY", inputs["body"])
if v, ok := inputs["assigneeIds"]; ok {
@ -716,10 +716,10 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreateMetadata\b`),
httpmock.GraphQLMutation(`
{ "data": { "updatePullRequest": {
"clientMutationId": ""
} } }
`, func(inputs map[string]interface{}) {
{ "data": { "updatePullRequest": {
"clientMutationId": ""
} } }
`, func(inputs map[string]interface{}) {
assert.Equal(t, "NEWPULLID", inputs["pullRequestId"])
assert.Equal(t, []interface{}{"MONAID"}, inputs["assigneeIds"])
assert.Equal(t, []interface{}{"BUGID", "TODOID"}, inputs["labelIds"])
@ -729,10 +729,10 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreateRequestReviews\b`),
httpmock.GraphQLMutation(`
{ "data": { "requestReviews": {
"clientMutationId": ""
} } }
`, func(inputs map[string]interface{}) {
{ "data": { "requestReviews": {
"clientMutationId": ""
} } }
`, func(inputs map[string]interface{}) {
assert.Equal(t, "NEWPULLID", inputs["pullRequestId"])
assert.Equal(t, []interface{}{"HUBOTID", "MONAID"}, inputs["userIds"])
assert.Equal(t, []interface{}{"COREID", "ROBOTID"}, inputs["teamIds"])
@ -807,7 +807,6 @@ func Test_createRun(t *testing.T) {
cs.Register(`git show-ref --verify -- HEAD refs/remotes/origin/feature`, 0, "")
cs.Register(`git( .+)? log( .+)? origin/master\.\.\.feature`, 0, "")
cs.Register(`git push --set-upstream origin HEAD:refs/heads/feature`, 0, "")
},
promptStubs: func(pm *prompter.PrompterMock) {
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
@ -834,25 +833,25 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`query PullRequestTemplates\b`),
httpmock.StringResponse(`
{ "data": { "repository": { "pullRequestTemplates": [
{ "filename": "template1",
"body": "this is a bug" },
{ "filename": "template2",
"body": "this is a enhancement" }
] } } }`),
{ "data": { "repository": { "pullRequestTemplates": [
{ "filename": "template1",
"body": "this is a bug" },
{ "filename": "template2",
"body": "this is a enhancement" }
] } } }`),
)
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
assert.Equal(t, true, input["draft"].(bool))
}))
},
cmdStubs: func(cs *run.CommandStubber) {
cs.Register(`git -c log.ShowSignature=false log --pretty=format:%H,%s --cherry origin/master...feature`, 0, "")
cs.Register(`git -c log.ShowSignature=false log --pretty=format:%H,%s,%b --cherry origin/master...feature`, 0, "")
cs.Register(`git rev-parse --show-toplevel`, 0, "")
},
promptStubs: func(pm *prompter.PrompterMock) {
@ -884,28 +883,28 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`query RepositoryResolveMetadataIDs\b`),
httpmock.StringResponse(`
{ "data": {
"u000": { "login": "jillValentine", "id": "JILLID" },
"repository": {},
"organization": {}
} }
`))
{ "data": {
"u000": { "login": "jillValentine", "id": "JILLID" },
"repository": {},
"organization": {}
} }
`))
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreateRequestReviews\b`),
httpmock.GraphQLMutation(`
{ "data": { "requestReviews": {
"clientMutationId": ""
} } }
`, func(inputs map[string]interface{}) {
{ "data": { "requestReviews": {
"clientMutationId": ""
} } }
`, func(inputs map[string]interface{}) {
assert.Equal(t, []interface{}{"JILLID"}, inputs["userIds"])
}))
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`, func(input map[string]interface{}) {
assert.Equal(t, "recovered title", input["title"].(string))
assert.Equal(t, "recovered body", input["body"].(string))
}))
@ -989,10 +988,10 @@ func Test_createRun(t *testing.T) {
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.StringResponse(`
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`))
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }
`))
},
expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
},
@ -1006,15 +1005,46 @@ func Test_createRun(t *testing.T) {
},
cmdStubs: func(cs *run.CommandStubber) {
cs.Register(
"git -c log.ShowSignature=false log --pretty=format:%H,%s --cherry origin/master...feature",
"git -c log.ShowSignature=false log --pretty=format:%H,%s,%b --cherry origin/master...feature",
0,
"56b6f8bb7c9e3a30093cd17e48934ce354148e80,second commit of pr\n"+
"343jdfe47c9e3a30093cd17e48934ce354148e80,first commit of pr",
"3a9b48085046d156c5acce8f3b3a0532cd706a4a,first commit of pr,first commit description\n",
)
},
httpStubs: func(reg *httpmock.Registry, t *testing.T) {
reg.Register(
httpmock.GraphQL(`mutation PullRequestCreate\b`),
httpmock.GraphQLMutation(`
{
"data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } }
}
`,
func(input map[string]interface{}) {
assert.Equal(t, "first commit of pr", input["title"], "pr title should be first commit message")
assert.Equal(t, "first commit description", input["body"], "pr body should be first commit description")
},
),
)
},
expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
expectedErrOut: "\nCreating pull request for feature into master in OWNER/REPO\n\n",
},
{
name: "fillverbose flag provided",
tty: true,
setup: func(opts *CreateOptions, t *testing.T) func() {
opts.FillVerbose = true
opts.HeadBranch = "feature"
return func() {}
},
cmdStubs: func(cs *run.CommandStubber) {
cs.Register(
"git -c log.ShowSignature=false show -s --pretty=format:%b 343jdfe47c9e3a30093cd17e48934ce354148e80",
"git -c log.ShowSignature=false log --pretty=format:%H,%s,%b --cherry origin/master...feature",
0,
"first commit description",
"56b6f8bb7c9e3a30093cd17e48934ce354148e80,second commit of pr,second commit description\n"+
"3a9b48085046d156c5acce8f3b3a0532cd706a4a,first commit of pr,first commit with super long description, with super long description, with super long description, with super long description.\n",
)
},
httpStubs: func(reg *httpmock.Registry, t *testing.T) {
@ -1028,8 +1058,8 @@ func Test_createRun(t *testing.T) {
}
`,
func(input map[string]interface{}) {
assert.Equal(t, "first commit of pr", input["title"], "pr title should be first commit message")
assert.Equal(t, "first commit description", input["body"], "pr body should be first commit description")
assert.Equal(t, "feature", input["title"], "pr title should be branch name")
assert.Equal(t, "- **first commit of pr**\n first commit with super long description, with super long description, with super long description, with super long description.\n\n- **second commit of pr**\n second commit description", input["body"], "pr body should be commits msg+body")
},
),
)