use Prompter in pr review

This commit is contained in:
vilmibm 2022-07-26 14:53:10 -05:00
parent 4afb567d06
commit 710212fb3d
2 changed files with 40 additions and 125 deletions

View file

@ -5,7 +5,6 @@ import (
"fmt"
"net/http"
"github.com/AlecAivazis/survey/v2"
"github.com/MakeNowJust/heredoc"
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/internal/config"
@ -13,8 +12,6 @@ import (
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/cli/cli/v2/pkg/markdown"
"github.com/cli/cli/v2/pkg/prompt"
"github.com/cli/cli/v2/pkg/surveyext"
"github.com/spf13/cobra"
)
@ -22,6 +19,7 @@ type ReviewOptions struct {
HttpClient func() (*http.Client, error)
Config func() (config.Config, error)
IO *iostreams.IOStreams
Prompter cmdutil.Prompter
Finder shared.PRFinder
@ -36,6 +34,7 @@ func NewCmdReview(f *cmdutil.Factory, runF func(*ReviewOptions) error) *cobra.Co
IO: f.IOStreams,
HttpClient: f.HttpClient,
Config: f.Config,
Prompter: f.Prompter,
}
var (
@ -160,7 +159,7 @@ func reviewRun(opts *ReviewOptions) error {
if err != nil {
return err
}
reviewData, err = reviewSurvey(opts.IO, editorCommand)
reviewData, err = reviewSurvey(opts, editorCommand)
if err != nil {
return err
}
@ -204,95 +203,51 @@ func reviewRun(opts *ReviewOptions) error {
return nil
}
func reviewSurvey(io *iostreams.IOStreams, editorCommand string) (*api.PullRequestReviewInput, error) {
typeAnswers := struct {
ReviewType string
}{}
typeQs := []*survey.Question{
{
Name: "reviewType",
Prompt: &survey.Select{
Message: "What kind of review do you want to give?",
Options: []string{
"Comment",
"Approve",
"Request changes",
},
},
},
}
err := prompt.SurveyAsk(typeQs, &typeAnswers)
func reviewSurvey(opts *ReviewOptions, editorCommand string) (*api.PullRequestReviewInput, error) {
reviewType, err := opts.Prompter.Select(
"What kind of review do you want to give?", "",
[]string{"Comment", "Approve", "Request Changes"})
if err != nil {
return nil, err
}
var reviewState api.PullRequestReviewState
switch typeAnswers.ReviewType {
case "Approve":
reviewState = api.ReviewApprove
case "Request changes":
reviewState = api.ReviewRequestChanges
case "Comment":
switch reviewType {
case 0:
reviewState = api.ReviewComment
case 1:
reviewState = api.ReviewApprove
case 2:
reviewState = api.ReviewRequestChanges
default:
panic("unreachable state")
}
bodyAnswers := struct {
Body string
}{}
blankAllowed := false
if reviewState == api.ReviewApprove {
blankAllowed = true
}
bodyQs := []*survey.Question{
{
Name: "body",
Prompt: &surveyext.GhEditor{
BlankAllowed: blankAllowed,
EditorCommand: editorCommand,
Editor: &survey.Editor{
Message: "Review body",
FileName: "*.md",
},
},
},
}
err = prompt.SurveyAsk(bodyQs, &bodyAnswers)
body, err := opts.Prompter.MarkdownEditor("Review body", "", blankAllowed)
if err != nil {
return nil, err
}
if bodyAnswers.Body == "" && (reviewState == api.ReviewComment || reviewState == api.ReviewRequestChanges) {
if body == "" && (reviewState == api.ReviewComment || reviewState == api.ReviewRequestChanges) {
return nil, errors.New("this type of review cannot be blank")
}
if len(bodyAnswers.Body) > 0 {
renderedBody, err := markdown.Render(bodyAnswers.Body, markdown.WithIO(io))
if len(body) > 0 {
renderedBody, err := markdown.Render(body, markdown.WithIO(opts.IO))
if err != nil {
return nil, err
}
fmt.Fprintf(io.Out, "Got:\n%s", renderedBody)
fmt.Fprintf(opts.IO.Out, "Got:\n%s", renderedBody)
}
confirm := false
confirmQs := []*survey.Question{
{
Name: "confirm",
Prompt: &survey.Confirm{
Message: "Submit?",
Default: true,
},
},
}
err = prompt.SurveyAsk(confirmQs, &confirm)
confirm, err := opts.Prompter.Confirm("Submit?", true)
if err != nil {
return nil, err
}
@ -302,7 +257,7 @@ func reviewSurvey(io *iostreams.IOStreams, editorCommand string) (*api.PullReque
}
return &api.PullRequestReviewInput{
Body: bodyAnswers.Body,
Body: body,
State: reviewState,
}, nil
}

View file

@ -18,7 +18,6 @@ import (
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/httpmock"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/cli/cli/v2/pkg/prompt"
"github.com/cli/cli/v2/test"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
@ -166,7 +165,7 @@ func Test_NewCmdReview(t *testing.T) {
}
}
func runCommand(rt http.RoundTripper, remotes context.Remotes, isTTY bool, cli string) (*test.CmdOut, error) {
func runCommand(rt http.RoundTripper, prompter cmdutil.Prompter, remotes context.Remotes, isTTY bool, cli string) (*test.CmdOut, error) {
ios, _, stdout, stderr := iostreams.Test()
ios.SetStdoutTTY(isTTY)
ios.SetStdinTTY(isTTY)
@ -180,6 +179,7 @@ func runCommand(rt http.RoundTripper, remotes context.Remotes, isTTY bool, cli s
Config: func() (config.Config, error) {
return config.NewBlankConfig(), nil
},
Prompter: prompter,
}
cmd := NewCmdReview(factory, nil)
@ -248,7 +248,7 @@ func TestPRReview(t *testing.T) {
}),
)
output, err := runCommand(http, nil, false, tt.args)
output, err := runCommand(http, nil, nil, false, tt.args)
assert.NoError(t, err)
assert.Equal(t, "", output.String())
assert.Equal(t, "", output.Stderr())
@ -271,33 +271,13 @@ func TestPRReview_interactive(t *testing.T) {
}),
)
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, teardown := prompt.InitAskStubber()
defer teardown()
pm := &cmdutil.PrompterMock{
SelectFunc: func(_, _ string, _ []string) (int, error) { return 1, nil },
MarkdownEditorFunc: func(_, _ string, _ bool) (string, error) { return "cool story", nil },
ConfirmFunc: func(_ string, _ bool) (bool, error) { return true, nil },
}
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "reviewType",
Value: "Approve",
},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "body",
Value: "cool story",
},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "confirm",
Value: true,
},
})
output, err := runCommand(http, nil, true, "")
output, err := runCommand(http, pm, nil, true, "")
assert.NoError(t, err)
assert.Equal(t, heredoc.Doc(`
Got:
@ -314,12 +294,12 @@ func TestPRReview_interactive_no_body(t *testing.T) {
shared.RunCommandFinder("", &api.PullRequest{ID: "THE-ID", Number: 123}, ghrepo.New("OWNER", "REPO"))
as := prompt.NewAskStubber(t)
pm := &cmdutil.PrompterMock{
SelectFunc: func(_, _ string, _ []string) (int, error) { return 2, nil },
MarkdownEditorFunc: func(_, _ string, _ bool) (string, error) { return "", nil },
}
as.StubPrompt("What kind of review do you want to give?").AnswerWith("Request changes")
as.StubPrompt("Review body").AnswerWith("")
_, err := runCommand(http, nil, true, "")
_, err := runCommand(http, pm, nil, true, "")
assert.EqualError(t, err, "this type of review cannot be blank")
}
@ -338,33 +318,13 @@ func TestPRReview_interactive_blank_approve(t *testing.T) {
}),
)
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, teardown := prompt.InitAskStubber()
defer teardown()
pm := &cmdutil.PrompterMock{
SelectFunc: func(_, _ string, _ []string) (int, error) { return 1, nil },
MarkdownEditorFunc: func(_, defVal string, _ bool) (string, error) { return defVal, nil },
ConfirmFunc: func(_ string, _ bool) (bool, error) { return true, nil },
}
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "reviewType",
Value: "Approve",
},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "body",
Default: true,
},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "confirm",
Value: true,
},
})
output, err := runCommand(http, nil, true, "")
output, err := runCommand(http, pm, nil, true, "")
assert.NoError(t, err)
assert.Equal(t, "", output.String())
assert.Equal(t, "✓ Approved pull request #123\n", output.Stderr())