Merge pull request #7847 from cli/mas-prompts
switch to prompter in workflow commands
This commit is contained in:
commit
e3a152c246
9 changed files with 168 additions and 114 deletions
|
|
@ -24,6 +24,7 @@ type ListOptions struct {
|
|||
IO *iostreams.IOStreams
|
||||
HttpClient func() (*http.Client, error)
|
||||
BaseRepo func() (ghrepo.Interface, error)
|
||||
Prompter iprompter
|
||||
|
||||
Exporter cmdutil.Exporter
|
||||
|
||||
|
|
@ -38,10 +39,15 @@ type ListOptions struct {
|
|||
now time.Time
|
||||
}
|
||||
|
||||
type iprompter interface {
|
||||
Select(string, string, []string) (int, error)
|
||||
}
|
||||
|
||||
func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Command {
|
||||
opts := &ListOptions{
|
||||
IO: f.IOStreams,
|
||||
HttpClient: f.HttpClient,
|
||||
Prompter: f.Prompter,
|
||||
now: time.Now(),
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +109,9 @@ func listRun(opts *ListOptions) error {
|
|||
opts.IO.StartProgressIndicator()
|
||||
if opts.WorkflowSelector != "" {
|
||||
states := []workflowShared.WorkflowState{workflowShared.Active}
|
||||
if workflow, err := workflowShared.ResolveWorkflow(opts.IO, client, baseRepo, false, opts.WorkflowSelector, states); err == nil {
|
||||
if workflow, err := workflowShared.ResolveWorkflow(
|
||||
opts.Prompter, opts.IO, client, baseRepo, false, opts.WorkflowSelector,
|
||||
states); err == nil {
|
||||
filters.WorkflowID = workflow.ID
|
||||
filters.WorkflowName = workflow.Name
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -17,15 +17,21 @@ type DisableOptions struct {
|
|||
HttpClient func() (*http.Client, error)
|
||||
IO *iostreams.IOStreams
|
||||
BaseRepo func() (ghrepo.Interface, error)
|
||||
Prompter iprompter
|
||||
|
||||
Selector string
|
||||
Prompt bool
|
||||
}
|
||||
|
||||
type iprompter interface {
|
||||
Select(string, string, []string) (int, error)
|
||||
}
|
||||
|
||||
func NewCmdDisable(f *cmdutil.Factory, runF func(*DisableOptions) error) *cobra.Command {
|
||||
opts := &DisableOptions{
|
||||
IO: f.IOStreams,
|
||||
HttpClient: f.HttpClient,
|
||||
Prompter: f.Prompter,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
|
|
@ -69,7 +75,7 @@ func runDisable(opts *DisableOptions) error {
|
|||
|
||||
states := []shared.WorkflowState{shared.Active}
|
||||
workflow, err := shared.ResolveWorkflow(
|
||||
opts.IO, client, repo, opts.Prompt, opts.Selector, states)
|
||||
opts.Prompter, opts.IO, client, repo, opts.Prompt, opts.Selector, states)
|
||||
if err != nil {
|
||||
var fae shared.FilteredAllError
|
||||
if errors.As(err, &fae) {
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/internal/prompter"
|
||||
"github.com/cli/cli/v2/pkg/cmd/workflow/shared"
|
||||
"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/google/shlex"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -91,14 +91,14 @@ func TestNewCmdDisable(t *testing.T) {
|
|||
|
||||
func TestDisableRun(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
opts *DisableOptions
|
||||
httpStubs func(*httpmock.Registry)
|
||||
askStubs func(*prompt.AskStubber)
|
||||
tty bool
|
||||
wantOut string
|
||||
wantErrOut string
|
||||
wantErr bool
|
||||
name string
|
||||
opts *DisableOptions
|
||||
httpStubs func(*httpmock.Registry)
|
||||
promptStubs func(*prompter.MockPrompter)
|
||||
tty bool
|
||||
wantOut string
|
||||
wantErrOut string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "tty no arg",
|
||||
|
|
@ -120,8 +120,10 @@ func TestDisableRun(t *testing.T) {
|
|||
httpmock.REST("PUT", "repos/OWNER/REPO/actions/workflows/789/disable"),
|
||||
httpmock.StatusStringResponse(204, "{}"))
|
||||
},
|
||||
askStubs: func(as *prompt.AskStubber) {
|
||||
as.StubPrompt("Select a workflow").AnswerWith("another workflow (another.yml)")
|
||||
promptStubs: func(pm *prompter.MockPrompter) {
|
||||
pm.RegisterSelect("Select a workflow", []string{"a workflow (flow.yml)", "another workflow (another.yml)"}, func(_, _ string, opts []string) (int, error) {
|
||||
return prompter.IndexFor(opts, "another workflow (another.yml)")
|
||||
})
|
||||
},
|
||||
wantOut: "✓ Disabled another workflow\n",
|
||||
},
|
||||
|
|
@ -169,8 +171,10 @@ func TestDisableRun(t *testing.T) {
|
|||
httpmock.REST("PUT", "repos/OWNER/REPO/actions/workflows/1011/disable"),
|
||||
httpmock.StatusStringResponse(204, "{}"))
|
||||
},
|
||||
askStubs: func(as *prompt.AskStubber) {
|
||||
as.StubPrompt("Which workflow do you mean?").AnswerWith("another workflow (yetanother.yml)")
|
||||
promptStubs: func(pm *prompter.MockPrompter) {
|
||||
pm.RegisterSelect("Which workflow do you mean?", []string{"another workflow (another.yml)", "another workflow (yetanother.yml)"}, func(_, _ string, opts []string) (int, error) {
|
||||
return prompter.IndexFor(opts, "another workflow (yetanother.yml)")
|
||||
})
|
||||
},
|
||||
wantOut: "✓ Disabled another workflow\n",
|
||||
},
|
||||
|
|
@ -269,10 +273,10 @@ func TestDisableRun(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
//nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock
|
||||
as := prompt.NewAskStubber(t)
|
||||
if tt.askStubs != nil {
|
||||
tt.askStubs(as)
|
||||
pm := prompter.NewMockPrompter(t)
|
||||
tt.opts.Prompter = pm
|
||||
if tt.promptStubs != nil {
|
||||
tt.promptStubs(pm)
|
||||
}
|
||||
|
||||
err := runDisable(tt.opts)
|
||||
|
|
|
|||
|
|
@ -17,15 +17,21 @@ type EnableOptions struct {
|
|||
HttpClient func() (*http.Client, error)
|
||||
IO *iostreams.IOStreams
|
||||
BaseRepo func() (ghrepo.Interface, error)
|
||||
Prompter iprompter
|
||||
|
||||
Selector string
|
||||
Prompt bool
|
||||
}
|
||||
|
||||
type iprompter interface {
|
||||
Select(string, string, []string) (int, error)
|
||||
}
|
||||
|
||||
func NewCmdEnable(f *cmdutil.Factory, runF func(*EnableOptions) error) *cobra.Command {
|
||||
opts := &EnableOptions{
|
||||
IO: f.IOStreams,
|
||||
HttpClient: f.HttpClient,
|
||||
Prompter: f.Prompter,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
|
|
@ -68,7 +74,7 @@ func runEnable(opts *EnableOptions) error {
|
|||
}
|
||||
|
||||
states := []shared.WorkflowState{shared.DisabledManually, shared.DisabledInactivity}
|
||||
workflow, err := shared.ResolveWorkflow(
|
||||
workflow, err := shared.ResolveWorkflow(opts.Prompter,
|
||||
opts.IO, client, repo, opts.Prompt, opts.Selector, states)
|
||||
if err != nil {
|
||||
var fae shared.FilteredAllError
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/internal/prompter"
|
||||
"github.com/cli/cli/v2/pkg/cmd/workflow/shared"
|
||||
"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/google/shlex"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -91,14 +91,14 @@ func TestNewCmdEnable(t *testing.T) {
|
|||
|
||||
func TestEnableRun(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
opts *EnableOptions
|
||||
httpStubs func(*httpmock.Registry)
|
||||
askStubs func(*prompt.AskStubber)
|
||||
tty bool
|
||||
wantOut string
|
||||
wantErrOut string
|
||||
wantErr bool
|
||||
name string
|
||||
opts *EnableOptions
|
||||
httpStubs func(*httpmock.Registry)
|
||||
promptStubs func(*prompter.MockPrompter)
|
||||
tty bool
|
||||
wantOut string
|
||||
wantErrOut string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "tty no arg",
|
||||
|
|
@ -120,8 +120,10 @@ func TestEnableRun(t *testing.T) {
|
|||
httpmock.REST("PUT", "repos/OWNER/REPO/actions/workflows/456/enable"),
|
||||
httpmock.StatusStringResponse(204, "{}"))
|
||||
},
|
||||
askStubs: func(as *prompt.AskStubber) {
|
||||
as.StubPrompt("Select a workflow").AnswerWith("a disabled workflow (disabled.yml)")
|
||||
promptStubs: func(pm *prompter.MockPrompter) {
|
||||
pm.RegisterSelect("Select a workflow", []string{"a disabled workflow (disabled.yml)"}, func(_, _ string, opts []string) (int, error) {
|
||||
return prompter.IndexFor(opts, "a disabled workflow (disabled.yml)")
|
||||
})
|
||||
},
|
||||
wantOut: "✓ Enabled a disabled workflow\n",
|
||||
},
|
||||
|
|
@ -169,8 +171,10 @@ func TestEnableRun(t *testing.T) {
|
|||
httpmock.REST("PUT", "repos/OWNER/REPO/actions/workflows/1213/enable"),
|
||||
httpmock.StatusStringResponse(204, "{}"))
|
||||
},
|
||||
askStubs: func(as *prompt.AskStubber) {
|
||||
as.StubPrompt("Which workflow do you mean?").AnswerWith("a disabled workflow (anotherDisabled.yml)")
|
||||
promptStubs: func(pm *prompter.MockPrompter) {
|
||||
pm.RegisterSelect("Which workflow do you mean?", []string{"a disabled workflow (disabled.yml)", "a disabled workflow (anotherDisabled.yml)"}, func(_, _ string, opts []string) (int, error) {
|
||||
return prompter.IndexFor(opts, "a disabled workflow (anotherDisabled.yml)")
|
||||
})
|
||||
},
|
||||
wantOut: "✓ Enabled a disabled workflow\n",
|
||||
},
|
||||
|
|
@ -309,10 +313,10 @@ func TestEnableRun(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
//nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock
|
||||
as := prompt.NewAskStubber(t)
|
||||
if tt.askStubs != nil {
|
||||
tt.askStubs(as)
|
||||
pm := prompter.NewMockPrompter(t)
|
||||
tt.opts.Prompter = pm
|
||||
if tt.promptStubs != nil {
|
||||
tt.promptStubs(pm)
|
||||
}
|
||||
|
||||
err := runEnable(tt.opts)
|
||||
|
|
|
|||
|
|
@ -11,14 +11,12 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/cli/cli/v2/api"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/pkg/cmd/workflow/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"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
|
@ -27,6 +25,7 @@ type RunOptions struct {
|
|||
HttpClient func() (*http.Client, error)
|
||||
IO *iostreams.IOStreams
|
||||
BaseRepo func() (ghrepo.Interface, error)
|
||||
Prompter iprompter
|
||||
|
||||
Selector string
|
||||
Ref string
|
||||
|
|
@ -39,10 +38,16 @@ type RunOptions struct {
|
|||
Prompt bool
|
||||
}
|
||||
|
||||
type iprompter interface {
|
||||
Input(string, string) (string, error)
|
||||
Select(string, string, []string) (int, error)
|
||||
}
|
||||
|
||||
func NewCmdRun(f *cmdutil.Factory, runF func(*RunOptions) error) *cobra.Command {
|
||||
opts := &RunOptions{
|
||||
IO: f.IOStreams,
|
||||
HttpClient: f.HttpClient,
|
||||
Prompter: f.Prompter,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
|
|
@ -198,7 +203,7 @@ func (ia *InputAnswer) WriteAnswer(name string, value interface{}) error {
|
|||
return fmt.Errorf("unexpected value type: %v", value)
|
||||
}
|
||||
|
||||
func collectInputs(yamlContent []byte) (map[string]string, error) {
|
||||
func collectInputs(p iprompter, yamlContent []byte) (map[string]string, error) {
|
||||
inputs, err := findInputs(yamlContent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -210,32 +215,24 @@ func collectInputs(yamlContent []byte) (map[string]string, error) {
|
|||
return providedInputs, nil
|
||||
}
|
||||
|
||||
qs := []*survey.Question{}
|
||||
for inputName, input := range inputs {
|
||||
q := &survey.Question{
|
||||
Name: inputName,
|
||||
Prompt: &survey.Input{
|
||||
Message: inputName,
|
||||
Default: input.Default,
|
||||
},
|
||||
}
|
||||
for _, input := range inputs {
|
||||
var answer string
|
||||
if input.Required {
|
||||
q.Validate = survey.Required
|
||||
for answer == "" {
|
||||
answer, err = p.Input(input.Name+" (required)", input.Default)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
answer, err = p.Input(input.Name, input.Default)
|
||||
}
|
||||
qs = append(qs, q)
|
||||
}
|
||||
|
||||
sort.Slice(qs, func(i, j int) bool {
|
||||
return qs[i].Name < qs[j].Name
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
inputAnswer := InputAnswer{
|
||||
providedInputs: providedInputs,
|
||||
}
|
||||
//nolint:staticcheck // SA1019: prompt.SurveyAsk is deprecated: use Prompter
|
||||
err = prompt.SurveyAsk(qs, &inputAnswer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
providedInputs[input.Name] = answer
|
||||
}
|
||||
|
||||
return providedInputs, nil
|
||||
|
|
@ -263,7 +260,7 @@ func runRun(opts *RunOptions) error {
|
|||
}
|
||||
|
||||
states := []shared.WorkflowState{shared.Active}
|
||||
workflow, err := shared.ResolveWorkflow(
|
||||
workflow, err := shared.ResolveWorkflow(opts.Prompter,
|
||||
opts.IO, client, repo, opts.Prompt, opts.Selector, states)
|
||||
if err != nil {
|
||||
var fae shared.FilteredAllError
|
||||
|
|
@ -290,7 +287,7 @@ func runRun(opts *RunOptions) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("unable to fetch workflow file content: %w", err)
|
||||
}
|
||||
providedInputs, err = collectInputs(yamlContent)
|
||||
providedInputs, err = collectInputs(opts.Prompter, yamlContent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -330,12 +327,13 @@ func runRun(opts *RunOptions) error {
|
|||
}
|
||||
|
||||
type WorkflowInput struct {
|
||||
Name string
|
||||
Required bool
|
||||
Default string
|
||||
Description string
|
||||
}
|
||||
|
||||
func findInputs(yamlContent []byte) (map[string]WorkflowInput, error) {
|
||||
func findInputs(yamlContent []byte) ([]WorkflowInput, error) {
|
||||
var rootNode yaml.Node
|
||||
err := yaml.Unmarshal(yamlContent, &rootNode)
|
||||
if err != nil {
|
||||
|
|
@ -400,16 +398,31 @@ func findInputs(yamlContent []byte) (map[string]WorkflowInput, error) {
|
|||
return nil, errors.New("unable to manually run a workflow without a workflow_dispatch event")
|
||||
}
|
||||
|
||||
out := map[string]WorkflowInput{}
|
||||
out := []WorkflowInput{}
|
||||
|
||||
m := map[string]WorkflowInput{}
|
||||
|
||||
if inputsKeyNode == nil || inputsMapNode == nil {
|
||||
return out, nil
|
||||
}
|
||||
|
||||
err = inputsMapNode.Decode(&out)
|
||||
err = inputsMapNode.Decode(&m)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not decode workflow inputs: %w", err)
|
||||
}
|
||||
|
||||
for name, input := range m {
|
||||
out = append(out, WorkflowInput{
|
||||
Name: name,
|
||||
Default: input.Default,
|
||||
Description: input.Description,
|
||||
Required: input.Required,
|
||||
})
|
||||
}
|
||||
|
||||
sort.Slice(out, func(i, j int) bool {
|
||||
return out[i].Name < out[j].Name
|
||||
})
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ import (
|
|||
|
||||
"github.com/cli/cli/v2/api"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/internal/prompter"
|
||||
"github.com/cli/cli/v2/pkg/cmd/workflow/shared"
|
||||
"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/google/shlex"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -215,7 +215,7 @@ func Test_findInputs(t *testing.T) {
|
|||
YAML []byte
|
||||
wantErr bool
|
||||
errMsg string
|
||||
wantOut map[string]WorkflowInput
|
||||
wantOut []WorkflowInput
|
||||
}{
|
||||
{
|
||||
name: "blank",
|
||||
|
|
@ -244,12 +244,12 @@ func Test_findInputs(t *testing.T) {
|
|||
{
|
||||
name: "short syntax",
|
||||
YAML: []byte("name: workflow\non: workflow_dispatch"),
|
||||
wantOut: map[string]WorkflowInput{},
|
||||
wantOut: []WorkflowInput{},
|
||||
},
|
||||
{
|
||||
name: "array of events",
|
||||
YAML: []byte("name: workflow\non: [pull_request, workflow_dispatch]\n"),
|
||||
wantOut: map[string]WorkflowInput{},
|
||||
wantOut: []WorkflowInput{},
|
||||
},
|
||||
{
|
||||
name: "inputs",
|
||||
|
|
@ -274,18 +274,22 @@ jobs:
|
|||
- name: echo
|
||||
run: |
|
||||
echo "echo"`),
|
||||
wantOut: map[string]WorkflowInput{
|
||||
"foo": {
|
||||
wantOut: []WorkflowInput{
|
||||
{
|
||||
Name: "bar",
|
||||
Default: "boo",
|
||||
},
|
||||
{
|
||||
Name: "baz",
|
||||
Description: "it's baz",
|
||||
},
|
||||
{
|
||||
Name: "foo",
|
||||
Required: true,
|
||||
Description: "good foo",
|
||||
},
|
||||
"bar": {
|
||||
Default: "boo",
|
||||
},
|
||||
"baz": {
|
||||
Description: "it's baz",
|
||||
},
|
||||
"quux": {
|
||||
{
|
||||
Name: "quux",
|
||||
Required: true,
|
||||
Default: "cool",
|
||||
},
|
||||
|
|
@ -359,15 +363,15 @@ jobs:
|
|||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
opts *RunOptions
|
||||
tty bool
|
||||
wantErr bool
|
||||
errOut string
|
||||
wantOut string
|
||||
wantBody map[string]interface{}
|
||||
httpStubs func(*httpmock.Registry)
|
||||
askStubs func(*prompt.AskStubber)
|
||||
name string
|
||||
opts *RunOptions
|
||||
tty bool
|
||||
wantErr bool
|
||||
errOut string
|
||||
wantOut string
|
||||
wantBody map[string]interface{}
|
||||
httpStubs func(*httpmock.Registry)
|
||||
promptStubs func(*prompter.MockPrompter)
|
||||
}{
|
||||
{
|
||||
name: "bad JSON",
|
||||
|
|
@ -577,8 +581,10 @@ jobs:
|
|||
httpmock.REST("POST", "repos/OWNER/REPO/actions/workflows/1/dispatches"),
|
||||
httpmock.StatusStringResponse(204, "cool"))
|
||||
},
|
||||
askStubs: func(as *prompt.AskStubber) {
|
||||
as.StubPrompt("Select a workflow").AnswerDefault()
|
||||
promptStubs: func(pm *prompter.MockPrompter) {
|
||||
pm.RegisterSelect("Select a workflow", []string{"minimal workflow (minimal.yml)"}, func(_, _ string, opts []string) (int, error) {
|
||||
return 0, nil
|
||||
})
|
||||
},
|
||||
wantBody: map[string]interface{}{
|
||||
"inputs": map[string]interface{}{},
|
||||
|
|
@ -614,10 +620,16 @@ jobs:
|
|||
httpmock.REST("POST", "repos/OWNER/REPO/actions/workflows/12345/dispatches"),
|
||||
httpmock.StatusStringResponse(204, "cool"))
|
||||
},
|
||||
askStubs: func(as *prompt.AskStubber) {
|
||||
as.StubPrompt("Select a workflow").AnswerDefault()
|
||||
as.StubPrompt("greeting").AnswerWith("hi")
|
||||
as.StubPrompt("name").AnswerWith("scully")
|
||||
promptStubs: func(pm *prompter.MockPrompter) {
|
||||
pm.RegisterSelect("Select a workflow", []string{"a workflow (workflow.yml)"}, func(_, _ string, opts []string) (int, error) {
|
||||
return 0, nil
|
||||
})
|
||||
pm.RegisterInput("greeting", func(_, _ string) (string, error) {
|
||||
return "hi", nil
|
||||
})
|
||||
pm.RegisterInput("name (required)", func(_, _ string) (string, error) {
|
||||
return "scully", nil
|
||||
})
|
||||
},
|
||||
wantBody: map[string]interface{}{
|
||||
"inputs": map[string]interface{}{
|
||||
|
|
@ -652,10 +664,10 @@ jobs:
|
|||
}
|
||||
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
//nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock
|
||||
as := prompt.NewAskStubber(t)
|
||||
if tt.askStubs != nil {
|
||||
tt.askStubs(as)
|
||||
pm := prompter.NewMockPrompter(t)
|
||||
tt.opts.Prompter = pm
|
||||
if tt.promptStubs != nil {
|
||||
tt.promptStubs(pm)
|
||||
}
|
||||
|
||||
err := runRun(tt.opts)
|
||||
|
|
|
|||
|
|
@ -11,11 +11,9 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/cli/cli/v2/api"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
"github.com/cli/cli/v2/pkg/prompt"
|
||||
"github.com/cli/go-gh/v2/pkg/asciisanitizer"
|
||||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
|
@ -26,6 +24,10 @@ const (
|
|||
DisabledInactivity WorkflowState = "disabled_inactivity"
|
||||
)
|
||||
|
||||
type iprompter interface {
|
||||
Select(string, string, []string) (int, error)
|
||||
}
|
||||
|
||||
type WorkflowState string
|
||||
|
||||
type Workflow struct {
|
||||
|
|
@ -90,7 +92,7 @@ type FilteredAllError struct {
|
|||
error
|
||||
}
|
||||
|
||||
func SelectWorkflow(workflows []Workflow, promptMsg string, states []WorkflowState) (*Workflow, error) {
|
||||
func selectWorkflow(p iprompter, workflows []Workflow, promptMsg string, states []WorkflowState) (*Workflow, error) {
|
||||
filtered := []Workflow{}
|
||||
candidates := []string{}
|
||||
for _, workflow := range workflows {
|
||||
|
|
@ -107,14 +109,7 @@ func SelectWorkflow(workflows []Workflow, promptMsg string, states []WorkflowSta
|
|||
return nil, FilteredAllError{errors.New("")}
|
||||
}
|
||||
|
||||
var selected int
|
||||
|
||||
//nolint:staticcheck // SA1019: prompt.SurveyAskOne is deprecated: use Prompter
|
||||
err := prompt.SurveyAskOne(&survey.Select{
|
||||
Message: promptMsg,
|
||||
Options: candidates,
|
||||
PageSize: 15,
|
||||
}, &selected)
|
||||
selected, err := p.Select(promptMsg, "", candidates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -182,7 +177,7 @@ func getWorkflowsByName(client *api.Client, repo ghrepo.Interface, name string,
|
|||
return filtered, nil
|
||||
}
|
||||
|
||||
func ResolveWorkflow(io *iostreams.IOStreams, client *api.Client, repo ghrepo.Interface, prompt bool, workflowSelector string, states []WorkflowState) (*Workflow, error) {
|
||||
func ResolveWorkflow(p iprompter, io *iostreams.IOStreams, client *api.Client, repo ghrepo.Interface, prompt bool, workflowSelector string, states []WorkflowState) (*Workflow, error) {
|
||||
if prompt {
|
||||
workflows, err := GetWorkflows(client, repo, 0)
|
||||
if len(workflows) == 0 {
|
||||
|
|
@ -198,7 +193,7 @@ func ResolveWorkflow(io *iostreams.IOStreams, client *api.Client, repo ghrepo.In
|
|||
return nil, fmt.Errorf("could not fetch workflows for %s: %w", ghrepo.FullName(repo), err)
|
||||
}
|
||||
|
||||
return SelectWorkflow(workflows, "Select a workflow", states)
|
||||
return selectWorkflow(p, workflows, "Select a workflow", states)
|
||||
}
|
||||
|
||||
workflows, err := FindWorkflow(client, repo, workflowSelector, states)
|
||||
|
|
@ -222,7 +217,7 @@ func ResolveWorkflow(io *iostreams.IOStreams, client *api.Client, repo ghrepo.In
|
|||
return nil, errors.New(errMsg)
|
||||
}
|
||||
|
||||
return SelectWorkflow(workflows, "Which workflow do you mean?", states)
|
||||
return selectWorkflow(p, workflows, "Which workflow do you mean?", states)
|
||||
}
|
||||
|
||||
func GetWorkflowContent(client *api.Client, repo ghrepo.Interface, workflow Workflow, ref string) ([]byte, error) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ type ViewOptions struct {
|
|||
IO *iostreams.IOStreams
|
||||
BaseRepo func() (ghrepo.Interface, error)
|
||||
Browser browser.Browser
|
||||
Prompter iprompter
|
||||
|
||||
Selector string
|
||||
Ref string
|
||||
|
|
@ -37,11 +38,16 @@ type ViewOptions struct {
|
|||
now time.Time
|
||||
}
|
||||
|
||||
type iprompter interface {
|
||||
Select(string, string, []string) (int, error)
|
||||
}
|
||||
|
||||
func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Command {
|
||||
opts := &ViewOptions{
|
||||
IO: f.IOStreams,
|
||||
HttpClient: f.HttpClient,
|
||||
Browser: f.Browser,
|
||||
Prompter: f.Prompter,
|
||||
now: time.Now(),
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +110,7 @@ func runView(opts *ViewOptions) error {
|
|||
|
||||
var workflow *shared.Workflow
|
||||
states := []shared.WorkflowState{shared.Active}
|
||||
workflow, err = shared.ResolveWorkflow(opts.IO, client, repo, opts.Prompt, opts.Selector, states)
|
||||
workflow, err = shared.ResolveWorkflow(opts.Prompter, opts.IO, client, repo, opts.Prompt, opts.Selector, states)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue