From 77a93ce2747f68ee377518625640affee96ecd16 Mon Sep 17 00:00:00 2001 From: Federico Guerinoni Date: Tue, 5 Dec 2023 22:55:48 +0100 Subject: [PATCH] pr: Add flag fillverbose This is used to fill the body of PR with all commits msg + body of every commits because there can be lot of useful information. Signed-off-by: Federico Guerinoni --- git/client.go | 2 +- git/client_test.go | 10 ++ pkg/cmd/pr/create/create.go | 88 ++++++++-- pkg/cmd/pr/create/create_test.go | 274 +++++++++++++++++-------------- 4 files changed, 234 insertions(+), 140 deletions(-) diff --git a/git/client.go b/git/client.go index ca004cdcec3..eeb34662995 100644 --- a/git/client.go +++ b/git/client.go @@ -242,7 +242,7 @@ func (c *Client) Commits(ctx context.Context, baseRef, headRef string) ([]*Commi title := 1 body := 2 for _, line := range outputLines(out) { - split := strings.Split(line, ",") + split := strings.SplitN(line, ",", 3) if len(split) < 2 { continue } diff --git a/git/client_test.go b/git/client_test.go index f11e4909821..a1183b08d26 100644 --- a/git/client_test.go +++ b/git/client_test.go @@ -477,6 +477,16 @@ func TestClientCommits(t *testing.T) { 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,%b --cherry SHA1...SHA2`, diff --git a/pkg/cmd/pr/create/create.go b/pkg/cmd/pr/create/create.go index 21cb419643d..ff35bae1916 100644 --- a/pkg/cmd/pr/create/create.go +++ b/pkg/cmd/pr/create/create.go @@ -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,40 @@ func createRun(opts *CreateOptions) (err error) { return } -func initDefaultTitleBody(ctx CreateContext, state *shared.IssueMetadataState, useFirstCommit bool) error { +func chunkString(s string, chunkSize int) []string { + var chunks []string + runes := []rune(s) + + if len(runes) == 0 { + return []string{s} + } + + for i := 0; i < len(runes); { + nn := i + chunkSize + fmt.Println(nn, i) + if nn > len(runes) { + chunks = append(chunks, string(runes[i:])) + return chunks + } + + if runes[nn-1] == ' ' { + chunks = append(chunks, string(runes[i:nn])) + } else { + // find the last space before the end of the chunk + for ; nn > i; nn-- { + if runes[nn] == ' ' { + break + } + } + chunks = append(chunks, string(runes[i:nn])) + } + + i += nn + } + return chunks +} + +func initDefaultTitleBody(ctx CreateContext, state *shared.IssueMetadataState, useFirstCommit bool, addBody bool) error { baseRef := ctx.BaseTrackingBranch headRef := ctx.HeadBranch gitClient := ctx.GitClient @@ -412,19 +455,32 @@ 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) + if addBody { + chunks := chunkString(commits[i].Body, 72) + for idx, chunk := range chunks { + if chunk[0] == ' ' { + chunk = chunk[1:] + } + fmt.Fprintf(&body, " %s", chunk) + if idx < len(chunks)-1 { + fmt.Fprintln(&body) + } + } + + if i > 0 { + fmt.Fprintln(&body) + fmt.Fprintln(&body) + } + } } state.Body = body.String() } @@ -495,9 +551,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 +715,6 @@ func NewCreateContext(opts *CreateOptions) (*CreateContext, error) { Client: client, GitClient: gitClient, }, nil - } func getRemotes(opts *CreateOptions) (ghContext.Remotes, error) { @@ -716,7 +771,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 { diff --git a/pkg/cmd/pr/create/create_test.go b/pkg/cmd/pr/create/create_test.go index a8c10057ae9..ab1ea923b5d 100644 --- a/pkg/cmd/pr/create/create_test.go +++ b/pkg/cmd/pr/create/create_test.go @@ -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,19 +609,19 @@ 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)) })) @@ -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: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", + "343jdfe47c9e3a30093cd17e48934ce354148e80,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"+ + "343jdfe47c9e3a30093cd17e48934ce354148e80,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,\n 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") }, ), )