Skip to content

Commit 16fe05c

Browse files
author
vilmibm
committed
cleanup
- refactor resolveWorkflow to be more functions - DRY the workflow prompting out - use path.Base(workflow.Path) in place of path + ID in prompts - preemptively move stuff into shared since the next workflow PR will make use of it
1 parent b06cdf0 commit 16fe05c

File tree

4 files changed

+141
-143
lines changed

4 files changed

+141
-143
lines changed

pkg/cmd/workflow/shared/shared.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
package shared
22

33
import (
4+
"errors"
45
"fmt"
6+
"path"
7+
"regexp"
8+
"strings"
59

10+
"github.com/AlecAivazis/survey/v2"
611
"github.com/cli/cli/api"
712
"github.com/cli/cli/internal/ghrepo"
13+
"github.com/cli/cli/pkg/prompt"
814
)
915

1016
const (
@@ -29,7 +35,12 @@ func (w *Workflow) Disabled() bool {
2935
return w.State != Active
3036
}
3137

38+
func (w *Workflow) Base() string {
39+
return path.Base(w.Path)
40+
}
41+
3242
func GetWorkflows(client *api.Client, repo ghrepo.Interface, limit int) ([]Workflow, error) {
43+
// TODO support getting all for 0 limit
3344
perPage := limit
3445
page := 1
3546
if limit > 100 {
@@ -64,3 +75,83 @@ func GetWorkflows(client *api.Client, repo ghrepo.Interface, limit int) ([]Workf
6475

6576
return workflows, nil
6677
}
78+
79+
func SelectWorkflow(workflows []Workflow, promptMsg string, states []WorkflowState) (*Workflow, error) {
80+
filtered := []Workflow{}
81+
candidates := []string{}
82+
for _, workflow := range workflows {
83+
for _, state := range states {
84+
if workflow.State == state {
85+
filtered = append(filtered, workflow)
86+
candidates = append(candidates, fmt.Sprintf("%s (%s)", workflow.Name, workflow.Base()))
87+
break
88+
}
89+
}
90+
}
91+
92+
var selected int
93+
94+
err := prompt.SurveyAskOne(&survey.Select{
95+
Message: promptMsg,
96+
Options: candidates,
97+
PageSize: 15,
98+
}, &selected)
99+
if err != nil {
100+
return nil, err
101+
}
102+
103+
return &filtered[selected], nil
104+
}
105+
106+
func ResolveWorkflow(client *api.Client, repo ghrepo.Interface, workflowSelector string) ([]Workflow, error) {
107+
if workflowSelector == "" {
108+
return nil, errors.New("empty workflow selector")
109+
}
110+
111+
idRE := regexp.MustCompile(`^\d+$`)
112+
113+
if idRE.MatchString(workflowSelector) {
114+
workflow, err := getWorkflowByID(client, repo, workflowSelector)
115+
if err != nil {
116+
return nil, err
117+
}
118+
return []Workflow{*workflow}, nil
119+
}
120+
121+
return getWorkflowsByName(client, repo, workflowSelector)
122+
}
123+
124+
func getWorkflowByID(client *api.Client, repo ghrepo.Interface, ID string) (*Workflow, error) {
125+
var workflow Workflow
126+
127+
err := client.REST(repo.RepoHost(), "GET",
128+
fmt.Sprintf("repos/%s/actions/workflows/%s", ghrepo.FullName(repo), ID),
129+
nil, &workflow)
130+
131+
if err != nil {
132+
return nil, err
133+
}
134+
135+
return &workflow, nil
136+
}
137+
138+
func getWorkflowsByName(client *api.Client, repo ghrepo.Interface, name string) ([]Workflow, error) {
139+
// TODO fix limit
140+
workflows, err := GetWorkflows(client, repo, 100)
141+
if err != nil {
142+
return nil, fmt.Errorf("couldn't fetch workflows for %s: %w", ghrepo.FullName(repo), err)
143+
}
144+
filtered := []Workflow{}
145+
146+
for _, workflow := range workflows {
147+
if workflow.Disabled() {
148+
continue
149+
}
150+
// TODO consider fuzzy or prefix match
151+
if strings.EqualFold(workflow.Name, name) {
152+
filtered = append(filtered, workflow)
153+
}
154+
}
155+
156+
return filtered, nil
157+
}

pkg/cmd/workflow/view/http.go

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,47 +3,12 @@ package view
33
import (
44
"encoding/base64"
55
"fmt"
6-
"strings"
76

87
"github.com/cli/cli/api"
98
"github.com/cli/cli/internal/ghrepo"
109
"github.com/cli/cli/pkg/cmd/workflow/shared"
1110
)
1211

13-
func getWorkflowByID(client *api.Client, repo ghrepo.Interface, workflowID string) (*shared.Workflow, error) {
14-
var workflow shared.Workflow
15-
16-
err := client.REST(repo.RepoHost(), "GET",
17-
fmt.Sprintf("repos/%s/actions/workflows/%s", ghrepo.FullName(repo), workflowID),
18-
nil, &workflow)
19-
20-
if err != nil {
21-
return nil, err
22-
}
23-
24-
return &workflow, nil
25-
}
26-
27-
func getWorkflowsByName(client *api.Client, repo ghrepo.Interface, workflowName string) ([]shared.Workflow, error) {
28-
workflows, err := shared.GetWorkflows(client, repo, 100)
29-
if err != nil {
30-
return nil, fmt.Errorf("couldn't fetch workflows for %s: %w", ghrepo.FullName(repo), err)
31-
}
32-
filtered := []shared.Workflow{}
33-
34-
for _, workflow := range workflows {
35-
if workflow.Disabled() {
36-
continue
37-
}
38-
// TODO consider fuzzy or prefix match
39-
if strings.EqualFold(workflow.Name, workflowName) {
40-
filtered = append(filtered, workflow)
41-
}
42-
}
43-
44-
return filtered, nil
45-
}
46-
4712
func getWorkflowContent(client *api.Client, repo ghrepo.Interface, workflow *shared.Workflow) (string, error) {
4813
path := fmt.Sprintf("repos/%s/contents/%s", ghrepo.FullName(repo), workflow.Path)
4914

pkg/cmd/workflow/view/view.go

Lines changed: 28 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,15 @@ import (
55
"fmt"
66
"net/http"
77
"path/filepath"
8-
"regexp"
98
"strings"
109

11-
"github.com/AlecAivazis/survey/v2"
1210
"github.com/MakeNowJust/heredoc"
1311
"github.com/cli/cli/api"
1412
"github.com/cli/cli/internal/ghrepo"
1513
"github.com/cli/cli/pkg/cmd/workflow/shared"
1614
"github.com/cli/cli/pkg/cmdutil"
1715
"github.com/cli/cli/pkg/iostreams"
1816
"github.com/cli/cli/pkg/markdown"
19-
"github.com/cli/cli/pkg/prompt"
2017
"github.com/cli/cli/utils"
2118
"github.com/spf13/cobra"
2219
)
@@ -26,8 +23,8 @@ type ViewOptions struct {
2623
IO *iostreams.IOStreams
2724
BaseRepo func() (ghrepo.Interface, error)
2825

29-
WorkflowID string
30-
Web bool
26+
WorkflowSelector string
27+
Web bool
3128

3229
Prompt bool
3330
Raw bool
@@ -57,9 +54,9 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman
5754
opts.Raw = !opts.IO.CanPrompt()
5855

5956
if len(args) > 0 {
60-
opts.WorkflowID = args[0]
57+
opts.WorkflowSelector = args[0]
6158
} else if !opts.IO.CanPrompt() {
62-
return &cmdutil.FlagError{Err: errors.New("workflow ID required when not running interactively")}
59+
return &cmdutil.FlagError{Err: errors.New("workflow argument required when not running interactively")}
6360
} else {
6461
opts.Prompt = true
6562
}
@@ -94,13 +91,31 @@ func runView(opts *ViewOptions) error {
9491
if err != nil {
9592
return err
9693
}
97-
}
98-
99-
if workflow == nil {
100-
workflow, err = resolveWorkflow(opts.IO, client, repo, opts.WorkflowID)
94+
} else {
95+
workflows, err := shared.ResolveWorkflow(client, repo, opts.WorkflowSelector)
10196
if err != nil {
10297
return err
10398
}
99+
if len(workflows) == 0 {
100+
return fmt.Errorf("could not find any workflows named %s", opts.WorkflowSelector)
101+
}
102+
103+
if len(workflows) == 1 {
104+
workflow = &workflows[0]
105+
} else {
106+
if !opts.IO.CanPrompt() {
107+
errMsg := "could not resolve to a unique workflow; found:"
108+
for _, workflow := range workflows {
109+
errMsg += fmt.Sprintf(" %s", workflow.Base())
110+
}
111+
return errors.New(errMsg)
112+
}
113+
states := []shared.WorkflowState{shared.Active}
114+
workflow, err = shared.SelectWorkflow(workflows, "Which workflow do you mean?", states)
115+
if err != nil {
116+
return err
117+
}
118+
}
104119
}
105120

106121
if opts.Web {
@@ -175,79 +190,6 @@ func promptWorkflows(client *api.Client, repo ghrepo.Interface) (*shared.Workflo
175190
return nil, fmt.Errorf("could not fetch workflows for %s: %w", ghrepo.FullName(repo), err)
176191
}
177192

178-
filtered := []shared.Workflow{}
179-
candidates := []string{}
180-
for _, workflow := range workflows {
181-
if !workflow.Disabled() {
182-
filtered = append(filtered, workflow)
183-
candidates = append(candidates, workflow.Name)
184-
}
185-
}
186-
187-
var selected int
188-
189-
err = prompt.SurveyAskOne(&survey.Select{
190-
Message: "Select a workflow",
191-
Options: candidates,
192-
PageSize: 10,
193-
}, &selected)
194-
if err != nil {
195-
return nil, err
196-
}
197-
198-
return &filtered[selected], nil
199-
}
200-
201-
func resolveWorkflow(io *iostreams.IOStreams, client *api.Client, repo ghrepo.Interface, workflowSelector string) (*shared.Workflow, error) {
202-
if workflowSelector == "" {
203-
return nil, errors.New("empty workflow selector")
204-
}
205-
206-
idRE := regexp.MustCompile(`^\d+$`)
207-
208-
if idRE.MatchString(workflowSelector) {
209-
workflow, err := getWorkflowByID(client, repo, workflowSelector)
210-
if err != nil {
211-
return nil, err
212-
}
213-
return workflow, nil
214-
}
215-
216-
workflows, err := getWorkflowsByName(client, repo, workflowSelector)
217-
if err != nil {
218-
return nil, err
219-
}
220-
221-
if len(workflows) == 0 {
222-
return nil, fmt.Errorf("could not find any workflows named %s", workflowSelector)
223-
}
224-
225-
if len(workflows) == 1 {
226-
return &workflows[0], nil
227-
}
228-
229-
if !io.CanPrompt() {
230-
errMsg := "could not resolve to a unique workflow; found:"
231-
for _, workflow := range workflows {
232-
errMsg += fmt.Sprintf(" %s (ID: %d)", workflow.Path, workflow.ID)
233-
}
234-
return nil, errors.New(errMsg)
235-
}
236-
237-
candidates := []string{}
238-
for _, workflow := range workflows {
239-
candidates = append(candidates, fmt.Sprintf("%s (ID: %d, path: %s)", workflow.Name, workflow.ID, workflow.Path))
240-
}
241-
242-
var selected int
243-
err = prompt.SurveyAskOne(&survey.Select{
244-
Message: "Which workflow do you mean?",
245-
Options: candidates,
246-
PageSize: 10,
247-
}, &selected)
248-
if err != nil {
249-
return nil, err
250-
}
251-
252-
return &workflows[selected], nil
193+
states := []shared.WorkflowState{shared.Active}
194+
return shared.SelectWorkflow(workflows, "Select a workflow", states)
253195
}

0 commit comments

Comments
 (0)