Skip to content

Commit 0a8161b

Browse files
authored
feat: Add config current-user command (#339)
## Summary Added new command under `config` command. Config command will now use `client.Config`instead of parsing the config itself, the effect is exactly the same. Refactored `printer` package a bit. ## Testing Added config e2e tests which check the new command's output with regex. ## Related changes nobl9/nobl9-go#726 ## Release Notes Added `sloctl config current-user` command which allows displaying current user (based on the access keys) details, like email, id, name and last name.
1 parent fd1ce39 commit 0a8161b

14 files changed

+304
-169
lines changed

go.mod

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/go-playground/validator/v10 v10.26.0
77
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db
88
github.com/nobl9/go-yaml v1.0.1
9-
github.com/nobl9/nobl9-go v0.102.0
9+
github.com/nobl9/nobl9-go v0.108.0
1010
github.com/pkg/errors v0.9.1
1111
github.com/schollz/progressbar/v3 v3.18.0
1212
github.com/spf13/cobra v1.9.1
@@ -24,7 +24,7 @@ require (
2424

2525
require (
2626
github.com/BurntSushi/toml v1.5.0 // indirect
27-
github.com/MicahParks/jwkset v0.9.5 // indirect
27+
github.com/MicahParks/jwkset v0.9.6 // indirect
2828
github.com/MicahParks/keyfunc/v3 v3.3.11 // indirect
2929
github.com/OpenSLO/go-sdk v0.6.0
3030
github.com/aws/aws-sdk-go v1.55.7 // indirect
@@ -34,7 +34,7 @@ require (
3434
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
3535
github.com/go-playground/locales v0.14.1 // indirect
3636
github.com/go-playground/universal-translator v0.18.1 // indirect
37-
github.com/goccy/go-yaml v1.17.1
37+
github.com/goccy/go-yaml v1.17.2-0.20250508142621-500180b7b722
3838
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
3939
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
4040
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
@@ -43,20 +43,20 @@ require (
4343
github.com/leodido/go-urn v1.4.0 // indirect
4444
github.com/mattn/go-colorable v0.1.14 // indirect
4545
github.com/mattn/go-isatty v0.0.20 // indirect
46-
github.com/nobl9/govy v0.16.0 // indirect
46+
github.com/nobl9/govy v0.18.0 // indirect
4747
github.com/nobl9/nobl9-openslo v0.1.0
4848
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
4949
github.com/rivo/uniseg v0.4.7 // indirect
5050
github.com/spf13/pflag v1.0.6 // indirect
5151
github.com/teambition/rrule-go v1.8.2 // indirect
52-
golang.org/x/crypto v0.37.0 // indirect
52+
golang.org/x/crypto v0.38.0 // indirect
5353
golang.org/x/mod v0.24.0 // indirect
54-
golang.org/x/net v0.39.0 // indirect
55-
golang.org/x/sys v0.32.0 // indirect
56-
golang.org/x/term v0.31.0 // indirect
57-
golang.org/x/text v0.24.0 // indirect
54+
golang.org/x/net v0.40.0 // indirect
55+
golang.org/x/sys v0.33.0 // indirect
56+
golang.org/x/term v0.32.0 // indirect
57+
golang.org/x/text v0.25.0 // indirect
5858
golang.org/x/time v0.11.0 // indirect
59-
golang.org/x/tools v0.32.0 // indirect
59+
golang.org/x/tools v0.33.0 // indirect
6060
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
6161
gopkg.in/yaml.v2 v2.4.0 // indirect
6262
gopkg.in/yaml.v3 v3.0.1 // indirect

go.sum

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
22
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
3-
github.com/MicahParks/jwkset v0.9.5 h1:/baA2n7RhO7nRIe1rx4ZX1Opeq+mwDuuWi2myDZwqnA=
4-
github.com/MicahParks/jwkset v0.9.5/go.mod h1:U2oRhRaLgDCLjtpGL2GseNKGmZtLs/3O7p+OZaL5vo0=
3+
github.com/MicahParks/jwkset v0.9.6 h1:Tf8l2/MOby5Kh3IkrqzThPQKfLytMERoAsGZKlyYZxg=
4+
github.com/MicahParks/jwkset v0.9.6/go.mod h1:U2oRhRaLgDCLjtpGL2GseNKGmZtLs/3O7p+OZaL5vo0=
55
github.com/MicahParks/keyfunc/v3 v3.3.11 h1:eA6wNltwdSRX2gtpTwZseBCC9nGeBkI9KxHtTyZbDbo=
66
github.com/MicahParks/keyfunc/v3 v3.3.11/go.mod h1:y6Ed3dMgNKTcpxbaQHD8mmrYDUZWJAxteddA6OQj+ag=
77
github.com/OpenSLO/go-sdk v0.6.0 h1:8VeLGqGaxc91YK49U0tcx/5GZ19sPfRBzcZKsZHJqtA=
@@ -28,8 +28,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
2828
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
2929
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
3030
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
31-
github.com/goccy/go-yaml v1.17.1 h1:LI34wktB2xEE3ONG/2Ar54+/HJVBriAGJ55PHls4YuY=
32-
github.com/goccy/go-yaml v1.17.1/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
31+
github.com/goccy/go-yaml v1.17.2-0.20250508142621-500180b7b722 h1:DHc9BORDIxpXjHd9UN4FUWmW82bTzDMokb5f05GEYA8=
32+
github.com/goccy/go-yaml v1.17.2-0.20250508142621-500180b7b722/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
3333
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
3434
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
3535
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -59,10 +59,10 @@ github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2Em
5959
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
6060
github.com/nobl9/go-yaml v1.0.1 h1:Aj1kSaYdRQTKlvS6ihvXzQJhCpoHhtf9nfA95zqWH4Q=
6161
github.com/nobl9/go-yaml v1.0.1/go.mod h1:t7vCO8ctYdBweZxU5lUgxzAw31+ZcqJYeqRtrv+5RHI=
62-
github.com/nobl9/govy v0.16.0 h1:VjMrkdFMt6CXGaqe6O8QZS7LhcntR5NAd0fG7WcAXSw=
63-
github.com/nobl9/govy v0.16.0/go.mod h1:yvhzfuWWVUJf7Txt1kMtwd6UsNTZqZZKJ8YyC3DYleE=
64-
github.com/nobl9/nobl9-go v0.102.0 h1:hhllq4uef16Vfa3mbdj4PGHsQpvSleaeNcZ8HVMlJ8U=
65-
github.com/nobl9/nobl9-go v0.102.0/go.mod h1:7DYLEwAGdzyAdcodeX8Clf8Ax6nJLqq06FNQVbt+Cw4=
62+
github.com/nobl9/govy v0.18.0 h1:EFNSFyS1ndAmWsHMvpR3T8vlLog4uvwtIjSUIKaJhW0=
63+
github.com/nobl9/govy v0.18.0/go.mod h1:t5EM5dz77gCzYx+U3Shf9/+lng+fwGRrD0k2hc99uuI=
64+
github.com/nobl9/nobl9-go v0.108.0 h1:avAECCtaNOm4abt14j6CLgwKDtz6a3BN2J6jK44QU4g=
65+
github.com/nobl9/nobl9-go v0.108.0/go.mod h1:3/479oqv21uxG/bKevH6Nr7OcigzOsbCzCjxjSonGrY=
6666
github.com/nobl9/nobl9-openslo v0.1.0 h1:RVHplfaIIbNfiSUohdjID8zi0CuDHTR7n7I5846e0e8=
6767
github.com/nobl9/nobl9-openslo v0.1.0/go.mod h1:pqoVxEPxI1WhtQ47gZcczgy0fDDrqPCQVZeZ5nahWIk=
6868
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -94,25 +94,25 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
9494
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
9595
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
9696
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
97-
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
98-
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
97+
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
98+
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
9999
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
100100
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
101-
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
102-
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
101+
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
102+
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
103103
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
104104
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
105105
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
106-
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
107-
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
108-
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
109-
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
110-
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
111-
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
106+
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
107+
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
108+
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
109+
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
110+
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
111+
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
112112
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
113113
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
114-
golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
115-
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
114+
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
115+
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
116116
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
117117
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
118118
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

internal/config.go

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import (
1313
"github.com/spf13/cobra"
1414

1515
"github.com/nobl9/nobl9-go/sdk"
16+
17+
"github.com/nobl9/sloctl/internal/printer"
1618
)
1719

1820
const defaultProject = "default"
@@ -25,37 +27,34 @@ Example: sloctl config rename-context [oldContext] [newContext]`)
2527
Example: sloctl config delete-context [contextName]`)
2628
)
2729

30+
type clientGetter interface {
31+
GetClient() *sdk.Client
32+
}
33+
2834
type ConfigCmd struct {
29-
config *sdk.FileConfig
30-
verbose bool
35+
clientGetter clientGetter
36+
config *sdk.FileConfig
37+
printer *printer.Printer
38+
verbose bool
3139
}
3240

3341
func (r *RootCmd) NewConfigCmd() *cobra.Command {
34-
configCmd := ConfigCmd{}
42+
configCmd := &ConfigCmd{
43+
clientGetter: r,
44+
printer: printer.NewPrinter(printer.Config{}),
45+
}
3546
cmd := &cobra.Command{
3647
Use: "config",
3748
Short: "Configuration management",
3849
Long: `Manage configurations stored in configuration file.`,
3950
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
40-
fileConfig := new(sdk.FileConfig)
41-
configPath := r.Flags.ConfigFile
42-
if configPath == "" {
43-
var err error
44-
configPath, err = sdk.GetDefaultConfigPath()
45-
if err != nil {
46-
return err
47-
}
48-
}
49-
if err := fileConfig.Load(configPath); err != nil {
50-
return err
51-
}
52-
configCmd.config = fileConfig
53-
return nil
51+
return configCmd.loadFileConfig(r.Flags.ConfigFile)
5452
},
5553
}
5654

5755
cmd.AddCommand(configCmd.AddContextCommand())
5856
cmd.AddCommand(configCmd.CurrentContextCommand())
57+
cmd.AddCommand(configCmd.CurrentUserCommand())
5958
cmd.AddCommand(configCmd.GetContextsCommand())
6059
cmd.AddCommand(configCmd.RenameContextCommand())
6160
cmd.AddCommand(configCmd.DeleteContextCommand())
@@ -64,6 +63,18 @@ func (r *RootCmd) NewConfigCmd() *cobra.Command {
6463
return cmd
6564
}
6665

66+
func (c *ConfigCmd) loadFileConfig(configPath string) error {
67+
if configPath == "" {
68+
var err error
69+
configPath, err = sdk.GetDefaultConfigPath()
70+
if err != nil {
71+
return err
72+
}
73+
}
74+
c.config = new(sdk.FileConfig)
75+
return c.config.Load(configPath)
76+
}
77+
6778
// AddContextCommand returns cobra command add-context, allows to add context to your configuration file.
6879
func (c *ConfigCmd) AddContextCommand() *cobra.Command {
6980
return &cobra.Command{
@@ -281,7 +292,7 @@ func (c *ConfigCmd) CurrentContextCommand() *cobra.Command {
281292
Long: "Display configuration for the current context set in the configuration file.",
282293
RunE: func(cmd *cobra.Command, args []string) error {
283294
if c.verbose {
284-
currentContext := displayContext(c.config.DefaultContext,
295+
currentContext := buildContextString(c.config.DefaultContext,
285296
c.config.Contexts[c.config.DefaultContext],
286297
c.verbose)
287298
fmt.Print(currentContext)
@@ -297,6 +308,34 @@ func (c *ConfigCmd) CurrentContextCommand() *cobra.Command {
297308
return currentCtxCmd
298309
}
299310

311+
func (c *ConfigCmd) CurrentUserCommand() *cobra.Command {
312+
currentUserCmd := &cobra.Command{
313+
Use: "current-user",
314+
Short: "Display current user details",
315+
Long: "Display extended details for the user associated with the current context's access key.",
316+
RunE: func(cmd *cobra.Command, args []string) error {
317+
client := c.clientGetter.GetClient()
318+
ctx := cmd.Context()
319+
userID, err := client.GetUser(ctx)
320+
if err != nil {
321+
return err
322+
}
323+
user, err := client.Users().V2().GetUser(ctx, userID)
324+
if err != nil {
325+
return err
326+
}
327+
if err = c.printer.Print(user); err != nil {
328+
return err
329+
}
330+
return nil
331+
},
332+
}
333+
334+
c.printer.MustRegisterFlags(currentUserCmd)
335+
336+
return currentUserCmd
337+
}
338+
300339
// GetContextsCommand returns cobra command to prints all available contexts.
301340
func (c *ConfigCmd) GetContextsCommand() *cobra.Command {
302341
getContextsCmd := &cobra.Command{
@@ -312,7 +351,7 @@ func (c *ConfigCmd) GetContextsCommand() *cobra.Command {
312351
var fullConfig string
313352
if len(args) == 0 && c.verbose {
314353
for _, name := range names {
315-
singleConfig := displayContext(name, c.config.Contexts[name], true)
354+
singleConfig := buildContextString(name, c.config.Contexts[name], true)
316355
fullConfig += singleConfig + "\n"
317356
}
318357
fmt.Printf("[%s]\n%s", strings.Join(names, ", "), fullConfig)
@@ -323,7 +362,7 @@ func (c *ConfigCmd) GetContextsCommand() *cobra.Command {
323362
fullConfig += fmt.Sprintf("Missing context: %s\n\n", name)
324363
continue
325364
}
326-
singleConfig := displayContext(name, c.config.Contexts[name], true)
365+
singleConfig := buildContextString(name, c.config.Contexts[name], true)
327366
fullConfig += singleConfig + "\n"
328367
}
329368
fmt.Printf("[%s]\n%s", strings.Join(names, ", "), fullConfig)
@@ -336,7 +375,7 @@ func (c *ConfigCmd) GetContextsCommand() *cobra.Command {
336375
return getContextsCmd
337376
}
338377

339-
func displayContext(name string, config sdk.ContextConfig, verbose bool) string {
378+
func buildContextString(name string, config sdk.ContextConfig, verbose bool) string {
340379
var sb strings.Builder
341380
sb.WriteString(fmt.Sprintf("Context: %s\n", name))
342381
if !verbose {

internal/printer/csv.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package printer
2+
3+
import (
4+
"io"
5+
6+
"github.com/nobl9/sloctl/internal/csv"
7+
)
8+
9+
type csvPrinter struct {
10+
out io.Writer
11+
fieldSeparator string
12+
recordSeparator string
13+
}
14+
15+
func (p *csvPrinter) Print(content any) error {
16+
b, err := csv.Marshal(content, p.fieldSeparator, p.recordSeparator)
17+
if err != nil {
18+
return err
19+
}
20+
_, err = p.out.Write(b)
21+
return err
22+
}

internal/printer/flags.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package printer
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
6+
"github.com/nobl9/sloctl/internal/csv"
7+
)
8+
9+
func (o *Printer) MustRegisterFlags(cmd *cobra.Command) {
10+
cmd.PersistentFlags().VarP(
11+
&o.config.OutputFormat,
12+
"output",
13+
"o",
14+
`Output format: one of yaml|json|csv.`,
15+
)
16+
17+
cmd.PersistentFlags().StringVarP(
18+
&o.config.CSVFieldSeparator,
19+
csv.FieldSeparatorFlag,
20+
"",
21+
csv.DefaultFieldSeparator,
22+
"Field Separator for CSV.",
23+
)
24+
if err := cmd.PersistentFlags().MarkHidden(csv.FieldSeparatorFlag); err != nil {
25+
panic(err)
26+
}
27+
28+
cmd.PersistentFlags().StringVarP(
29+
&o.config.CSVRecordSeparator,
30+
csv.RecordSeparatorFlag,
31+
"",
32+
csv.DefaultRecordSeparator,
33+
"Record Separator for CSV.",
34+
)
35+
if err := cmd.PersistentFlags().MarkHidden(csv.RecordSeparatorFlag); err != nil {
36+
panic(err)
37+
}
38+
}

internal/printer/json.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package printer
2+
3+
import (
4+
"encoding/json"
5+
"io"
6+
7+
"github.com/nobl9/nobl9-go/manifest"
8+
"github.com/nobl9/nobl9-go/sdk"
9+
)
10+
11+
type jsonPrinter struct {
12+
out io.Writer
13+
}
14+
15+
func (p *jsonPrinter) Print(content any) error {
16+
switch v := content.(type) {
17+
case []manifest.Object:
18+
return sdk.PrintObjects(v, p.out, manifest.ObjectFormatJSON)
19+
default:
20+
b, err := json.MarshalIndent(content, "", " ")
21+
if err != nil {
22+
return err
23+
}
24+
_, err = p.out.Write(b)
25+
return err
26+
}
27+
}

0 commit comments

Comments
 (0)