diff --git a/pkg/cmd/pr/create/create_test.go b/pkg/cmd/pr/create/create_test.go index 6b79551bf..f3426702f 100644 --- a/pkg/cmd/pr/create/create_test.go +++ b/pkg/cmd/pr/create/create_test.go @@ -5,6 +5,8 @@ import ( "encoding/json" "io/ioutil" "net/http" + "os" + "path" "reflect" "strings" "testing" @@ -314,7 +316,7 @@ func TestPRCreate_nonLegacyTemplate(t *testing.T) { eq(t, reqBody.Variables.Input.RepositoryID, "REPOID") eq(t, reqBody.Variables.Input.Title, "my title") - eq(t, reqBody.Variables.Input.Body, "Fixes a bug and Closes an issue") + eq(t, reqBody.Variables.Input.Body, "- commit 1\n- commit 0\n\nFixes a bug and Closes an issue") eq(t, reqBody.Variables.Input.BaseRefName, "master") eq(t, reqBody.Variables.Input.HeadRefName, "feature") @@ -851,6 +853,77 @@ func TestPRCreate_survey_defaults_monocommit(t *testing.T) { eq(t, output.String(), "https://github.com/OWNER/REPO/pull/12\n") } +func TestPRCreate_survey_defaults_monocommit_template(t *testing.T) { + http := initFakeHTTP() + defer http.Verify(t) + + http.Register(httpmock.GraphQL(`query RepositoryNetwork\b`), httpmock.StringResponse(httpmock.RepoNetworkStubResponse("OWNER", "REPO", "master", "WRITE"))) + http.Register(httpmock.GraphQL(`query RepositoryFindFork\b`), httpmock.StringResponse(` + { "data": { "repository": { "forks": { "nodes": [ + ] } } } } + `)) + http.Register(httpmock.GraphQL(`query PullRequestForBranch\b`), httpmock.StringResponse(` + { "data": { "repository": { "pullRequests": { "nodes" : [ + ] } } } } + `)) + http.Register(httpmock.GraphQL(`mutation PullRequestCreate\b`), httpmock.GraphQLMutation(` + { "data": { "createPullRequest": { "pullRequest": { + "URL": "https://github.com/OWNER/REPO/pull/12" + } } } } + `, func(inputs map[string]interface{}) { + eq(t, inputs["repositoryId"], "REPOID") + eq(t, inputs["title"], "the sky above the port") + eq(t, inputs["body"], "was the color of a television\n\n... turned to a dead channel") + eq(t, inputs["baseRefName"], "master") + eq(t, inputs["headRefName"], "feature") + })) + + cs, cmdTeardown := test.InitCmdStubber() + defer cmdTeardown() + + tmpdir, err := ioutil.TempDir("", "gh-cli") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + templateFp := path.Join(tmpdir, ".github/PULL_REQUEST_TEMPLATE.md") + _ = os.MkdirAll(path.Dir(templateFp), 0700) + _ = ioutil.WriteFile(templateFp, []byte("... turned to a dead channel"), 0700) + + cs.Stub("") // git config --get-regexp (determineTrackingBranch) + cs.Stub("") // git show-ref --verify (determineTrackingBranch) + cs.Stub("") // git status + cs.Stub("1234567890,the sky above the port") // git log + cs.Stub("was the color of a television") // git show + cs.Stub(tmpdir) // git rev-parse + cs.Stub("") // git push + + as, surveyTeardown := prompt.InitAskStubber() + defer surveyTeardown() + + as.Stub([]*prompt.QuestionStub{ + { + Name: "title", + Default: true, + }, + { + Name: "body", + Default: true, + }, + }) + as.Stub([]*prompt.QuestionStub{ + { + Name: "confirmation", + Value: 0, + }, + }) + + output, err := runCommand(http, nil, "feature", true, ``) + eq(t, err, nil) + eq(t, output.String(), "https://github.com/OWNER/REPO/pull/12\n") +} + func TestPRCreate_survey_autofill_nontty(t *testing.T) { http := initFakeHTTP() defer http.Verify(t) diff --git a/pkg/cmd/pr/shared/title_body_survey.go b/pkg/cmd/pr/shared/title_body_survey.go index 3afeba803..83a50e0ff 100644 --- a/pkg/cmd/pr/shared/title_body_survey.go +++ b/pkg/cmd/pr/shared/title_body_survey.go @@ -2,6 +2,7 @@ package shared import ( "fmt" + "strings" "github.com/AlecAivazis/survey/v2" "github.com/cli/cli/api" @@ -154,18 +155,26 @@ func TitleBodySurvey(io *iostreams.IOStreams, editorCommand string, issueState * templateContents := "" if providedBody == "" { + issueState.Body = defs.Body + if len(nonLegacyTemplatePaths) > 0 { var err error templateContents, err = selectTemplate(nonLegacyTemplatePaths, legacyTemplatePath, issueState.Type) if err != nil { return err } - issueState.Body = templateContents + } else if legacyTemplatePath != nil { templateContents = string(githubtemplate.ExtractContents(*legacyTemplatePath)) - issueState.Body = templateContents - } else { - issueState.Body = defs.Body + } + + if templateContents != "" { + if issueState.Body != "" { + // prevent excessive newlines between default body and template + issueState.Body = strings.TrimRight(issueState.Body, "\n") + issueState.Body += "\n\n" + } + issueState.Body += templateContents } }