Moves CAPI client initialization to a deferred function in ListOptions, simplifying command setup and improving testability. Updates tests to use the new client initialization pattern and adds more comprehensive test cases for session listing.
143 lines
3.1 KiB
Go
143 lines
3.1 KiB
Go
package list
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/cli/cli/v2/internal/gh"
|
|
"github.com/cli/cli/v2/internal/tableprinter"
|
|
"github.com/cli/cli/v2/pkg/cmd/agent-task/capi"
|
|
prShared "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/spf13/cobra"
|
|
)
|
|
|
|
const defaultLimit = 30
|
|
|
|
// ListOptions are the options for the list command
|
|
type ListOptions struct {
|
|
IO *iostreams.IOStreams
|
|
Config func() (gh.Config, error)
|
|
Limit int
|
|
CapiClient func() (*capi.CAPIClient, error)
|
|
}
|
|
|
|
// NewCmdList creates the list command
|
|
func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Command {
|
|
opts := &ListOptions{
|
|
IO: f.IOStreams,
|
|
Config: f.Config,
|
|
Limit: defaultLimit,
|
|
}
|
|
|
|
cmd := &cobra.Command{
|
|
Use: "list",
|
|
Short: "List agent tasks",
|
|
Args: cobra.NoArgs,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
if runF != nil {
|
|
return runF(opts)
|
|
}
|
|
return listRun(opts)
|
|
},
|
|
}
|
|
|
|
opts.CapiClient = func() (*capi.CAPIClient, error) {
|
|
cfg, err := opts.Config()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
httpClient, err := f.HttpClient()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
authCfg := cfg.Authentication()
|
|
return capi.NewCAPIClient(httpClient, authCfg), nil
|
|
}
|
|
|
|
return cmd
|
|
}
|
|
|
|
func listRun(opts *ListOptions) error {
|
|
if opts.Limit <= 0 {
|
|
opts.Limit = defaultLimit
|
|
}
|
|
|
|
capiClient, err := opts.CapiClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
opts.IO.StartProgressIndicatorWithLabel("Fetching agent tasks...")
|
|
defer opts.IO.StopProgressIndicator()
|
|
sessions, err := capiClient.ListSessionsForViewer(context.Background(), opts.Limit)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
opts.IO.StopProgressIndicator()
|
|
|
|
if len(sessions) == 0 {
|
|
fmt.Fprintln(opts.IO.Out, "no agent tasks found")
|
|
return nil
|
|
}
|
|
|
|
cs := opts.IO.ColorScheme()
|
|
tp := tableprinter.New(opts.IO, tableprinter.WithHeader("Session ID", "Pull Request", "Repo", "Session State", "Created"))
|
|
for _, s := range sessions {
|
|
if s.ResourceType != "pull" || s.PullRequest == nil || s.PullRequest.Repository == nil {
|
|
// Skip these sessions in case they happen, for now.
|
|
continue
|
|
}
|
|
|
|
pr := fmt.Sprintf("#%d", s.PullRequest.Number)
|
|
repo := s.PullRequest.Repository.NameWithOwner
|
|
|
|
// ID
|
|
tp.AddField(s.ID)
|
|
if tp.IsTTY() {
|
|
tp.AddField(pr, tableprinter.WithColor(cs.ColorFromString(prShared.ColorForPRState(*s.PullRequest))))
|
|
} else {
|
|
tp.AddField(pr)
|
|
}
|
|
|
|
// Repo
|
|
tp.AddField(repo, tableprinter.WithColor(cs.Muted))
|
|
|
|
// State
|
|
if tp.IsTTY() {
|
|
var stateColor func(string) string
|
|
switch s.State {
|
|
case "completed":
|
|
stateColor = cs.Green
|
|
case "canceled":
|
|
stateColor = cs.Muted
|
|
case "in_progress", "queued":
|
|
stateColor = cs.Yellow
|
|
case "failed":
|
|
stateColor = cs.Red
|
|
default:
|
|
stateColor = cs.Muted
|
|
}
|
|
tp.AddField(s.State, tableprinter.WithColor(stateColor))
|
|
} else {
|
|
tp.AddField(s.State)
|
|
}
|
|
|
|
// Created
|
|
if tp.IsTTY() {
|
|
tp.AddTimeField(time.Now(), s.CreatedAt, cs.Muted)
|
|
} else {
|
|
tp.AddField(s.CreatedAt.Format(time.RFC3339))
|
|
}
|
|
|
|
tp.EndRow()
|
|
}
|
|
|
|
if err := tp.Render(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|