use Prompter in pr create

Note that this isn't done; it's leaving the metadata piece alone until
better testing utils are in place
This commit is contained in:
vilmibm 2022-10-17 14:13:54 -07:00
parent 57fbe4f317
commit a3b1bb7fb2
5 changed files with 208 additions and 148 deletions

View file

@ -23,6 +23,7 @@ type CreateOptions struct {
IO *iostreams.IOStreams
BaseRepo func() (ghrepo.Interface, error)
Browser browser.Browser
Prompter prShared.Prompt
RootDirOverride string
@ -46,6 +47,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
HttpClient: f.HttpClient,
Config: f.Config,
Browser: f.Browser,
Prompter: f.Prompter,
}
var bodyFile string
@ -194,16 +196,10 @@ func createRun(opts *CreateOptions) (err error) {
var openURL string
if opts.Interactive {
var editorCommand string
editorCommand, err = cmdutil.DetermineEditor(opts.Config)
if err != nil {
return
}
defer prShared.PreserveInput(opts.IO, &tb, &err)()
if opts.Title == "" {
err = prShared.TitleSurvey(&tb)
err = prShared.TitleSurvey(opts.Prompter, &tb)
if err != nil {
return
}
@ -227,7 +223,7 @@ func createRun(opts *CreateOptions) (err error) {
}
}
err = prShared.BodySurvey(&tb, templateContent, editorCommand)
err = prShared.BodySurvey(opts.Prompter, &tb, templateContent)
if err != nil {
return
}
@ -239,7 +235,7 @@ func createRun(opts *CreateOptions) (err error) {
}
allowPreview := !tb.HasMetadata() && prShared.ValidURL(openURL)
action, err = prShared.ConfirmIssueSubmission(allowPreview, repo.ViewerCanTriage())
action, err = prShared.ConfirmIssueSubmission(opts.Prompter, allowPreview, repo.ViewerCanTriage())
if err != nil {
err = fmt.Errorf("unable to confirm: %w", err)
return
@ -257,7 +253,7 @@ func createRun(opts *CreateOptions) (err error) {
return
}
action, err = prShared.ConfirmIssueSubmission(!tb.HasMetadata(), false)
action, err = prShared.ConfirmIssueSubmission(opts.Prompter, !tb.HasMetadata(), false)
if err != nil {
return
}

View file

@ -15,6 +15,7 @@ import (
"github.com/cli/cli/v2/internal/browser"
"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/internal/prompter"
"github.com/cli/cli/v2/internal/run"
prShared "github.com/cli/cli/v2/pkg/cmd/pr/shared"
"github.com/cli/cli/v2/pkg/cmdutil"
@ -288,11 +289,11 @@ func Test_createRun(t *testing.T) {
/*** LEGACY TESTS ***/
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
return runCommandWithRootDirOverridden(rt, isTTY, cli, "")
func runCommand(rt http.RoundTripper, isTTY bool, cli string, pm *prompter.PrompterMock) (*test.CmdOut, error) {
return runCommandWithRootDirOverridden(rt, isTTY, cli, "", pm)
}
func runCommandWithRootDirOverridden(rt http.RoundTripper, isTTY bool, cli string, rootDir string) (*test.CmdOut, error) {
func runCommandWithRootDirOverridden(rt http.RoundTripper, isTTY bool, cli string, rootDir string, pm *prompter.PrompterMock) (*test.CmdOut, error) {
ios, _, stdout, stderr := iostreams.Test()
ios.SetStdoutTTY(isTTY)
ios.SetStdinTTY(isTTY)
@ -310,7 +311,8 @@ func runCommandWithRootDirOverridden(rt http.RoundTripper, isTTY bool, cli strin
BaseRepo: func() (ghrepo.Interface, error) {
return ghrepo.New("OWNER", "REPO"), nil
},
Browser: browser,
Browser: browser,
Prompter: pm,
}
cmd := NewCmdCreate(factory, func(opts *CreateOptions) error {
@ -361,7 +363,7 @@ func TestIssueCreate(t *testing.T) {
}),
)
output, err := runCommand(http, true, `-t hello -b "cash rules everything around me"`)
output, err := runCommand(http, true, `-t hello -b "cash rules everything around me"`, nil)
if err != nil {
t.Errorf("error running command `issue create`: %v", err)
}
@ -403,12 +405,28 @@ func TestIssueCreate_recover(t *testing.T) {
assert.Equal(t, []interface{}{"BUGID", "TODOID"}, inputs["labelIds"])
}))
//nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock
as := prompt.NewAskStubber(t)
as.StubPrompt("Title").AnswerDefault()
as.StubPrompt("Body").AnswerDefault()
as.StubPrompt("What's next?").AnswerWith("Submit")
pm := &prompter.PrompterMock{}
pm.InputFunc = func(p, d string) (string, error) {
if p == "Title" {
return d, nil
} else {
return "", prompter.NoSuchPromptErr(p)
}
}
pm.MarkdownEditorFunc = func(p, d string, ba bool) (string, error) {
if p == "Body" {
return d, nil
} else {
return "", prompter.NoSuchPromptErr(p)
}
}
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
if p == "What's next?" {
return prompter.IndexFor(opts, "Submit")
} else {
return -1, prompter.NoSuchPromptErr(p)
}
}
tmpfile, err := os.CreateTemp(t.TempDir(), "testrecover*")
assert.NoError(t, err)
@ -428,7 +446,7 @@ func TestIssueCreate_recover(t *testing.T) {
args := fmt.Sprintf("--recover '%s'", tmpfile.Name())
output, err := runCommandWithRootDirOverridden(http, true, args, "")
output, err := runCommandWithRootDirOverridden(http, true, args, "", pm)
if err != nil {
t.Errorf("error running command `issue create`: %v", err)
}
@ -474,13 +492,26 @@ func TestIssueCreate_nonLegacyTemplate(t *testing.T) {
//nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock
as := prompt.NewAskStubber(t)
// TODO fix
as.StubPrompt("Choose a template").AnswerWith("Submit a request")
as.StubPrompt("Body").AnswerDefault()
as.StubPrompt("What's next?").
AssertOptions([]string{"Submit", "Continue in browser", "Cancel"}).
AnswerWith("Submit")
output, err := runCommandWithRootDirOverridden(http, true, `-t hello`, "./fixtures/repoWithNonLegacyIssueTemplates")
pm := &prompter.PrompterMock{}
pm.MarkdownEditorFunc = func(p, d string, ba bool) (string, error) {
if p == "Body" {
return d, nil
} else {
return "", prompter.NoSuchPromptErr(p)
}
}
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
if p == "What's next?" {
return prompter.IndexFor(opts, "Submit")
} else {
return -1, prompter.NoSuchPromptErr(p)
}
}
output, err := runCommandWithRootDirOverridden(http, true, `-t hello`, "./fixtures/repoWithNonLegacyIssueTemplates", pm)
if err != nil {
t.Errorf("error running command `issue create`: %v", err)
}
@ -502,16 +533,26 @@ func TestIssueCreate_continueInBrowser(t *testing.T) {
} } }`),
)
//nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock
as := prompt.NewAskStubber(t)
as.StubPrompt("Title").AnswerWith("hello")
as.StubPrompt("What's next?").AnswerWith("Continue in browser")
pm := &prompter.PrompterMock{}
pm.InputFunc = func(p, d string) (string, error) {
if p == "Title" {
return "hello", nil
} else {
return "", prompter.NoSuchPromptErr(p)
}
}
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
if p == "What's next?" {
return prompter.IndexFor(opts, "Continue in browser")
} else {
return -1, prompter.NoSuchPromptErr(p)
}
}
_, cmdTeardown := run.Stub()
defer cmdTeardown(t)
output, err := runCommand(http, true, `-b body`)
output, err := runCommand(http, true, `-b body`, pm)
if err != nil {
t.Errorf("error running command `issue create`: %v", err)
}
@ -596,7 +637,7 @@ func TestIssueCreate_metadata(t *testing.T) {
}
}))
output, err := runCommand(http, true, `-t TITLE -b BODY -a monalisa -l bug -l todo -p roadmap -m 'big one.oh'`)
output, err := runCommand(http, true, `-t TITLE -b BODY -a monalisa -l bug -l todo -p roadmap -m 'big one.oh'`, nil)
if err != nil {
t.Errorf("error running command `issue create`: %v", err)
}
@ -617,7 +658,7 @@ func TestIssueCreate_disabledIssues(t *testing.T) {
} } }`),
)
_, err := runCommand(http, true, `-t heres -b johnny`)
_, err := runCommand(http, true, `-t heres -b johnny`, nil)
if err == nil || err.Error() != "the 'OWNER/REPO' repository has disabled issues" {
t.Errorf("error running command `issue create`: %v", err)
}
@ -668,7 +709,7 @@ func TestIssueCreate_AtMeAssignee(t *testing.T) {
assert.Equal(t, []interface{}{"MONAID", "SOMEID"}, inputs["assigneeIds"])
}))
output, err := runCommand(http, true, `-a @me -a someoneelse -t hello -b "cash rules everything around me"`)
output, err := runCommand(http, true, `-a @me -a someoneelse -t hello -b "cash rules everything around me"`, nil)
if err != nil {
t.Errorf("error running command `issue create`: %v", err)
}

View file

@ -10,7 +10,6 @@ import (
"strings"
"time"
"github.com/AlecAivazis/survey/v2"
"github.com/MakeNowJust/heredoc"
"github.com/cli/cli/v2/api"
ghContext "github.com/cli/cli/v2/context"
@ -22,14 +21,9 @@ import (
"github.com/cli/cli/v2/pkg/cmd/pr/shared"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/cli/cli/v2/pkg/prompt"
"github.com/spf13/cobra"
)
type iprompter interface {
Select(string, string, []string) (int, error)
}
type CreateOptions struct {
// This struct stores user input and factory functions
HttpClient func() (*http.Client, error)
@ -39,7 +33,7 @@ type CreateOptions struct {
Remotes func() (ghContext.Remotes, error)
Branch func() (string, error)
Browser browser.Browser
Prompter iprompter
Prompter shared.Prompt
Finder shared.PRFinder
TitleProvided bool
@ -276,17 +270,12 @@ func createRun(opts *CreateOptions) (err error) {
}
if !opts.TitleProvided {
err = shared.TitleSurvey(state)
err = shared.TitleSurvey(opts.Prompter, state)
if err != nil {
return
}
}
editorCommand, err := cmdutil.DetermineEditor(opts.Config)
if err != nil {
return
}
defer shared.PreserveInput(opts.IO, state, &err)()
if !opts.BodyProvided {
@ -306,7 +295,7 @@ func createRun(opts *CreateOptions) (err error) {
}
}
err = shared.BodySurvey(state, templateContent, editorCommand)
err = shared.BodySurvey(opts.Prompter, state, templateContent)
if err != nil {
return
}
@ -319,7 +308,7 @@ func createRun(opts *CreateOptions) (err error) {
allowPreview := !state.HasMetadata() && shared.ValidURL(openURL)
allowMetadata := ctx.BaseRepo.ViewerCanTriage()
action, err := shared.ConfirmPRSubmission(allowPreview, allowMetadata, state.Draft)
action, err := shared.ConfirmPRSubmission(opts.Prompter, allowPreview, allowMetadata, state.Draft)
if err != nil {
return fmt.Errorf("unable to confirm: %w", err)
}
@ -336,7 +325,7 @@ func createRun(opts *CreateOptions) (err error) {
return
}
action, err = shared.ConfirmPRSubmission(!state.HasMetadata(), false, state.Draft)
action, err = shared.ConfirmPRSubmission(opts.Prompter, !state.HasMetadata(), false, state.Draft)
if err != nil {
return
}
@ -577,12 +566,7 @@ func NewCreateContext(opts *CreateOptions) (*CreateContext, error) {
pushOptions = append(pushOptions, "Skip pushing the branch")
pushOptions = append(pushOptions, "Cancel")
var selectedOption int
//nolint:staticcheck // SA1019: prompt.SurveyAskOne is deprecated: use Prompter
err = prompt.SurveyAskOne(&survey.Select{
Message: fmt.Sprintf("Where should we push the '%s' branch?", headBranch),
Options: pushOptions,
}, &selectedOption)
selectedOption, err := opts.Prompter.Select(fmt.Sprintf("Where should we push the '%s' branch?", headBranch), "", pushOptions)
if err != nil {
return nil, err
}

View file

@ -15,6 +15,7 @@ import (
"github.com/cli/cli/v2/internal/browser"
"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/internal/prompter"
"github.com/cli/cli/v2/internal/run"
"github.com/cli/cli/v2/pkg/cmd/pr/shared"
prShared "github.com/cli/cli/v2/pkg/cmd/pr/shared"
@ -188,6 +189,7 @@ func Test_createRun(t *testing.T) {
setup func(*CreateOptions, *testing.T) func()
cmdStubs func(*run.CommandStubber)
askStubs func(*prompt.AskStubber) // TODO eventually migrate to PrompterMock
promptStubs func(*prompter.PrompterMock)
httpStubs func(*httpmock.Registry, *testing.T)
expectedOut string
expectedErrOut string
@ -268,8 +270,14 @@ func Test_createRun(t *testing.T) {
cs.Register(`git show-ref --verify -- HEAD refs/remotes/origin/feature`, 0, "")
cs.Register(`git push --set-upstream origin HEAD:feature`, 0, "")
},
askStubs: func(as *prompt.AskStubber) {
as.StubPrompt("Where should we push the 'feature' branch?").AnswerDefault()
promptStubs: func(pm *prompter.PrompterMock) {
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
if p == "Where should we push the 'feature' branch?" {
return 0, nil
} else {
return -1, prompter.NoSuchPromptErr(p)
}
}
},
expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
expectedErrOut: "\nCreating pull request for feature into master in OWNER/REPO\n\n",
@ -309,8 +317,14 @@ func Test_createRun(t *testing.T) {
cs.Register(`git show-ref --verify -- HEAD refs/remotes/origin/feature`, 0, "")
cs.Register(`git push --set-upstream origin HEAD:feature`, 0, "")
},
askStubs: func(as *prompt.AskStubber) {
as.StubPrompt("Where should we push the 'feature' branch?").AnswerDefault()
promptStubs: func(pm *prompter.PrompterMock) {
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
if p == "Where should we push the 'feature' branch?" {
return 0, nil
} else {
return -1, prompter.NoSuchPromptErr(p)
}
}
},
expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
expectedErrOut: "\nCreating pull request for feature into master in OWNER/REPO\n\n",
@ -354,10 +368,14 @@ func Test_createRun(t *testing.T) {
cs.Register(`git remote add -f fork https://github.com/monalisa/REPO.git`, 0, "")
cs.Register(`git push --set-upstream fork HEAD:feature`, 0, "")
},
askStubs: func(as *prompt.AskStubber) {
as.StubPrompt("Where should we push the 'feature' branch?").
AssertOptions([]string{"OWNER/REPO", "Create a fork of OWNER/REPO", "Skip pushing the branch", "Cancel"}).
AnswerWith("Create a fork of OWNER/REPO")
promptStubs: func(pm *prompter.PrompterMock) {
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
if p == "Where should we push the 'feature' branch?" {
return prompter.IndexFor(opts, "Create a fork of OWNER/REPO")
} else {
return -1, prompter.NoSuchPromptErr(p)
}
}
},
expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
expectedErrOut: "\nCreating pull request for monalisa:feature into master in OWNER/REPO\n\n",
@ -486,10 +504,22 @@ func Test_createRun(t *testing.T) {
as.StubPrompt("Choose a template").
AssertOptions([]string{"template1", "template2", "Open a blank pull request"}).
AnswerWith("template1")
as.StubPrompt("Body").AnswerDefault()
as.StubPrompt("What's next?").
AssertOptions([]string{"Submit", "Submit as draft", "Continue in browser", "Add metadata", "Cancel"}).
AnswerDefault()
},
promptStubs: func(pm *prompter.PrompterMock) {
pm.MarkdownEditorFunc = func(p, d string, ba bool) (string, error) {
if p == "Body" {
return d, nil
} else {
return "", prompter.NoSuchPromptErr(p)
}
}
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
if p == "What's next?" {
return 0, nil
} else {
return -1, prompter.NoSuchPromptErr(p)
}
}
},
expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
expectedErrOut: "\nCreating pull request for feature into master in OWNER/REPO\n\n",
@ -636,10 +666,14 @@ func Test_createRun(t *testing.T) {
cs.Register(`git( .+)? log( .+)? origin/master\.\.\.feature`, 0, "")
cs.Register(`git push --set-upstream origin HEAD:feature`, 0, "")
},
askStubs: func(as *prompt.AskStubber) {
as.StubPrompt("Where should we push the 'feature' branch?").
AssertOptions([]string{"OWNER/REPO", "Skip pushing the branch", "Cancel"}).
AnswerDefault()
promptStubs: func(pm *prompter.PrompterMock) {
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
if p == "Where should we push the 'feature' branch?" {
return 0, nil
} else {
return -1, prompter.NoSuchPromptErr(p)
}
}
},
expectedErrOut: "Opening github.com/OWNER/REPO/compare/master...feature in your browser.\n",
expectedBrowse: "https://github.com/OWNER/REPO/compare/master...feature?body=&expand=1",
@ -685,8 +719,14 @@ func Test_createRun(t *testing.T) {
cs.Register(`git push --set-upstream origin HEAD:feature`, 0, "")
},
askStubs: func(as *prompt.AskStubber) {
as.StubPrompt("Where should we push the 'feature' branch?").AnswerDefault()
promptStubs: func(pm *prompter.PrompterMock) {
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
if p == "Where should we push the 'feature' branch?" {
return 0, nil
} else {
return -1, prompter.NoSuchPromptErr(p)
}
}
},
expectedErrOut: "Opening github.com/OWNER/REPO/compare/master...feature in your browser.\n",
expectedBrowse: "https://github.com/OWNER/REPO/compare/master...feature?body=&expand=1&projects=ORG%2F1",
@ -727,10 +767,22 @@ func Test_createRun(t *testing.T) {
},
askStubs: func(as *prompt.AskStubber) {
as.StubPrompt("Choose a template").AnswerDefault()
as.StubPrompt("Body").AnswerDefault()
as.StubPrompt("What's next?").
AssertOptions([]string{"Submit", "Submit as draft", "Continue in browser", "Add metadata", "Cancel"}).
AnswerWith("Submit as draft")
},
promptStubs: func(pm *prompter.PrompterMock) {
pm.MarkdownEditorFunc = func(p, d string, ba bool) (string, error) {
if p == "Body" {
return d, nil
} else {
return "", prompter.NoSuchPromptErr(p)
}
}
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
if p == "What's next?" {
return prompter.IndexFor(opts, "Submit as draft")
} else {
return -1, prompter.NoSuchPromptErr(p)
}
}
},
expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
expectedErrOut: "\nCreating pull request for feature into master in OWNER/REPO\n\n",
@ -771,10 +823,28 @@ func Test_createRun(t *testing.T) {
cmdStubs: func(cs *run.CommandStubber) {
cs.Register(`git( .+)? log( .+)? origin/master\.\.\.feature`, 0, "")
},
askStubs: func(as *prompt.AskStubber) {
as.StubPrompt("Title").AnswerDefault()
as.StubPrompt("Body").AnswerDefault()
as.StubPrompt("What's next?").AnswerDefault()
promptStubs: func(pm *prompter.PrompterMock) {
pm.InputFunc = func(p, d string) (string, error) {
if p == "Title" {
return d, nil
} else {
return "", prompter.NoSuchPromptErr(p)
}
}
pm.MarkdownEditorFunc = func(p, d string, ba bool) (string, error) {
if p == "Body" {
return d, nil
} else {
return "", prompter.NoSuchPromptErr(p)
}
}
pm.SelectFunc = func(p, _ string, opts []string) (int, error) {
if p == "What's next?" {
return 0, nil
} else {
return -1, prompter.NoSuchPromptErr(p)
}
}
},
setup: func(opts *CreateOptions, t *testing.T) func() {
tmpfile, err := os.CreateTemp(t.TempDir(), "testrecover*")
@ -830,6 +900,12 @@ func Test_createRun(t *testing.T) {
tt.askStubs(ask)
}
pm := &prompter.PrompterMock{}
if tt.promptStubs != nil {
tt.promptStubs(pm)
}
cs, cmdTeardown := run.Stub()
defer cmdTeardown(t)
cs.Register(`git status --porcelain`, 0, "")
@ -839,6 +915,7 @@ func Test_createRun(t *testing.T) {
}
opts := CreateOptions{}
opts.Prompter = pm
ios, _, stdout, stderr := iostreams.Test()
// TODO do i need to bother with this
@ -1064,3 +1141,5 @@ func Test_generateCompareURL(t *testing.T) {
})
}
}
// TODO interactive metadata tests once: 1) we have test utils for Prompter and 2) metadata questions use Prompter

View file

@ -9,7 +9,6 @@ import (
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/cli/cli/v2/pkg/prompt"
"github.com/cli/cli/v2/pkg/surveyext"
)
type Action int
@ -32,15 +31,21 @@ const (
cancelLabel = "Cancel"
)
func ConfirmIssueSubmission(allowPreview bool, allowMetadata bool) (Action, error) {
return confirmSubmission(allowPreview, allowMetadata, false, false)
type Prompt interface {
Input(string, string) (string, error)
Select(string, string, []string) (int, error)
MarkdownEditor(string, string, bool) (string, error)
}
func ConfirmPRSubmission(allowPreview, allowMetadata, isDraft bool) (Action, error) {
return confirmSubmission(allowPreview, allowMetadata, true, isDraft)
func ConfirmIssueSubmission(p Prompt, allowPreview bool, allowMetadata bool) (Action, error) {
return confirmSubmission(p, allowPreview, allowMetadata, false, false)
}
func confirmSubmission(allowPreview, allowMetadata, allowDraft, isDraft bool) (Action, error) {
func ConfirmPRSubmission(p Prompt, allowPreview, allowMetadata, isDraft bool) (Action, error) {
return confirmSubmission(p, allowPreview, allowMetadata, true, isDraft)
}
func confirmSubmission(p Prompt, allowPreview, allowMetadata, allowDraft, isDraft bool) (Action, error) {
var options []string
if !isDraft {
options = append(options, submitLabel)
@ -56,26 +61,12 @@ func confirmSubmission(allowPreview, allowMetadata, allowDraft, isDraft bool) (A
}
options = append(options, cancelLabel)
confirmAnswers := struct {
Confirmation int
}{}
confirmQs := []*survey.Question{
{
Name: "confirmation",
Prompt: &survey.Select{
Message: "What's next?",
Options: options,
},
},
}
//nolint:staticcheck // SA1019: prompt.SurveyAsk is deprecated: use Prompter
err := prompt.SurveyAsk(confirmQs, &confirmAnswers)
result, err := p.Select("What's next?", "", options)
if err != nil {
return -1, fmt.Errorf("could not prompt: %w", err)
}
switch options[confirmAnswers.Confirmation] {
switch options[result] {
case submitLabel:
return SubmitAction, nil
case submitDraftLabel:
@ -87,11 +78,11 @@ func confirmSubmission(allowPreview, allowMetadata, allowDraft, isDraft bool) (A
case cancelLabel:
return CancelAction, nil
default:
return -1, fmt.Errorf("invalid index: %d", confirmAnswers.Confirmation)
return -1, fmt.Errorf("invalid index: %d", result)
}
}
func BodySurvey(state *IssueMetadataState, templateContent, editorCommand string) error {
func BodySurvey(p Prompt, state *IssueMetadataState, templateContent string) error {
if templateContent != "" {
if state.Body != "" {
// prevent excessive newlines between default body and template
@ -101,63 +92,32 @@ func BodySurvey(state *IssueMetadataState, templateContent, editorCommand string
state.Body += templateContent
}
preBody := state.Body
// TODO should just be an AskOne but ran into problems with the stubber
qs := []*survey.Question{
{
Name: "Body",
Prompt: &surveyext.GhEditor{
BlankAllowed: true,
EditorCommand: editorCommand,
Editor: &survey.Editor{
Message: "Body",
FileName: "*.md",
Default: state.Body,
HideDefault: true,
AppendDefault: true,
},
},
},
}
//nolint:staticcheck // SA1019: prompt.SurveyAsk is deprecated: use Prompter
err := prompt.SurveyAsk(qs, state)
result, err := p.MarkdownEditor("Body", state.Body, true)
if err != nil {
return err
}
if preBody != state.Body {
if state.Body != result {
state.MarkDirty()
}
state.Body = result
return nil
}
func TitleSurvey(state *IssueMetadataState) error {
preTitle := state.Title
// TODO should just be an AskOne but ran into problems with the stubber
qs := []*survey.Question{
{
Name: "Title",
Prompt: &survey.Input{
Message: "Title",
Default: state.Title,
},
},
}
//nolint:staticcheck // SA1019: prompt.SurveyAsk is deprecated: use Prompter
err := prompt.SurveyAsk(qs, state)
func TitleSurvey(p Prompt, state *IssueMetadataState) error {
result, err := p.Input("Title", state.Title)
if err != nil {
return err
}
if preTitle != state.Title {
if result != state.Title {
state.MarkDirty()
}
state.Title = result
return nil
}