github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/run/list/list.go (about) 1 package list 2 3 import ( 4 "fmt" 5 "net/http" 6 "time" 7 8 "github.com/ungtb10d/cli/v2/api" 9 "github.com/ungtb10d/cli/v2/internal/ghrepo" 10 "github.com/ungtb10d/cli/v2/internal/text" 11 "github.com/ungtb10d/cli/v2/pkg/cmd/run/shared" 12 workflowShared "github.com/ungtb10d/cli/v2/pkg/cmd/workflow/shared" 13 "github.com/ungtb10d/cli/v2/pkg/cmdutil" 14 "github.com/ungtb10d/cli/v2/pkg/iostreams" 15 "github.com/ungtb10d/cli/v2/utils" 16 "github.com/spf13/cobra" 17 ) 18 19 const ( 20 defaultLimit = 20 21 ) 22 23 type ListOptions struct { 24 IO *iostreams.IOStreams 25 HttpClient func() (*http.Client, error) 26 BaseRepo func() (ghrepo.Interface, error) 27 28 Exporter cmdutil.Exporter 29 30 Limit int 31 WorkflowSelector string 32 Branch string 33 Actor string 34 35 now time.Time 36 } 37 38 func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Command { 39 opts := &ListOptions{ 40 IO: f.IOStreams, 41 HttpClient: f.HttpClient, 42 now: time.Now(), 43 } 44 45 cmd := &cobra.Command{ 46 Use: "list", 47 Short: "List recent workflow runs", 48 Aliases: []string{"ls"}, 49 Args: cobra.NoArgs, 50 RunE: func(cmd *cobra.Command, args []string) error { 51 // support `-R, --repo` override 52 opts.BaseRepo = f.BaseRepo 53 54 if opts.Limit < 1 { 55 return cmdutil.FlagErrorf("invalid limit: %v", opts.Limit) 56 } 57 58 if runF != nil { 59 return runF(opts) 60 } 61 62 return listRun(opts) 63 }, 64 } 65 66 cmd.Flags().IntVarP(&opts.Limit, "limit", "L", defaultLimit, "Maximum number of runs to fetch") 67 cmd.Flags().StringVarP(&opts.WorkflowSelector, "workflow", "w", "", "Filter runs by workflow") 68 cmd.Flags().StringVarP(&opts.Branch, "branch", "b", "", "Filter runs by branch") 69 cmd.Flags().StringVarP(&opts.Actor, "user", "u", "", "Filter runs by user who triggered the run") 70 cmdutil.AddJSONFlags(cmd, &opts.Exporter, shared.RunFields) 71 72 return cmd 73 } 74 75 func listRun(opts *ListOptions) error { 76 baseRepo, err := opts.BaseRepo() 77 if err != nil { 78 return fmt.Errorf("failed to determine base repo: %w", err) 79 } 80 81 c, err := opts.HttpClient() 82 if err != nil { 83 return fmt.Errorf("failed to create http client: %w", err) 84 } 85 client := api.NewClientFromHTTP(c) 86 87 filters := &shared.FilterOptions{ 88 Branch: opts.Branch, 89 Actor: opts.Actor, 90 } 91 92 opts.IO.StartProgressIndicator() 93 if opts.WorkflowSelector != "" { 94 states := []workflowShared.WorkflowState{workflowShared.Active} 95 if workflow, err := workflowShared.ResolveWorkflow(opts.IO, client, baseRepo, false, opts.WorkflowSelector, states); err == nil { 96 filters.WorkflowID = workflow.ID 97 filters.WorkflowName = workflow.Name 98 } else { 99 return err 100 } 101 } 102 runsResult, err := shared.GetRuns(client, baseRepo, filters, opts.Limit) 103 opts.IO.StopProgressIndicator() 104 if err != nil { 105 return fmt.Errorf("failed to get runs: %w", err) 106 } 107 runs := runsResult.WorkflowRuns 108 if len(runs) == 0 && opts.Exporter == nil { 109 return cmdutil.NewNoResultsError("no runs found") 110 } 111 112 if err := opts.IO.StartPager(); err == nil { 113 defer opts.IO.StopPager() 114 } else { 115 fmt.Fprintf(opts.IO.ErrOut, "failed to start pager: %v\n", err) 116 } 117 118 if opts.Exporter != nil { 119 return opts.Exporter.Write(opts.IO, runs) 120 } 121 122 //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter 123 tp := utils.NewTablePrinter(opts.IO) 124 125 cs := opts.IO.ColorScheme() 126 127 if tp.IsTTY() { 128 tp.AddField("STATUS", nil, nil) 129 tp.AddField("TITLE", nil, nil) 130 tp.AddField("WORKFLOW", nil, nil) 131 tp.AddField("BRANCH", nil, nil) 132 tp.AddField("EVENT", nil, nil) 133 tp.AddField("ID", nil, nil) 134 tp.AddField("ELAPSED", nil, nil) 135 tp.AddField("AGE", nil, nil) 136 tp.EndRow() 137 } 138 139 for _, run := range runs { 140 if tp.IsTTY() { 141 symbol, symbolColor := shared.Symbol(cs, run.Status, run.Conclusion) 142 tp.AddField(symbol, nil, symbolColor) 143 } else { 144 tp.AddField(string(run.Status), nil, nil) 145 tp.AddField(string(run.Conclusion), nil, nil) 146 } 147 148 tp.AddField(run.Title(), nil, cs.Bold) 149 150 tp.AddField(run.WorkflowName(), nil, nil) 151 tp.AddField(run.HeadBranch, nil, cs.Bold) 152 tp.AddField(string(run.Event), nil, nil) 153 tp.AddField(fmt.Sprintf("%d", run.ID), nil, cs.Cyan) 154 155 tp.AddField(run.Duration(opts.now).String(), nil, nil) 156 tp.AddField(text.FuzzyAgoAbbr(time.Now(), run.StartedTime()), nil, nil) 157 tp.EndRow() 158 } 159 160 err = tp.Render() 161 if err != nil { 162 return err 163 } 164 165 return nil 166 }