Skip to content

Commit c10efcc

Browse files
stainless-app[bot]cjquines
authored andcommitted
feat: improved formatting options for command outputs
1 parent 242ebdc commit c10efcc

File tree

11 files changed

+837
-61
lines changed

11 files changed

+837
-61
lines changed

cmd/stl/main.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ func main() {
1919
var apierr *stainless.Error
2020
if errors.As(err, &apierr) {
2121
fmt.Fprintf(os.Stderr, "%s %q: %d %s\n", apierr.Request.Method, apierr.Request.URL, apierr.Response.StatusCode, http.StatusText(apierr.Response.StatusCode))
22-
fmt.Fprintf(os.Stdout, "%s\n", cmd.ColorizeJSON(apierr.RawJSON(), os.Stdout))
22+
format := app.String("format")
23+
show_err := cmd.ShowJSON("Error", apierr.RawJSON(), format)
24+
if show_err != nil {
25+
// Just print the original error:
26+
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
27+
}
2328
} else {
2429
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
2530
}

pkg/cmd/build.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,13 @@ package cmd
55
import (
66
"bytes"
77
"context"
8-
"fmt"
98
"io"
109
"net/http"
1110
"net/url"
12-
"os"
1311
"os/exec"
1412
"path/filepath"
1513
"strings"
1614
"time"
17-
1815
"github.com/stainless-api/stainless-api-cli/pkg/jsonflag"
1916
"github.com/stainless-api/stainless-api-go"
2017
"github.com/stainless-api/stainless-api-go/option"
@@ -482,8 +479,8 @@ func handleBuildsCreate(ctx context.Context, cmd *cli.Command) error {
482479
}
483480
}
484481

485-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
486-
return nil
482+
format := cmd.Root().String("format")
483+
return ShowJSON("builds create", res.RawJSON(), format)
487484
}
488485

489486
func handleBuildsRetrieve(ctx context.Context, cmd *cli.Command) error {
@@ -497,8 +494,8 @@ func handleBuildsRetrieve(ctx context.Context, cmd *cli.Command) error {
497494
return err
498495
}
499496

500-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
501-
return nil
497+
format := cmd.Root().String("format")
498+
return ShowJSON("builds retrieve", res.RawJSON(), format)
502499
}
503500

504501
// pullBuildOutputs pulls the outputs for a completed build
@@ -782,8 +779,8 @@ func handleBuildsList(ctx context.Context, cmd *cli.Command) error {
782779
return err
783780
}
784781

785-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
786-
return nil
782+
format := cmd.Root().String("format")
783+
return ShowJSON("builds list", res.RawJSON(), format)
787784
}
788785

789786
func handleBuildsCompare(ctx context.Context, cmd *cli.Command) error {
@@ -798,6 +795,6 @@ func handleBuildsCompare(ctx context.Context, cmd *cli.Command) error {
798795
return err
799796
}
800797

801-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
802-
return nil
798+
format := cmd.Root().String("format")
799+
return ShowJSON("builds compare", res.RawJSON(), format)
803800
}

pkg/cmd/builddiagnostic.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ package cmd
44

55
import (
66
"context"
7-
"fmt"
8-
"os"
97

108
"github.com/stainless-api/stainless-api-cli/pkg/jsonflag"
119
"github.com/stainless-api/stainless-api-go"
@@ -73,6 +71,6 @@ func handleBuildsDiagnosticsList(ctx context.Context, cmd *cli.Command) error {
7371
return err
7472
}
7573

76-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
77-
return nil
74+
format := cmd.Root().String("format")
75+
return ShowJSON("builds:diagnostics list", res.RawJSON(), format)
7876
}

pkg/cmd/cmd.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,17 @@ import (
88
"fmt"
99
"os"
1010
"path/filepath"
11+
"slices"
12+
"strings"
1113

1214
docs "github.com/urfave/cli-docs/v3"
1315
"github.com/urfave/cli/v3"
1416
)
1517

16-
var Command *cli.Command
18+
var (
19+
Command *cli.Command
20+
OutputFormats = []string{"auto", "explore", "json", "pretty", "raw", "yaml"}
21+
)
1722

1823
func init() {
1924
Command = &cli.Command{
@@ -32,8 +37,20 @@ stl builds create --branch <branch>`,
3237
Usage: "Enable debug logging",
3338
},
3439
&cli.StringFlag{
35-
Name: "base-url",
36-
Usage: "Override the base URL for API requests",
40+
Name: "base-url",
41+
DefaultText: "url",
42+
Usage: "Override the base URL for API requests",
43+
},
44+
&cli.StringFlag{
45+
Name: "format",
46+
Usage: "The format for data output (one of: " + strings.Join(OutputFormats[:], ", ") + ")",
47+
Value: "auto",
48+
Validator: func(format string) error {
49+
if !slices.Contains(OutputFormats[:], strings.ToLower(format)) {
50+
return fmt.Errorf("format must be one of: %s", strings.Join(OutputFormats[:], ", "))
51+
}
52+
return nil
53+
},
3754
},
3855
&cli.StringFlag{
3956
Name: "environment",

pkg/cmd/org.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ package cmd
44

55
import (
66
"context"
7-
"fmt"
8-
"os"
97

108
"github.com/stainless-api/stainless-api-go/option"
119
"github.com/urfave/cli/v3"
@@ -42,8 +40,8 @@ func handleOrgsRetrieve(ctx context.Context, cmd *cli.Command) error {
4240
return err
4341
}
4442

45-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
46-
return nil
43+
format := cmd.Root().String("format")
44+
return ShowJSON("orgs retrieve", res.RawJSON(), format)
4745
}
4846

4947
func handleOrgsList(ctx context.Context, cmd *cli.Command) error {
@@ -53,6 +51,6 @@ func handleOrgsList(ctx context.Context, cmd *cli.Command) error {
5351
return err
5452
}
5553

56-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
57-
return nil
54+
format := cmd.Root().String("format")
55+
return ShowJSON("orgs list", res.RawJSON(), format)
5856
}

pkg/cmd/project.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ package cmd
44

55
import (
66
"context"
7-
"fmt"
8-
"os"
97

108
"github.com/stainless-api/stainless-api-cli/pkg/jsonflag"
119
"github.com/stainless-api/stainless-api-go"
@@ -130,8 +128,8 @@ func handleProjectsCreate(ctx context.Context, cmd *cli.Command) error {
130128
return err
131129
}
132130

133-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
134-
return nil
131+
format := cmd.Root().String("format")
132+
return ShowJSON("projects create", res.RawJSON(), format)
135133
}
136134

137135
func handleProjectsRetrieve(ctx context.Context, cmd *cli.Command) error {
@@ -149,8 +147,8 @@ func handleProjectsRetrieve(ctx context.Context, cmd *cli.Command) error {
149147
return err
150148
}
151149

152-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
153-
return nil
150+
format := cmd.Root().String("format")
151+
return ShowJSON("projects retrieve", res.RawJSON(), format)
154152
}
155153

156154
func handleProjectsUpdate(ctx context.Context, cmd *cli.Command) error {
@@ -168,8 +166,8 @@ func handleProjectsUpdate(ctx context.Context, cmd *cli.Command) error {
168166
return err
169167
}
170168

171-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
172-
return nil
169+
format := cmd.Root().String("format")
170+
return ShowJSON("projects update", res.RawJSON(), format)
173171
}
174172

175173
func handleProjectsList(ctx context.Context, cmd *cli.Command) error {
@@ -184,6 +182,6 @@ func handleProjectsList(ctx context.Context, cmd *cli.Command) error {
184182
return err
185183
}
186184

187-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
188-
return nil
185+
format := cmd.Root().String("format")
186+
return ShowJSON("projects list", res.RawJSON(), format)
189187
}

pkg/cmd/projectbranch.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ package cmd
44

55
import (
66
"context"
7-
"fmt"
8-
"os"
97

108
"github.com/stainless-api/stainless-api-cli/pkg/jsonflag"
119
"github.com/stainless-api/stainless-api-go"
@@ -140,8 +138,8 @@ func handleProjectsBranchesCreate(ctx context.Context, cmd *cli.Command) error {
140138
return err
141139
}
142140

143-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
144-
return nil
141+
format := cmd.Root().String("format")
142+
return ShowJSON("projects:branches create", res.RawJSON(), format)
145143
}
146144

147145
func handleProjectsBranchesRetrieve(ctx context.Context, cmd *cli.Command) error {
@@ -160,8 +158,8 @@ func handleProjectsBranchesRetrieve(ctx context.Context, cmd *cli.Command) error
160158
return err
161159
}
162160

163-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
164-
return nil
161+
format := cmd.Root().String("format")
162+
return ShowJSON("projects:branches retrieve", res.RawJSON(), format)
165163
}
166164

167165
func handleProjectsBranchesList(ctx context.Context, cmd *cli.Command) error {
@@ -179,8 +177,8 @@ func handleProjectsBranchesList(ctx context.Context, cmd *cli.Command) error {
179177
return err
180178
}
181179

182-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
183-
return nil
180+
format := cmd.Root().String("format")
181+
return ShowJSON("projects:branches list", res.RawJSON(), format)
184182
}
185183

186184
func handleProjectsBranchesDelete(ctx context.Context, cmd *cli.Command) error {
@@ -201,8 +199,8 @@ func handleProjectsBranchesDelete(ctx context.Context, cmd *cli.Command) error {
201199
return err
202200
}
203201

204-
fmt.Printf("%s\n", ColorizeJSON(string(res), os.Stdout))
205-
return nil
202+
format := cmd.Root().String("format")
203+
return ShowJSON("projects:branches delete", string(res), format)
206204
}
207205

208206
func handleProjectsBranchesRebase(ctx context.Context, cmd *cli.Command) error {
@@ -221,6 +219,6 @@ func handleProjectsBranchesRebase(ctx context.Context, cmd *cli.Command) error {
221219
return err
222220
}
223221

224-
fmt.Printf("%s\n", ColorizeJSON(res.RawJSON(), os.Stdout))
225-
return nil
222+
format := cmd.Root().String("format")
223+
return ShowJSON("projects:branches rebase", res.RawJSON(), format)
226224
}

pkg/cmd/projectconfig.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ package cmd
44

55
import (
66
"context"
7-
"fmt"
8-
"os"
97

108
"github.com/stainless-api/stainless-api-cli/pkg/jsonflag"
119
"github.com/stainless-api/stainless-api-go"
@@ -82,8 +80,8 @@ func handleProjectsConfigsRetrieve(ctx context.Context, cmd *cli.Command) error
8280
return err
8381
}
8482

85-
fmt.Printf("%s\n", ColorizeJSON(string(res), os.Stdout))
86-
return nil
83+
format := cmd.Root().String("format")
84+
return ShowJSON("projects:configs retrieve", string(res), format)
8785
}
8886

8987
func handleProjectsConfigsGuess(ctx context.Context, cmd *cli.Command) error {
@@ -103,6 +101,6 @@ func handleProjectsConfigsGuess(ctx context.Context, cmd *cli.Command) error {
103101
return err
104102
}
105103

106-
fmt.Printf("%s\n", ColorizeJSON(string(res), os.Stdout))
107-
return nil
104+
format := cmd.Root().String("format")
105+
return ShowJSON("projects:configs guess", string(res), format)
108106
}

pkg/cmd/util.go

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ import (
1818
"golang.org/x/term"
1919

2020
"github.com/logrusorgru/aurora/v4"
21+
22+
"github.com/itchyny/json2yaml"
2123
"github.com/stainless-api/stainless-api-cli/pkg/jsonflag"
24+
"github.com/stainless-api/stainless-api-cli/pkg/jsonview"
2225
"github.com/stainless-api/stainless-api-go"
2326
"github.com/stainless-api/stainless-api-go/option"
2427
"github.com/tidwall/gjson"
@@ -349,15 +352,38 @@ func shouldUseColors(w io.Writer) bool {
349352
}
350353
}
351354

352-
if isTerminal(w) {
353-
return true
354-
}
355-
return false
355+
return isTerminal(w)
356356
}
357357

358-
func ColorizeJSON(input string, w io.Writer) string {
359-
if !shouldUseColors(w) {
360-
return input
358+
func ShowJSON(title, jsonText, format string) error {
359+
switch strings.ToLower(format) {
360+
case "auto":
361+
return ShowJSON(title, jsonText, "json")
362+
case "explore":
363+
return jsonview.ExploreJSON(title, jsonText)
364+
case "pretty":
365+
jsonview.DisplayJSON(title, jsonText)
366+
return nil
367+
case "json":
368+
prettyJSON := pretty.Pretty([]byte(jsonText))
369+
if shouldUseColors(os.Stdout) {
370+
fmt.Print(string(pretty.Color(prettyJSON, pretty.TerminalStyle)))
371+
} else {
372+
fmt.Print(string(prettyJSON))
373+
}
374+
return nil
375+
case "raw":
376+
fmt.Println(jsonText)
377+
return nil
378+
case "yaml":
379+
input := strings.NewReader(jsonText)
380+
var yaml strings.Builder
381+
if err := json2yaml.Convert(&yaml, input); err != nil {
382+
return err
383+
}
384+
fmt.Print(yaml.String())
385+
return nil
386+
default:
387+
return fmt.Errorf("Invalid format: %s, valid formats are: %s", format, strings.Join(OutputFormats[:], ", "))
361388
}
362-
return string(pretty.Color(pretty.Pretty([]byte(input)), nil))
363389
}

0 commit comments

Comments
 (0)