diff --git a/internal/codespaces/api/api.go b/internal/codespaces/api/api.go index 505e292ae..f509e2661 100644 --- a/internal/codespaces/api/api.go +++ b/internal/codespaces/api/api.go @@ -35,6 +35,7 @@ import ( "io/ioutil" "net/http" "net/url" + "reflect" "regexp" "strconv" "strings" @@ -176,6 +177,43 @@ type CodespaceConnection struct { HostPublicKeys []string `json:"hostPublicKeys"` } +var CodespaceFields = []string{ + "name", + "owner", + "repository", + "state", + "gitStatus", + "createdAt", + "lastUsedAt", +} + +func (c *Codespace) ExportData(fields []string) *map[string]interface{} { + v := reflect.ValueOf(c).Elem() + data := map[string]interface{}{} + + for _, f := range fields { + switch f { + case "owner": + data[f] = c.Owner.Login + case "repository": + data[f] = c.Repository.FullName + case "gitStatus": + data[f] = map[string]interface{}{ + "ref": c.GitStatus.Ref, + "hasUnpushedChanges": c.GitStatus.HasUnpushedChanges, + "hasUncommitedChanges": c.GitStatus.HasUncommitedChanges, + } + default: + sf := v.FieldByNameFunc(func(s string) bool { + return strings.EqualFold(f, s) + }) + data[f] = sf.Interface() + } + } + + return &data +} + // ListCodespaces returns a list of codespaces for the user. Pass a negative limit to request all pages from // the API until all codespaces have been fetched. func (a *API) ListCodespaces(ctx context.Context, limit int) (codespaces []*Codespace, err error) { diff --git a/pkg/cmd/codespace/list.go b/pkg/cmd/codespace/list.go index ba573a226..7fe71d6fa 100644 --- a/pkg/cmd/codespace/list.go +++ b/pkg/cmd/codespace/list.go @@ -12,8 +12,8 @@ import ( ) func newListCmd(app *App) *cobra.Command { - var asJSON bool var limit int + var exporter cmdutil.Exporter listCmd := &cobra.Command{ Use: "list", @@ -24,17 +24,17 @@ func newListCmd(app *App) *cobra.Command { return cmdutil.FlagErrorf("invalid limit: %v", limit) } - return app.List(cmd.Context(), asJSON, limit) + return app.List(cmd.Context(), limit, exporter) }, } - listCmd.Flags().BoolVar(&asJSON, "json", false, "Output as JSON") listCmd.Flags().IntVarP(&limit, "limit", "L", 30, "Maximum number of codespaces to list") + cmdutil.AddJSONFlags(listCmd, &exporter, api.CodespaceFields) return listCmd } -func (a *App) List(ctx context.Context, asJSON bool, limit int) error { +func (a *App) List(ctx context.Context, limit int, exporter cmdutil.Exporter) error { a.StartProgressIndicatorWithLabel("Fetching codespaces") codespaces, err := a.apiClient.ListCodespaces(ctx, limit) a.StopProgressIndicator() @@ -47,6 +47,10 @@ func (a *App) List(ctx context.Context, asJSON bool, limit int) error { } defer a.io.StopPager() + if exporter != nil { + return exporter.Write(a.io, codespaces) + } + tp := utils.NewTablePrinter(a.io) if tp.IsTTY() { tp.AddField("NAME", nil, nil)