@@ -2,6 +2,7 @@ package cmd
22
33import (
44 "context"
5+ "encoding/json"
56 "fmt"
67 "net/http"
78 "strconv"
@@ -42,6 +43,7 @@ type ProjectsCmd struct {
4243type ProjectsListInput struct {
4344 Limit int
4445 Offset int
46+ Output string
4547}
4648
4749type ProjectsCreateInput struct {
@@ -92,6 +94,9 @@ func resolveProjectArg(ctx context.Context, projects ProjectListService, val str
9294}
9395
9496func (c ProjectsCmd ) List (ctx context.Context , in ProjectsListInput ) error {
97+ if err := validateJSONOutput (in .Output ); err != nil {
98+ return err
99+ }
95100 if in .Limit < 1 || in .Limit > 100 {
96101 return fmt .Errorf ("--limit must be between 1 and 100" )
97102 }
@@ -108,13 +113,37 @@ func (c ProjectsCmd) List(ctx context.Context, in ProjectsListInput) error {
108113 return util.CleanedUpSdkError {Err : err }
109114 }
110115
111- if projects == nil || len (projects .Items ) == 0 {
116+ items := []kernel.Project {}
117+ if projects != nil {
118+ items = projects .Items
119+ }
120+
121+ nextOffset := projectListNextOffsetRaw (response )
122+ if in .Output == "json" {
123+ payload := struct {
124+ Projects []kernel.Project `json:"projects"`
125+ NextOffset string `json:"next_offset,omitempty"`
126+ }{
127+ Projects : items ,
128+ }
129+ if nextOffset != "" {
130+ payload .NextOffset = nextOffset
131+ }
132+ data , err := json .MarshalIndent (payload , "" , " " )
133+ if err != nil {
134+ return err
135+ }
136+ fmt .Println (string (data ))
137+ return nil
138+ }
139+
140+ if len (items ) == 0 {
112141 pterm .Info .Println ("No projects found" )
113142 return nil
114143 }
115144
116145 table := pterm.TableData {{"ID" , "Name" , "Status" , "Created At" , "idx" }}
117- for i , p := range projects . Items {
146+ for i , p := range items {
118147 table = append (table , []string {
119148 p .ID ,
120149 p .Name ,
@@ -125,20 +154,24 @@ func (c ProjectsCmd) List(ctx context.Context, in ProjectsListInput) error {
125154 }
126155 PrintTableNoPad (table , true )
127156
128- if nextOffset , ok := projectListNextOffset (response ); ok {
157+ if nextOffset , ok := projectListNextOffset (nextOffset ); ok {
129158 pterm .Warning .Printfln (
130159 "Output truncated after index %d. Continue with: kernel projects list --limit %d --offset %d" ,
131- in .Offset + len (projects . Items )- 1 , in .Limit , nextOffset ,
160+ in .Offset + len (items )- 1 , in .Limit , nextOffset ,
132161 )
133162 }
134163 return nil
135164}
136165
137- func projectListNextOffset (response * http.Response ) ( int , bool ) {
166+ func projectListNextOffsetRaw (response * http.Response ) string {
138167 if response == nil {
139- return 0 , false
168+ return ""
140169 }
141- nextOffset , err := strconv .Atoi (response .Header .Get ("X-Next-Offset" ))
170+ return strings .TrimSpace (response .Header .Get ("X-Next-Offset" ))
171+ }
172+
173+ func projectListNextOffset (nextOffsetRaw string ) (int , bool ) {
174+ nextOffset , err := strconv .Atoi (nextOffsetRaw )
142175 return nextOffset , err == nil && nextOffset > 0
143176}
144177
@@ -362,7 +395,8 @@ func runProjectsList(cmd *cobra.Command, args []string) error {
362395 c := getProjectsHandler (cmd )
363396 limit , _ := cmd .Flags ().GetInt ("limit" )
364397 offset , _ := cmd .Flags ().GetInt ("offset" )
365- return c .List (cmd .Context (), ProjectsListInput {Limit : limit , Offset : offset })
398+ output , _ := cmd .Flags ().GetString ("output" )
399+ return c .List (cmd .Context (), ProjectsListInput {Limit : limit , Offset : offset , Output : output })
366400}
367401
368402func runProjectsCreate (cmd * cobra.Command , args []string ) error {
@@ -518,6 +552,7 @@ var projectsSetLimitsCompatCmd = &cobra.Command{
518552func init () {
519553 projectsListCmd .Flags ().Int ("limit" , 100 , "Maximum number of projects to return (1-100)" )
520554 projectsListCmd .Flags ().Int ("offset" , 0 , "Number of projects to skip (for pagination)" )
555+ addJSONOutputFlag (projectsListCmd )
521556
522557 projectsUpdateCmd .Flags ().String ("name" , "" , "New project name (1-255 characters)" )
523558 projectsUpdateCmd .Flags ().String ("status" , "" , "New project status: active or archived" )
0 commit comments