Add --json support to gh agent-task list
Add --json, --jq, and --template flags to `gh agent-task list`, consistent with the pattern used by `gh pr list --json`, `gh issue list --json`, etc. This implements the ExportData interface on capi.Session and defines SessionFields for the available JSON fields: id, name, status, repository, createdAt, updatedAt, pullRequestNumber, pullRequestUrl. Closes https://github.com/cli/cli/issues/12805 (partial) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
cf862d65df
commit
0d9e6af3da
3 changed files with 93 additions and 0 deletions
|
|
@ -102,6 +102,58 @@ type SessionError struct {
|
|||
Message string
|
||||
}
|
||||
|
||||
// SessionFields defines the available fields for JSON export of a Session.
|
||||
var SessionFields = []string{
|
||||
"id",
|
||||
"name",
|
||||
"status",
|
||||
"repository",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"pullRequestNumber",
|
||||
"pullRequestUrl",
|
||||
}
|
||||
|
||||
// ExportData implements the exportable interface for JSON output.
|
||||
func (s *Session) ExportData(fields []string) map[string]interface{} {
|
||||
data := make(map[string]interface{}, len(fields))
|
||||
for _, f := range fields {
|
||||
switch f {
|
||||
case "id":
|
||||
data[f] = s.ID
|
||||
case "name":
|
||||
data[f] = s.Name
|
||||
case "status":
|
||||
data[f] = s.State
|
||||
case "repository":
|
||||
if s.PullRequest != nil && s.PullRequest.Repository != nil {
|
||||
data[f] = s.PullRequest.Repository.NameWithOwner
|
||||
} else {
|
||||
data[f] = nil
|
||||
}
|
||||
case "createdAt":
|
||||
data[f] = s.CreatedAt
|
||||
case "updatedAt":
|
||||
data[f] = s.LastUpdatedAt
|
||||
case "pullRequestNumber":
|
||||
if s.PullRequest != nil {
|
||||
data[f] = s.PullRequest.Number
|
||||
} else {
|
||||
data[f] = nil
|
||||
}
|
||||
case "pullRequestUrl":
|
||||
if s.PullRequest != nil {
|
||||
data[f] = s.PullRequest.URL
|
||||
} else {
|
||||
data[f] = nil
|
||||
}
|
||||
default:
|
||||
data[f] = nil
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
type resource struct {
|
||||
ID string `json:"id"`
|
||||
UserID uint64 `json:"user_id"`
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ type ListOptions struct {
|
|||
CapiClient func() (capi.CapiClient, error)
|
||||
Web bool
|
||||
Browser browser.Browser
|
||||
Exporter cmdutil.Exporter
|
||||
}
|
||||
|
||||
// NewCmdList creates the list command
|
||||
|
|
@ -54,6 +55,8 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
|
|||
cmd.Flags().IntVarP(&opts.Limit, "limit", "L", defaultLimit, "Maximum number of agent tasks to fetch")
|
||||
cmd.Flags().BoolVarP(&opts.Web, "web", "w", false, "Open agent tasks in the browser")
|
||||
|
||||
cmdutil.AddJSONFlags(cmd, &opts.Exporter, capi.SessionFields)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
|
@ -91,6 +94,10 @@ func listRun(opts *ListOptions) error {
|
|||
return cmdutil.NewNoResultsError("no agent tasks found")
|
||||
}
|
||||
|
||||
if opts.Exporter != nil {
|
||||
return opts.Exporter.Write(opts.IO, sessions)
|
||||
}
|
||||
|
||||
if err := opts.IO.StartPager(); err == nil {
|
||||
defer opts.IO.StopPager()
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ func Test_listRun(t *testing.T) {
|
|||
capiStubs func(*testing.T, *capi.CapiClientMock)
|
||||
limit int
|
||||
web bool
|
||||
jsonFields []string
|
||||
wantOut string
|
||||
wantErr error
|
||||
wantStderr string
|
||||
|
|
@ -286,6 +287,33 @@ func Test_listRun(t *testing.T) {
|
|||
wantStderr: "Opening https://github.com/copilot/agents in your browser.\n",
|
||||
wantBrowserURL: "https://github.com/copilot/agents",
|
||||
},
|
||||
{
|
||||
name: "json output",
|
||||
tty: false,
|
||||
capiStubs: func(t *testing.T, m *capi.CapiClientMock) {
|
||||
m.ListLatestSessionsForViewerFunc = func(ctx context.Context, limit int) ([]*capi.Session, error) {
|
||||
return []*capi.Session{
|
||||
{
|
||||
ID: "abc-123",
|
||||
Name: "s1",
|
||||
State: "completed",
|
||||
CreatedAt: sampleDate,
|
||||
LastUpdatedAt: sampleDate,
|
||||
ResourceType: "pull",
|
||||
PullRequest: &api.PullRequest{
|
||||
Number: 101,
|
||||
URL: "https://github.com/OWNER/REPO/pull/101",
|
||||
Repository: &api.PRRepository{
|
||||
NameWithOwner: "OWNER/REPO",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
},
|
||||
jsonFields: []string{"id", "name", "status", "repository", "pullRequestNumber", "pullRequestUrl"},
|
||||
wantOut: "[{\"id\":\"abc-123\",\"name\":\"s1\",\"pullRequestNumber\":101,\"pullRequestUrl\":\"https://github.com/OWNER/REPO/pull/101\",\"repository\":\"OWNER/REPO\",\"status\":\"completed\"}]\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
@ -316,6 +344,12 @@ func Test_listRun(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
if tt.jsonFields != nil {
|
||||
exporter := cmdutil.NewJSONExporter()
|
||||
exporter.SetFields(tt.jsonFields)
|
||||
opts.Exporter = exporter
|
||||
}
|
||||
|
||||
err := listRun(opts)
|
||||
if tt.wantErr != nil {
|
||||
assert.Error(t, err)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue