From d4ca01592c225a6cf99195ea7439ea260cb6257a Mon Sep 17 00:00:00 2001 From: Integralist Date: Tue, 18 Apr 2023 13:12:41 +0100 Subject: [PATCH 1/2] refactor: consistent json implementation --- pkg/commands/acl/describe.go | 33 +++----- pkg/commands/acl/list.go | 35 +++------ pkg/commands/aclentry/describe.go | 33 +++----- pkg/commands/aclentry/list.go | 37 +++------ pkg/commands/authtoken/describe.go | 33 +++----- pkg/commands/authtoken/list.go | 39 +++------- pkg/commands/backend/describe.go | 34 +++------ pkg/commands/backend/list.go | 38 +++------- pkg/commands/dictionary/describe.go | 31 +++----- pkg/commands/dictionary/list.go | 30 ++------ pkg/commands/dictionaryentry/describe.go | 30 ++------ pkg/commands/dictionaryentry/list.go | 34 +++------ pkg/commands/domain/describe.go | 36 +++------ pkg/commands/domain/list.go | 34 +++------ pkg/commands/healthcheck/describe.go | 34 +++------ pkg/commands/healthcheck/list.go | 42 ++++------- pkg/commands/kvstore/create.go | 27 ++----- pkg/commands/kvstore/describe.go | 27 ++----- pkg/commands/kvstore/list.go | 27 ++----- pkg/commands/kvstoreentry/describe.go | 14 ++-- pkg/commands/kvstoreentry/list.go | 27 ++----- pkg/commands/logging/azureblob/describe.go | 66 +++++++--------- pkg/commands/logging/azureblob/list.go | 38 +++------- pkg/commands/logging/bigquery/describe.go | 57 ++++++-------- pkg/commands/logging/bigquery/list.go | 38 +++------- pkg/commands/logging/cloudfiles/describe.go | 64 +++++++--------- pkg/commands/logging/cloudfiles/list.go | 38 +++------- pkg/commands/logging/datadog/describe.go | 48 +++++------- pkg/commands/logging/datadog/list.go | 38 +++------- pkg/commands/logging/digitalocean/describe.go | 63 ++++++---------- pkg/commands/logging/digitalocean/list.go | 38 +++------- .../logging/elasticsearch/describe.go | 62 ++++++--------- pkg/commands/logging/elasticsearch/list.go | 38 +++------- pkg/commands/logging/ftp/describe.go | 63 ++++++---------- pkg/commands/logging/ftp/list.go | 38 +++------- pkg/commands/logging/gcs/describe.go | 63 ++++++---------- pkg/commands/logging/gcs/list.go | 38 +++------- pkg/commands/logging/googlepubsub/describe.go | 53 +++++-------- pkg/commands/logging/googlepubsub/list.go | 38 +++------- pkg/commands/logging/heroku/describe.go | 47 ++++-------- pkg/commands/logging/heroku/list.go | 38 +++------- pkg/commands/logging/honeycomb/describe.go | 47 ++++-------- pkg/commands/logging/honeycomb/list.go | 38 +++------- pkg/commands/logging/https/describe.go | 69 +++++++---------- pkg/commands/logging/https/list.go | 38 +++------- pkg/commands/logging/kafka/describe.go | 71 +++++++----------- pkg/commands/logging/kafka/list.go | 38 +++------- pkg/commands/logging/kinesis/describe.go | 57 ++++++-------- pkg/commands/logging/kinesis/list.go | 38 +++------- pkg/commands/logging/loggly/describe.go | 45 ++++------- pkg/commands/logging/loggly/list.go | 38 +++------- pkg/commands/logging/logshuttle/describe.go | 47 ++++-------- pkg/commands/logging/logshuttle/list.go | 38 +++------- pkg/commands/logging/newrelic/describe.go | 34 +++------ pkg/commands/logging/newrelic/list.go | 35 +++------ pkg/commands/logging/openstack/describe.go | 65 +++++++--------- pkg/commands/logging/openstack/list.go | 38 +++------- pkg/commands/logging/papertrail/describe.go | 47 ++++-------- pkg/commands/logging/papertrail/list.go | 38 +++------- pkg/commands/logging/s3/describe.go | 75 ++++++++----------- pkg/commands/logging/s3/list.go | 38 +++------- pkg/commands/logging/scalyr/describe.go | 47 ++++-------- pkg/commands/logging/scalyr/list.go | 38 +++------- pkg/commands/logging/sftp/describe.go | 69 +++++++---------- pkg/commands/logging/sftp/list.go | 38 +++------- pkg/commands/logging/splunk/describe.go | 55 +++++--------- pkg/commands/logging/splunk/list.go | 38 +++------- pkg/commands/logging/sumologic/describe.go | 47 ++++-------- pkg/commands/logging/sumologic/list.go | 38 +++------- pkg/commands/logging/syslog/describe.go | 65 +++++++--------- pkg/commands/logging/syslog/list.go | 38 +++------- pkg/commands/profile/list.go | 27 ++----- pkg/commands/resourcelink/create.go | 6 +- pkg/commands/resourcelink/describe.go | 10 +-- pkg/commands/resourcelink/list.go | 8 +- pkg/commands/resourcelink/update.go | 6 +- pkg/commands/service/describe.go | 34 +++------ pkg/commands/service/list.go | 40 ++++------ pkg/commands/serviceauth/describe.go | 34 +++------ pkg/commands/serviceauth/list.go | 38 +++------- pkg/commands/serviceversion/list.go | 40 ++++------ pkg/commands/tls/config/describe.go | 33 +++----- pkg/commands/tls/config/list.go | 35 +++------ .../tls/custom/activation/describe.go | 33 +++----- pkg/commands/tls/custom/activation/list.go | 35 +++------ .../tls/custom/certificate/describe.go | 33 +++----- pkg/commands/tls/custom/certificate/list.go | 35 +++------ pkg/commands/tls/custom/domain/list.go | 35 +++------ .../tls/custom/privatekey/describe.go | 33 +++----- pkg/commands/tls/custom/privatekey/list.go | 35 +++------ pkg/commands/tls/platform/describe.go | 33 +++----- pkg/commands/tls/platform/list.go | 35 +++------ pkg/commands/tls/subscription/describe.go | 34 +++------ pkg/commands/tls/subscription/list.go | 35 +++------ pkg/commands/user/describe.go | 35 +++++---- pkg/commands/user/list.go | 34 +++------ pkg/commands/vcl/custom/describe.go | 33 +++----- pkg/commands/vcl/custom/list.go | 35 +++------ pkg/commands/vcl/snippet/describe.go | 57 +++++--------- pkg/commands/vcl/snippet/list.go | 35 +++------ 100 files changed, 1298 insertions(+), 2666 deletions(-) diff --git a/pkg/commands/acl/describe.go b/pkg/commands/acl/describe.go index 75fc0b1b5..dc5df65f2 100644 --- a/pkg/commands/acl/describe.go +++ b/pkg/commands/acl/describe.go @@ -1,7 +1,6 @@ package acl import ( - "encoding/json" "fmt" "io" @@ -32,12 +31,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -57,8 +51,8 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput - json bool manifest manifest.Data name string serviceName cmd.OptionalServiceNameID @@ -67,7 +61,7 @@ type DescribeCommand struct { // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,7 +84,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { input := c.constructInput(serviceID, serviceVersion.Number) - a, err := c.Globals.APIClient.GetACL(input) + o, err := c.Globals.APIClient.GetACL(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -99,7 +93,11 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, a) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. @@ -115,19 +113,6 @@ func (c *DescribeCommand) constructInput(serviceID string, serviceVersion int) * // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, a *fastly.ACL) error { - if c.json { - data, err := json.Marshal(a) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - if !c.Globals.Verbose() { fmt.Fprintf(out, "\nService ID: %s\n", a.ServiceID) } diff --git a/pkg/commands/acl/list.go b/pkg/commands/acl/list.go index bf5ca537e..1b302cfa6 100644 --- a/pkg/commands/acl/list.go +++ b/pkg/commands/acl/list.go @@ -1,7 +1,6 @@ package acl import ( - "encoding/json" "fmt" "io" @@ -32,12 +31,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -57,8 +51,8 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput - json bool manifest manifest.Data serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion @@ -66,7 +60,7 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +83,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { input := c.constructInput(serviceID, serviceVersion.Number) - as, err := c.Globals.APIClient.ListACLs(input) + o, err := c.Globals.APIClient.ListACLs(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,10 +92,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - c.printVerbose(out, serviceVersion.Number, as) + c.printVerbose(out, serviceVersion.Number, o) } else { - err = c.printSummary(out, as) + err = c.printSummary(out, o) if err != nil { return err } @@ -145,19 +143,6 @@ func (c *ListCommand) printVerbose(out io.Writer, serviceVersion int, as []*fast // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, as []*fastly.ACL) error { - if c.json { - data, err := json.Marshal(as) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("SERVICE ID", "VERSION", "NAME", "ID") for _, a := range as { diff --git a/pkg/commands/aclentry/describe.go b/pkg/commands/aclentry/describe.go index 590c757f6..deb21177b 100644 --- a/pkg/commands/aclentry/describe.go +++ b/pkg/commands/aclentry/describe.go @@ -1,7 +1,6 @@ package aclentry import ( - "encoding/json" "fmt" "io" @@ -27,12 +26,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) c.CmdClause.Flag("id", "Alphanumeric string identifying an ACL Entry").Required().StringVar(&c.id) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -52,17 +46,17 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput aclID string id string - json bool manifest manifest.Data serviceName cmd.OptionalServiceNameID } // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -76,7 +70,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { input := c.constructInput(serviceID) - a, err := c.Globals.APIClient.GetACLEntry(input) + o, err := c.Globals.APIClient.GetACLEntry(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -84,7 +78,11 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, a) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. @@ -100,19 +98,6 @@ func (c *DescribeCommand) constructInput(serviceID string) *fastly.GetACLEntryIn // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, a *fastly.ACLEntry) error { - if c.json { - data, err := json.Marshal(a) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - if !c.Globals.Verbose() { fmt.Fprintf(out, "\nService ID: %s\n", a.ServiceID) } diff --git a/pkg/commands/aclentry/list.go b/pkg/commands/aclentry/list.go index ab44ef69a..3c192b2eb 100644 --- a/pkg/commands/aclentry/list.go +++ b/pkg/commands/aclentry/list.go @@ -1,7 +1,6 @@ package aclentry import ( - "encoding/json" "fmt" "io" @@ -27,12 +26,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis c.CmdClause.Flag("acl-id", "Alphanumeric string identifying a ACL").Required().StringVar(&c.aclID) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -57,10 +51,10 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput aclID string direction string - json bool manifest manifest.Data page int perPage int @@ -70,7 +64,7 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -87,7 +81,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { // TODO: Use generics support in go 1.18 to replace this almost identical // logic inside of 'dictionary-item list' and 'service list'. - var as []*fastly.ACLEntry + var o []*fastly.ACLEntry for paginator.HasNext() { data, err := paginator.GetNext() if err != nil { @@ -98,13 +92,17 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { }) return err } - as = append(as, data...) + o = append(o, data...) + } + + if ok, err := c.WriteJSON(out, o); ok { + return err } if c.Globals.Verbose() { - c.printVerbose(out, as) + c.printVerbose(out, o) } else { - err = c.printSummary(out, as) + err = c.printSummary(out, o) if err != nil { return err } @@ -154,19 +152,6 @@ func (c *ListCommand) printVerbose(out io.Writer, as []*fastly.ACLEntry) { // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, as []*fastly.ACLEntry) error { - if c.json { - data, err := json.Marshal(as) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("SERVICE ID", "ID", "IP", "SUBNET", "NEGATED") for _, a := range as { diff --git a/pkg/commands/authtoken/describe.go b/pkg/commands/authtoken/describe.go index 48495fe09..e4dc3c5c8 100644 --- a/pkg/commands/authtoken/describe.go +++ b/pkg/commands/authtoken/describe.go @@ -1,7 +1,6 @@ package authtoken import ( - "encoding/json" "fmt" "io" "strings" @@ -24,20 +23,15 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) } c.CmdClause = parent.Command("describe", "Get the current API token").Alias("get") - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput - json bool manifest manifest.Data } @@ -47,34 +41,25 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { if s == lookup.SourceUndefined { return fsterr.ErrNoToken } - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } - r, err := c.Globals.APIClient.GetTokenSelf() + o, err := c.Globals.APIClient.GetTokenSelf() if err != nil { c.Globals.ErrLog.Add(err) return err } - return c.print(out, r) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, r *fastly.Token) error { - if c.json { - data, err := json.Marshal(r) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - fmt.Fprintf(out, "\nID: %s\n", r.ID) fmt.Fprintf(out, "Name: %s\n", r.Name) fmt.Fprintf(out, "User ID: %s\n", r.UserID) diff --git a/pkg/commands/authtoken/list.go b/pkg/commands/authtoken/list.go index 2e733159b..a1d758052 100644 --- a/pkg/commands/authtoken/list.go +++ b/pkg/commands/authtoken/list.go @@ -1,7 +1,6 @@ package authtoken import ( - "encoding/json" "fmt" "io" "strings" @@ -31,21 +30,16 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis Dst: &c.customerID.Value, Action: c.customerID.Set, }) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput customerID cmd.OptionalCustomerID - json bool manifest manifest.Data } @@ -55,13 +49,13 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { if s == lookup.SourceUndefined { return fsterr.ErrNoToken } - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } var ( err error - rs []*fastly.Token + o []*fastly.Token ) if err = c.customerID.Parse(); err == nil { @@ -72,23 +66,27 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { input := c.constructInput() - rs, err = c.Globals.APIClient.ListCustomerTokens(input) + o, err = c.Globals.APIClient.ListCustomerTokens(input) if err != nil { c.Globals.ErrLog.Add(err) return err } } else { - rs, err = c.Globals.APIClient.ListTokens() + o, err = c.Globals.APIClient.ListTokens() if err != nil { c.Globals.ErrLog.Add(err) return err } } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - c.printVerbose(out, rs) + c.printVerbose(out, o) } else { - err = c.printSummary(out, rs) + err = c.printSummary(out, o) if err != nil { return err } @@ -132,19 +130,6 @@ func (c *ListCommand) printVerbose(out io.Writer, rs []*fastly.Token) { // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, rs []*fastly.Token) error { - if c.json { - data, err := json.Marshal(rs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("NAME", "TOKEN ID", "USER ID", "SCOPE", "SERVICES") for _, r := range rs { diff --git a/pkg/commands/backend/describe.go b/pkg/commands/backend/describe.go index 2b9f0321b..693f89b0f 100644 --- a/pkg/commands/backend/describe.go +++ b/pkg/commands/backend/describe.go @@ -1,7 +1,6 @@ package backend import ( - "encoding/json" "fmt" "io" @@ -15,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a backend. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetBackendInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +84,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - backend, err := c.Globals.APIClient.GetBackend(&c.Input) + o, err := c.Globals.APIClient.GetBackend(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,24 +93,15 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, backend) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, b *fastly.Backend) error { - if c.json { - data, err := json.Marshal(b) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - if !c.Globals.Verbose() { fmt.Fprintf(out, "\nService ID: %s\n", b.ServiceID) } diff --git a/pkg/commands/backend/list.go b/pkg/commands/backend/list.go index 55a4eb6f7..afaf3080c 100644 --- a/pkg/commands/backend/list.go +++ b/pkg/commands/backend/list.go @@ -1,7 +1,6 @@ package backend import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list backends. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListBackendsInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +84,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - backends, err := c.Globals.APIClient.ListBackends(&c.Input) + o, err := c.Globals.APIClient.ListBackends(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,23 +93,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(backends) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME", "ADDRESS", "PORT", "COMMENT") - for _, backend := range backends { + for _, backend := range o { tw.AddLine(backend.ServiceID, backend.ServiceVersion, backend.Name, backend.Address, backend.Port, backend.Comment) } tw.Print() @@ -122,8 +108,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, backend := range backends { - fmt.Fprintf(out, "\tBackend %d/%d\n", i+1, len(backends)) + for i, backend := range o { + fmt.Fprintf(out, "\tBackend %d/%d\n", i+1, len(o)) text.PrintBackend(out, "\t\t", backend) } fmt.Fprintln(out) diff --git a/pkg/commands/dictionary/describe.go b/pkg/commands/dictionary/describe.go index 329821759..da46d76ae 100644 --- a/pkg/commands/dictionary/describe.go +++ b/pkg/commands/dictionary/describe.go @@ -1,8 +1,6 @@ package dictionary import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a dictionary. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetDictionaryInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -103,7 +97,8 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { info *fastly.DictionaryInfo items []*fastly.DictionaryItem ) - if c.Globals.Verbose() || c.json { + + if c.Globals.Verbose() || c.JSONOutput.Enabled { infoInput := fastly.GetDictionaryInfoInput{ ServiceID: c.Input.ServiceID, ServiceVersion: c.Input.ServiceVersion, @@ -131,7 +126,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { } } - if c.json { + if c.JSONOutput.Enabled { // NOTE: When not using JSON you have to provide the --verbose flag to get // some extra information about the dictionary. When using --json we go // ahead and acquire that info and combine it into the JSON output. @@ -140,16 +135,12 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { *fastly.DictionaryInfo Items []*fastly.DictionaryItem } - data, err := json.Marshal(&container{Dictionary: dictionary, DictionaryInfo: info, Items: items}) - if err != nil { + + o := &container{Dictionary: dictionary, DictionaryInfo: info, Items: items} + + if ok, err := c.WriteJSON(out, o); ok { return err } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil } if !c.Globals.Verbose() { diff --git a/pkg/commands/dictionary/list.go b/pkg/commands/dictionary/list.go index a719d1593..1a2ae5b82 100644 --- a/pkg/commands/dictionary/list.go +++ b/pkg/commands/dictionary/list.go @@ -1,7 +1,6 @@ package dictionary import ( - "encoding/json" "fmt" "io" @@ -16,7 +15,8 @@ import ( // ListCommand calls the Fastly API to list dictionaries type ListCommand struct { cmd.Base - json bool + cmd.JSONOutput + manifest manifest.Data Input fastly.ListDictionariesInput serviceName cmd.OptionalServiceNameID @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } serviceID, serviceVersion, err := cmd.ServiceDetails(cmd.ServiceDetailsOpts{ @@ -88,7 +83,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - dictionaries, err := c.Globals.APIClient.ListDictionaries(&c.Input) + o, err := c.Globals.APIClient.ListDictionaries(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -97,24 +92,15 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(dictionaries) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } if !c.Globals.Verbose() { fmt.Fprintf(out, "\nService ID: %s\n", serviceID) } text.Output(out, "Version: %d", c.Input.ServiceVersion) - for _, dictionary := range dictionaries { + for _, dictionary := range o { text.PrintDictionary(out, "", dictionary) } diff --git a/pkg/commands/dictionaryentry/describe.go b/pkg/commands/dictionaryentry/describe.go index 009b1d773..1d7378870 100644 --- a/pkg/commands/dictionaryentry/describe.go +++ b/pkg/commands/dictionaryentry/describe.go @@ -1,7 +1,6 @@ package dictionaryentry import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // DescribeCommand calls the Fastly API to describe a dictionary item. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetDictionaryItemInput - json bool serviceName cmd.OptionalServiceNameID } @@ -37,12 +37,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) c.CmdClause.Flag("key", "Dictionary item key").Required().StringVar(&c.Input.ItemKey) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -61,7 +56,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -75,7 +70,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID - item, err := c.Globals.APIClient.GetDictionaryItem(&c.Input) + o, err := c.Globals.APIClient.GetDictionaryItem(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -83,22 +78,13 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(item) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } if !c.Globals.Verbose() { fmt.Fprintf(out, "\nService ID: %s\n", c.Input.ServiceID) } - text.PrintDictionaryItem(out, "", item) + text.PrintDictionaryItem(out, "", o) return nil } diff --git a/pkg/commands/dictionaryentry/list.go b/pkg/commands/dictionaryentry/list.go index 4aeb0e92a..827997948 100644 --- a/pkg/commands/dictionaryentry/list.go +++ b/pkg/commands/dictionaryentry/list.go @@ -1,7 +1,6 @@ package dictionaryentry import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list dictionary items. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data input fastly.ListDictionaryItemsInput - json bool serviceName cmd.OptionalServiceNameID } @@ -37,12 +37,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // optional c.CmdClause.Flag("direction", "Direction in which to sort results").Default(cmd.PaginationDirection[0]).HintOptions(cmd.PaginationDirection...).EnumVar(&c.input.Direction, cmd.PaginationDirection...) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.CmdClause.Flag("page", "Page number of data set to fetch").IntVar(&c.input.Page) c.CmdClause.Flag("per-page", "Number of records per page").IntVar(&c.input.PerPage) c.RegisterFlag(cmd.StringFlagOpts{ @@ -63,7 +58,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -78,7 +73,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.input.ServiceID = serviceID paginator := c.Globals.APIClient.NewListDictionaryItemsPaginator(&c.input) - var ds []*fastly.DictionaryItem + var o []*fastly.DictionaryItem for paginator.HasNext() { data, err := paginator.GetNext() if err != nil { @@ -89,27 +84,18 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { }) return err } - ds = append(ds, data...) + o = append(o, data...) } - if c.json { - data, err := json.Marshal(ds) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } if !c.Globals.Verbose() { fmt.Fprintf(out, "\nService ID: %s\n", c.input.ServiceID) } - for i, dictionary := range ds { - text.Output(out, "Item: %d/%d", i+1, len(ds)) + for i, dictionary := range o { + text.Output(out, "Item: %d/%d", i+1, len(o)) text.PrintDictionaryItem(out, "\t", dictionary) text.Break(out) } diff --git a/pkg/commands/domain/describe.go b/pkg/commands/domain/describe.go index 0da05870f..7685e5736 100644 --- a/pkg/commands/domain/describe.go +++ b/pkg/commands/domain/describe.go @@ -1,7 +1,6 @@ package domain import ( - "encoding/json" "fmt" "io" @@ -15,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a domain. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetDomainInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +84,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - domain, err := c.Globals.APIClient.GetDomain(&c.Input) + o, err := c.Globals.APIClient.GetDomain(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,25 +93,16 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(domain) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } if !c.Globals.Verbose() { - fmt.Fprintf(out, "\nService ID: %s\n", domain.ServiceID) + fmt.Fprintf(out, "\nService ID: %s\n", o.ServiceID) } - fmt.Fprintf(out, "Version: %d\n", domain.ServiceVersion) - fmt.Fprintf(out, "Name: %s\n", domain.Name) - fmt.Fprintf(out, "Comment: %v\n", domain.Comment) + fmt.Fprintf(out, "Version: %d\n", o.ServiceVersion) + fmt.Fprintf(out, "Name: %s\n", o.Name) + fmt.Fprintf(out, "Comment: %v\n", o.Comment) return nil } diff --git a/pkg/commands/domain/list.go b/pkg/commands/domain/list.go index 0f5680767..7fea638ce 100644 --- a/pkg/commands/domain/list.go +++ b/pkg/commands/domain/list.go @@ -1,7 +1,6 @@ package domain import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list domains. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListDomainsInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +84,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - domains, err := c.Globals.APIClient.ListDomains(&c.Input) + o, err := c.Globals.APIClient.ListDomains(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,23 +93,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(domains) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME", "COMMENT") - for _, domain := range domains { + for _, domain := range o { tw.AddLine(domain.ServiceID, domain.ServiceVersion, domain.Name, domain.Comment) } tw.Print() @@ -122,8 +108,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, domain := range domains { - fmt.Fprintf(out, "\tDomain %d/%d\n", i+1, len(domains)) + for i, domain := range o { + fmt.Fprintf(out, "\tDomain %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tName: %s\n", domain.Name) fmt.Fprintf(out, "\t\tComment: %v\n", domain.Comment) } diff --git a/pkg/commands/healthcheck/describe.go b/pkg/commands/healthcheck/describe.go index bc730bca0..929d0e9c7 100644 --- a/pkg/commands/healthcheck/describe.go +++ b/pkg/commands/healthcheck/describe.go @@ -1,7 +1,6 @@ package healthcheck import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // DescribeCommand calls the Fastly API to describe a healthcheck. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetHealthCheckInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +43,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +61,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,7 +85,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - healthCheck, err := c.Globals.APIClient.GetHealthCheck(&c.Input) + o, err := c.Globals.APIClient.GetHealthCheck(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -99,24 +94,15 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(healthCheck) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } if !c.Globals.Verbose() { - fmt.Fprintf(out, "\nService ID: %s\n", healthCheck.ServiceID) + fmt.Fprintf(out, "\nService ID: %s\n", o.ServiceID) } - fmt.Fprintf(out, "Version: %d\n", healthCheck.ServiceVersion) - text.PrintHealthCheck(out, "", healthCheck) + fmt.Fprintf(out, "Version: %d\n", o.ServiceVersion) + text.PrintHealthCheck(out, "", o) return nil } diff --git a/pkg/commands/healthcheck/list.go b/pkg/commands/healthcheck/list.go index 2a74bf5ee..50202a892 100644 --- a/pkg/commands/healthcheck/list.go +++ b/pkg/commands/healthcheck/list.go @@ -1,7 +1,6 @@ package healthcheck import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list healthchecks. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListHealthChecksInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +84,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - healthChecks, err := c.Globals.APIClient.ListHealthChecks(&c.Input) + o, err := c.Globals.APIClient.ListHealthChecks(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,33 +93,24 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(healthChecks) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME", "METHOD", "HOST", "PATH") - for _, healthCheck := range healthChecks { - tw.AddLine(healthCheck.ServiceID, healthCheck.ServiceVersion, healthCheck.Name, healthCheck.Method, healthCheck.Host, healthCheck.Path) + for _, hc := range o { + tw.AddLine(hc.ServiceID, hc.ServiceVersion, hc.Name, hc.Method, hc.Host, hc.Path) } tw.Print() return nil } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, healthCheck := range healthChecks { - fmt.Fprintf(out, "\tHealthcheck %d/%d\n", i+1, len(healthChecks)) - text.PrintHealthCheck(out, "\t\t", healthCheck) + for i, hc := range o { + fmt.Fprintf(out, "\tHealthcheck %d/%d\n", i+1, len(o)) + text.PrintHealthCheck(out, "\t\t", hc) } fmt.Fprintln(out) diff --git a/pkg/commands/kvstore/create.go b/pkg/commands/kvstore/create.go index 87d14866d..3ac985197 100644 --- a/pkg/commands/kvstore/create.go +++ b/pkg/commands/kvstore/create.go @@ -1,8 +1,6 @@ package kvstore import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,7 +14,8 @@ import ( // CreateCommand calls the Fastly API to create an kv store. type CreateCommand struct { cmd.Base - json bool + cmd.JSONOutput + manifest manifest.Data Input fastly.CreateKVStoreInput } @@ -31,18 +30,13 @@ func NewCreateCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *C } c.CmdClause = parent.Command("create", "Create an kv store") c.CmdClause.Flag("name", "Name of KV Store").Short('n').Required().StringVar(&c.Input.Name) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } // Exec invokes the application logic for the command. func (c *CreateCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -52,17 +46,8 @@ func (c *CreateCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(o) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } text.Success(out, "Created kv store %s (name %s)", o.ID, o.Name) diff --git a/pkg/commands/kvstore/describe.go b/pkg/commands/kvstore/describe.go index 9a44b54f2..2e105ff48 100644 --- a/pkg/commands/kvstore/describe.go +++ b/pkg/commands/kvstore/describe.go @@ -1,8 +1,6 @@ package kvstore import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,7 +14,8 @@ import ( // DescribeCommand calls the Fastly API to fetch the value of a key from an kv store. type DescribeCommand struct { cmd.Base - json bool + cmd.JSONOutput + manifest manifest.Data Input fastly.GetKVStoreInput } @@ -33,19 +32,14 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) c.CmdClause.Flag("store-id", "Store ID").Short('s').Required().StringVar(&c.Input.ID) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -55,17 +49,8 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(o) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } text.PrintKVStore(out, "", o) diff --git a/pkg/commands/kvstore/list.go b/pkg/commands/kvstore/list.go index 54d06d802..f143ec087 100644 --- a/pkg/commands/kvstore/list.go +++ b/pkg/commands/kvstore/list.go @@ -1,8 +1,6 @@ package kvstore import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,7 +14,8 @@ import ( // ListCommand calls the Fastly API to list the available kv stores. type ListCommand struct { cmd.Base - json bool + cmd.JSONOutput + manifest manifest.Data Input fastly.ListKVStoresInput } @@ -32,19 +31,14 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis c.CmdClause = parent.Command("list", "List kv stores") // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -54,17 +48,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(o) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } for _, o := range o.Data { diff --git a/pkg/commands/kvstoreentry/describe.go b/pkg/commands/kvstoreentry/describe.go index 7bd6418f8..beeea405b 100644 --- a/pkg/commands/kvstoreentry/describe.go +++ b/pkg/commands/kvstoreentry/describe.go @@ -14,7 +14,8 @@ import ( // DescribeCommand calls the Fastly API to fetch the value of a key from an kv store. type DescribeCommand struct { cmd.Base - json bool + cmd.JSONOutput + manifest manifest.Data Input fastly.GetKVStoreKeyInput } @@ -32,19 +33,14 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) c.CmdClause.Flag("key-name", "Key name").Short('k').Required().StringVar(&c.Input.Key) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -54,7 +50,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { + if c.JSONOutput.Enabled { text.Output(out, `{"%s": "%s"}`, c.Input.Key, value) return nil } diff --git a/pkg/commands/kvstoreentry/list.go b/pkg/commands/kvstoreentry/list.go index e7abd1b02..614e9454c 100644 --- a/pkg/commands/kvstoreentry/list.go +++ b/pkg/commands/kvstoreentry/list.go @@ -1,8 +1,6 @@ package kvstoreentry import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,7 +14,8 @@ import ( // ListCommand calls the Fastly API to list the keys for a given kv store. type ListCommand struct { cmd.Base - json bool + cmd.JSONOutput + manifest manifest.Data Input fastly.ListKVStoreKeysInput } @@ -33,18 +32,13 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis c.CmdClause.Flag("store-id", "Store ID").Short('s').Required().StringVar(&c.Input.ID) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -54,17 +48,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(o) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } if c.Globals.Flags.Verbose { diff --git a/pkg/commands/logging/azureblob/describe.go b/pkg/commands/logging/azureblob/describe.go index c50795cc0..383d5d9c3 100644 --- a/pkg/commands/logging/azureblob/describe.go +++ b/pkg/commands/logging/azureblob/describe.go @@ -1,8 +1,6 @@ package azureblob import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe an Azure Blob Storage logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetBlobStorageInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,7 +84,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - azureblob, err := c.Globals.APIClient.GetBlobStorage(&c.Input) + o, err := c.Globals.APIClient.GetBlobStorage(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -99,39 +93,31 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(azureblob) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } + lines := text.Lines{ - "Account name": azureblob.AccountName, - "Compression codec": azureblob.CompressionCodec, - "Container": azureblob.Container, - "File max bytes": azureblob.FileMaxBytes, - "Format version": azureblob.FormatVersion, - "Format": azureblob.Format, - "GZip level": azureblob.GzipLevel, - "Message type": azureblob.MessageType, - "Name": azureblob.Name, - "Path": azureblob.Path, - "Period": azureblob.Period, - "Placement": azureblob.Placement, - "Public key": azureblob.PublicKey, - "Response condition": azureblob.ResponseCondition, - "SAS token": azureblob.SASToken, - "Timestamp format": azureblob.TimestampFormat, - "Version": azureblob.ServiceVersion, + "Account name": o.AccountName, + "Compression codec": o.CompressionCodec, + "Container": o.Container, + "File max bytes": o.FileMaxBytes, + "Format version": o.FormatVersion, + "Format": o.Format, + "GZip level": o.GzipLevel, + "Message type": o.MessageType, + "Name": o.Name, + "Path": o.Path, + "Period": o.Period, + "Placement": o.Placement, + "Public key": o.PublicKey, + "Response condition": o.ResponseCondition, + "SAS token": o.SASToken, + "Timestamp format": o.TimestampFormat, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = azureblob.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/azureblob/list.go b/pkg/commands/logging/azureblob/list.go index 964d3cbf7..a407b94c6 100644 --- a/pkg/commands/logging/azureblob/list.go +++ b/pkg/commands/logging/azureblob/list.go @@ -1,7 +1,6 @@ package azureblob import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Azure Blob Storage logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListBlobStoragesInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +84,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - azureblobs, err := c.Globals.APIClient.ListBlobStorages(&c.Input) + o, err := c.Globals.APIClient.ListBlobStorages(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,23 +93,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(azureblobs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, azureblob := range azureblobs { + for _, azureblob := range o { tw.AddLine(azureblob.ServiceID, azureblob.ServiceVersion, azureblob.Name) } tw.Print() @@ -122,8 +108,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, azureblob := range azureblobs { - fmt.Fprintf(out, "\tBlobStorage %d/%d\n", i+1, len(azureblobs)) + for i, azureblob := range o { + fmt.Fprintf(out, "\tBlobStorage %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", azureblob.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", azureblob.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", azureblob.Name) diff --git a/pkg/commands/logging/bigquery/describe.go b/pkg/commands/logging/bigquery/describe.go index aa9b8607c..2803c45f9 100644 --- a/pkg/commands/logging/bigquery/describe.go +++ b/pkg/commands/logging/bigquery/describe.go @@ -1,8 +1,6 @@ package bigquery import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a BigQuery logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetBigQueryInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,7 +84,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - bq, err := c.Globals.APIClient.GetBigQuery(&c.Input) + o, err := c.Globals.APIClient.GetBigQuery(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -99,36 +93,27 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(bq) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Account name": bq.AccountName, - "Dataset": bq.Dataset, - "Format version": bq.FormatVersion, - "Format": bq.Format, - "Name": bq.Name, - "Placement": bq.Placement, - "Project ID": bq.ProjectID, - "Response condition": bq.ResponseCondition, - "Secret key": bq.SecretKey, - "Table": bq.Table, - "Template suffix": bq.Template, - "User": bq.User, - "Version": bq.ServiceVersion, + "Account name": o.AccountName, + "Dataset": o.Dataset, + "Format version": o.FormatVersion, + "Format": o.Format, + "Name": o.Name, + "Placement": o.Placement, + "Project ID": o.ProjectID, + "Response condition": o.ResponseCondition, + "Secret key": o.SecretKey, + "Table": o.Table, + "Template suffix": o.Template, + "User": o.User, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = bq.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/bigquery/list.go b/pkg/commands/logging/bigquery/list.go index 31454564c..a64eb18cb 100644 --- a/pkg/commands/logging/bigquery/list.go +++ b/pkg/commands/logging/bigquery/list.go @@ -1,7 +1,6 @@ package bigquery import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list BigQuery logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListBigQueriesInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +84,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - bqs, err := c.Globals.APIClient.ListBigQueries(&c.Input) + o, err := c.Globals.APIClient.ListBigQueries(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,23 +93,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(bqs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, bq := range bqs { + for _, bq := range o { tw.AddLine(bq.ServiceID, bq.ServiceVersion, bq.Name) } tw.Print() @@ -122,8 +108,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, bq := range bqs { - fmt.Fprintf(out, "\tBigQuery %d/%d\n", i+1, len(bqs)) + for i, bq := range o { + fmt.Fprintf(out, "\tBigQuery %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", bq.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", bq.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", bq.Name) diff --git a/pkg/commands/logging/cloudfiles/describe.go b/pkg/commands/logging/cloudfiles/describe.go index 0ee0593fd..76b5d1ad3 100644 --- a/pkg/commands/logging/cloudfiles/describe.go +++ b/pkg/commands/logging/cloudfiles/describe.go @@ -1,8 +1,6 @@ package cloudfiles import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Cloudfiles logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetCloudfilesInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,7 +84,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - cloudfiles, err := c.Globals.APIClient.GetCloudfiles(&c.Input) + o, err := c.Globals.APIClient.GetCloudfiles(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -99,38 +93,30 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if c.json { - data, err := json.Marshal(cloudfiles) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } + lines := text.Lines{ - "Access key": cloudfiles.AccessKey, - "Bucket": cloudfiles.BucketName, - "Format version": cloudfiles.FormatVersion, - "Format": cloudfiles.Format, - "GZip level": cloudfiles.GzipLevel, - "Message type": cloudfiles.MessageType, - "Name": cloudfiles.Name, - "Path": cloudfiles.Path, - "Period": cloudfiles.Period, - "Placement": cloudfiles.Placement, - "Public key": cloudfiles.PublicKey, - "Region": cloudfiles.Region, - "Response condition": cloudfiles.ResponseCondition, - "Timestamp format": cloudfiles.TimestampFormat, - "User": cloudfiles.User, - "Version": cloudfiles.ServiceVersion, + "Access key": o.AccessKey, + "Bucket": o.BucketName, + "Format version": o.FormatVersion, + "Format": o.Format, + "GZip level": o.GzipLevel, + "Message type": o.MessageType, + "Name": o.Name, + "Path": o.Path, + "Period": o.Period, + "Placement": o.Placement, + "Public key": o.PublicKey, + "Region": o.Region, + "Response condition": o.ResponseCondition, + "Timestamp format": o.TimestampFormat, + "User": o.User, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = cloudfiles.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/cloudfiles/list.go b/pkg/commands/logging/cloudfiles/list.go index dfe036185..f22be9047 100644 --- a/pkg/commands/logging/cloudfiles/list.go +++ b/pkg/commands/logging/cloudfiles/list.go @@ -1,7 +1,6 @@ package cloudfiles import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Cloudfiles logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListCloudfilesInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +84,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - cloudfiles, err := c.Globals.APIClient.ListCloudfiles(&c.Input) + o, err := c.Globals.APIClient.ListCloudfiles(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,23 +93,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(cloudfiles) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, cloudfile := range cloudfiles { + for _, cloudfile := range o { tw.AddLine(cloudfile.ServiceID, cloudfile.ServiceVersion, cloudfile.Name) } tw.Print() @@ -122,8 +108,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, cloudfile := range cloudfiles { - fmt.Fprintf(out, "\tCloudfiles %d/%d\n", i+1, len(cloudfiles)) + for i, cloudfile := range o { + fmt.Fprintf(out, "\tCloudfiles %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", cloudfile.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", cloudfile.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", cloudfile.Name) diff --git a/pkg/commands/logging/datadog/describe.go b/pkg/commands/logging/datadog/describe.go index 8995bce7c..796408c76 100644 --- a/pkg/commands/logging/datadog/describe.go +++ b/pkg/commands/logging/datadog/describe.go @@ -1,8 +1,6 @@ package datadog import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Datadog logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetDatadogInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,36 +84,28 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - datadog, err := c.Globals.APIClient.GetDatadog(&c.Input) + o, err := c.Globals.APIClient.GetDatadog(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(datadog) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } + lines := text.Lines{ - "Format version": datadog.FormatVersion, - "Format": datadog.Format, - "Name": datadog.Name, - "Placement": datadog.Placement, - "Region": datadog.Region, - "Response condition": datadog.ResponseCondition, - "Token": datadog.Token, - "Version": datadog.ServiceVersion, + "Format version": o.FormatVersion, + "Format": o.Format, + "Name": o.Name, + "Placement": o.Placement, + "Region": o.Region, + "Response condition": o.ResponseCondition, + "Token": o.Token, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = datadog.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/datadog/list.go b/pkg/commands/logging/datadog/list.go index 2d87b390d..e0bd33231 100644 --- a/pkg/commands/logging/datadog/list.go +++ b/pkg/commands/logging/datadog/list.go @@ -1,7 +1,6 @@ package datadog import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Datadog logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListDatadogInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - datadogs, err := c.Globals.APIClient.ListDatadog(&c.Input) + o, err := c.Globals.APIClient.ListDatadog(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(datadogs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, datadog := range datadogs { + for _, datadog := range o { tw.AddLine(datadog.ServiceID, datadog.ServiceVersion, datadog.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, datadog := range datadogs { - fmt.Fprintf(out, "\tDatadog %d/%d\n", i+1, len(datadogs)) + for i, datadog := range o { + fmt.Fprintf(out, "\tDatadog %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", datadog.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", datadog.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", datadog.Name) diff --git a/pkg/commands/logging/digitalocean/describe.go b/pkg/commands/logging/digitalocean/describe.go index 784183513..5529df95d 100644 --- a/pkg/commands/logging/digitalocean/describe.go +++ b/pkg/commands/logging/digitalocean/describe.go @@ -1,8 +1,6 @@ package digitalocean import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a DigitalOcean Spaces logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetDigitalOceanInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,45 +84,36 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - digitalocean, err := c.Globals.APIClient.GetDigitalOcean(&c.Input) + o, err := c.Globals.APIClient.GetDigitalOcean(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(digitalocean) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Access key": digitalocean.AccessKey, - "Bucket": digitalocean.BucketName, - "Domain": digitalocean.Domain, - "Format version": digitalocean.FormatVersion, - "Format": digitalocean.Format, - "GZip level": digitalocean.GzipLevel, - "Message type": digitalocean.MessageType, - "Name": digitalocean.Name, - "Path": digitalocean.Path, - "Period": digitalocean.Period, - "Placement": digitalocean.Placement, - "Public key": digitalocean.PublicKey, - "Response condition": digitalocean.ResponseCondition, - "Secret key": digitalocean.SecretKey, - "Timestamp format": digitalocean.TimestampFormat, - "Version": digitalocean.ServiceVersion, + "Access key": o.AccessKey, + "Bucket": o.BucketName, + "Domain": o.Domain, + "Format version": o.FormatVersion, + "Format": o.Format, + "GZip level": o.GzipLevel, + "Message type": o.MessageType, + "Name": o.Name, + "Path": o.Path, + "Period": o.Period, + "Placement": o.Placement, + "Public key": o.PublicKey, + "Response condition": o.ResponseCondition, + "Secret key": o.SecretKey, + "Timestamp format": o.TimestampFormat, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = digitalocean.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/digitalocean/list.go b/pkg/commands/logging/digitalocean/list.go index bf09ffe1c..59a269b6e 100644 --- a/pkg/commands/logging/digitalocean/list.go +++ b/pkg/commands/logging/digitalocean/list.go @@ -1,7 +1,6 @@ package digitalocean import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list DigitalOcean Spaces logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListDigitalOceansInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - digitaloceans, err := c.Globals.APIClient.ListDigitalOceans(&c.Input) + o, err := c.Globals.APIClient.ListDigitalOceans(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(digitaloceans) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, digitalocean := range digitaloceans { + for _, digitalocean := range o { tw.AddLine(digitalocean.ServiceID, digitalocean.ServiceVersion, digitalocean.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, digitalocean := range digitaloceans { - fmt.Fprintf(out, "\tDigitalOcean %d/%d\n", i+1, len(digitaloceans)) + for i, digitalocean := range o { + fmt.Fprintf(out, "\tDigitalOcean %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", digitalocean.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", digitalocean.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", digitalocean.Name) diff --git a/pkg/commands/logging/elasticsearch/describe.go b/pkg/commands/logging/elasticsearch/describe.go index a1af67e66..7c9dcc827 100644 --- a/pkg/commands/logging/elasticsearch/describe.go +++ b/pkg/commands/logging/elasticsearch/describe.go @@ -1,8 +1,6 @@ package elasticsearch import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe an Elasticsearch logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetElasticsearchInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,43 +84,35 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - elasticsearch, err := c.Globals.APIClient.GetElasticsearch(&c.Input) + o, err := c.Globals.APIClient.GetElasticsearch(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(elasticsearch) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } + lines := text.Lines{ - "Format version": elasticsearch.FormatVersion, - "Format": elasticsearch.Format, - "Index": elasticsearch.Index, - "Name": elasticsearch.Name, - "Password": elasticsearch.Password, - "Pipeline": elasticsearch.Pipeline, - "Placement": elasticsearch.Placement, - "Response condition": elasticsearch.ResponseCondition, - "TLS CA certificate": elasticsearch.TLSCACert, - "TLS client certificate": elasticsearch.TLSClientCert, - "TLS client key": elasticsearch.TLSClientKey, - "TLS hostname": elasticsearch.TLSHostname, - "URL": elasticsearch.URL, - "User": elasticsearch.User, - "Version": elasticsearch.ServiceVersion, + "Format version": o.FormatVersion, + "Format": o.Format, + "Index": o.Index, + "Name": o.Name, + "Password": o.Password, + "Pipeline": o.Pipeline, + "Placement": o.Placement, + "Response condition": o.ResponseCondition, + "TLS CA certificate": o.TLSCACert, + "TLS client certificate": o.TLSClientCert, + "TLS client key": o.TLSClientKey, + "TLS hostname": o.TLSHostname, + "URL": o.URL, + "User": o.User, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = elasticsearch.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/elasticsearch/list.go b/pkg/commands/logging/elasticsearch/list.go index d3744b3fa..b4da82cff 100644 --- a/pkg/commands/logging/elasticsearch/list.go +++ b/pkg/commands/logging/elasticsearch/list.go @@ -1,7 +1,6 @@ package elasticsearch import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Elasticsearch logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListElasticsearchInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - elasticsearchs, err := c.Globals.APIClient.ListElasticsearch(&c.Input) + o, err := c.Globals.APIClient.ListElasticsearch(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(elasticsearchs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, elasticsearch := range elasticsearchs { + for _, elasticsearch := range o { tw.AddLine(elasticsearch.ServiceID, elasticsearch.ServiceVersion, elasticsearch.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, elasticsearch := range elasticsearchs { - fmt.Fprintf(out, "\tElasticsearch %d/%d\n", i+1, len(elasticsearchs)) + for i, elasticsearch := range o { + fmt.Fprintf(out, "\tElasticsearch %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", elasticsearch.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", elasticsearch.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", elasticsearch.Name) diff --git a/pkg/commands/logging/ftp/describe.go b/pkg/commands/logging/ftp/describe.go index b780534c1..7d7cd9c7f 100644 --- a/pkg/commands/logging/ftp/describe.go +++ b/pkg/commands/logging/ftp/describe.go @@ -1,8 +1,6 @@ package ftp import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe an FTP logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetFTPInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -32,12 +31,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) manifest: m, } c.CmdClause = parent.Command("describe", "Show detailed information about an FTP logging endpoint on a Fastly service version").Alias("get") - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -62,7 +56,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -86,45 +80,36 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - ftp, err := c.Globals.APIClient.GetFTP(&c.Input) + o, err := c.Globals.APIClient.GetFTP(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(ftp) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Address": ftp.Address, - "Compression codec": ftp.CompressionCodec, - "Format version": ftp.FormatVersion, - "Format": ftp.Format, - "GZip level": ftp.GzipLevel, - "Name": ftp.Name, - "Password": ftp.Password, - "Path": ftp.Path, - "Period": ftp.Period, - "Placement": ftp.Placement, - "Port": ftp.Port, - "Public key": ftp.PublicKey, - "Response condition": ftp.ResponseCondition, - "Timestamp format": ftp.TimestampFormat, - "Username": ftp.Username, - "Version": ftp.ServiceVersion, + "Address": o.Address, + "Compression codec": o.CompressionCodec, + "Format version": o.FormatVersion, + "Format": o.Format, + "GZip level": o.GzipLevel, + "Name": o.Name, + "Password": o.Password, + "Path": o.Path, + "Period": o.Period, + "Placement": o.Placement, + "Port": o.Port, + "Public key": o.PublicKey, + "Response condition": o.ResponseCondition, + "Timestamp format": o.TimestampFormat, + "Username": o.Username, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = ftp.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/ftp/list.go b/pkg/commands/logging/ftp/list.go index 435caba86..e83f0fdba 100644 --- a/pkg/commands/logging/ftp/list.go +++ b/pkg/commands/logging/ftp/list.go @@ -1,7 +1,6 @@ package ftp import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list FTP logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListFTPsInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - ftps, err := c.Globals.APIClient.ListFTPs(&c.Input) + o, err := c.Globals.APIClient.ListFTPs(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(ftps) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, ftp := range ftps { + for _, ftp := range o { tw.AddLine(ftp.ServiceID, ftp.ServiceVersion, ftp.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, ftp := range ftps { - fmt.Fprintf(out, "\tFTP %d/%d\n", i+1, len(ftps)) + for i, ftp := range o { + fmt.Fprintf(out, "\tFTP %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", ftp.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", ftp.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", ftp.Name) diff --git a/pkg/commands/logging/gcs/describe.go b/pkg/commands/logging/gcs/describe.go index 1380460dd..d670d4004 100644 --- a/pkg/commands/logging/gcs/describe.go +++ b/pkg/commands/logging/gcs/describe.go @@ -1,8 +1,6 @@ package gcs import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a GCS logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetGCSInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,45 +84,36 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - gcs, err := c.Globals.APIClient.GetGCS(&c.Input) + o, err := c.Globals.APIClient.GetGCS(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(gcs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Account name": gcs.AccountName, - "Bucket": gcs.Bucket, - "Compression codec": gcs.CompressionCodec, - "Format version": gcs.FormatVersion, - "Format": gcs.Format, - "GZip level": gcs.GzipLevel, - "Message type": gcs.MessageType, - "Name": gcs.Name, - "Path": gcs.Path, - "Period": gcs.Period, - "Placement": gcs.Placement, - "Response condition": gcs.ResponseCondition, - "Secret key": gcs.SecretKey, - "Timestamp format": gcs.TimestampFormat, - "User": gcs.User, - "Version": gcs.ServiceVersion, + "Account name": o.AccountName, + "Bucket": o.Bucket, + "Compression codec": o.CompressionCodec, + "Format version": o.FormatVersion, + "Format": o.Format, + "GZip level": o.GzipLevel, + "Message type": o.MessageType, + "Name": o.Name, + "Path": o.Path, + "Period": o.Period, + "Placement": o.Placement, + "Response condition": o.ResponseCondition, + "Secret key": o.SecretKey, + "Timestamp format": o.TimestampFormat, + "User": o.User, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = gcs.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/gcs/list.go b/pkg/commands/logging/gcs/list.go index c1a028de4..013cbebd2 100644 --- a/pkg/commands/logging/gcs/list.go +++ b/pkg/commands/logging/gcs/list.go @@ -1,7 +1,6 @@ package gcs import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list GCS logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListGCSsInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - gcss, err := c.Globals.APIClient.ListGCSs(&c.Input) + o, err := c.Globals.APIClient.ListGCSs(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(gcss) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, gcs := range gcss { + for _, gcs := range o { tw.AddLine(gcs.ServiceID, gcs.ServiceVersion, gcs.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, gcs := range gcss { - fmt.Fprintf(out, "\tGCS %d/%d\n", i+1, len(gcss)) + for i, gcs := range o { + fmt.Fprintf(out, "\tGCS %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", gcs.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", gcs.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", gcs.Name) diff --git a/pkg/commands/logging/googlepubsub/describe.go b/pkg/commands/logging/googlepubsub/describe.go index a764dc55e..6cdeab7e0 100644 --- a/pkg/commands/logging/googlepubsub/describe.go +++ b/pkg/commands/logging/googlepubsub/describe.go @@ -1,8 +1,6 @@ package googlepubsub import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Google Cloud Pub/Sub logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetPubsubInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,40 +84,31 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - googlepubsub, err := c.Globals.APIClient.GetPubsub(&c.Input) + o, err := c.Globals.APIClient.GetPubsub(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(googlepubsub) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Account name": googlepubsub.AccountName, - "Format version": googlepubsub.FormatVersion, - "Format": googlepubsub.Format, - "Name": googlepubsub.Name, - "Placement": googlepubsub.Placement, - "Project ID": googlepubsub.ProjectID, - "Response condition": googlepubsub.ResponseCondition, - "Secret key": googlepubsub.SecretKey, - "Topic": googlepubsub.Topic, - "User": googlepubsub.User, - "Version": googlepubsub.ServiceVersion, + "Account name": o.AccountName, + "Format version": o.FormatVersion, + "Format": o.Format, + "Name": o.Name, + "Placement": o.Placement, + "Project ID": o.ProjectID, + "Response condition": o.ResponseCondition, + "Secret key": o.SecretKey, + "Topic": o.Topic, + "User": o.User, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = googlepubsub.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/googlepubsub/list.go b/pkg/commands/logging/googlepubsub/list.go index 5b061b613..e61d47e88 100644 --- a/pkg/commands/logging/googlepubsub/list.go +++ b/pkg/commands/logging/googlepubsub/list.go @@ -1,7 +1,6 @@ package googlepubsub import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Google Cloud Pub/Sub logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListPubsubsInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - googlepubsubs, err := c.Globals.APIClient.ListPubsubs(&c.Input) + o, err := c.Globals.APIClient.ListPubsubs(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(googlepubsubs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, googlepubsub := range googlepubsubs { + for _, googlepubsub := range o { tw.AddLine(googlepubsub.ServiceID, googlepubsub.ServiceVersion, googlepubsub.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, googlepubsub := range googlepubsubs { - fmt.Fprintf(out, "\tGoogle Cloud Pub/Sub %d/%d\n", i+1, len(googlepubsubs)) + for i, googlepubsub := range o { + fmt.Fprintf(out, "\tGoogle Cloud Pub/Sub %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", googlepubsub.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", googlepubsub.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", googlepubsub.Name) diff --git a/pkg/commands/logging/heroku/describe.go b/pkg/commands/logging/heroku/describe.go index 088c5f582..cf7c331fa 100644 --- a/pkg/commands/logging/heroku/describe.go +++ b/pkg/commands/logging/heroku/describe.go @@ -1,8 +1,6 @@ package heroku import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Heroku logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetHerokuInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,37 +84,28 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - heroku, err := c.Globals.APIClient.GetHeroku(&c.Input) + o, err := c.Globals.APIClient.GetHeroku(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(heroku) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Format version": heroku.FormatVersion, - "Format": heroku.Format, - "Name": heroku.Name, - "Placement": heroku.Placement, - "Response condition": heroku.ResponseCondition, - "Token": heroku.Token, - "URL": heroku.URL, - "Version": heroku.ServiceVersion, + "Format version": o.FormatVersion, + "Format": o.Format, + "Name": o.Name, + "Placement": o.Placement, + "Response condition": o.ResponseCondition, + "Token": o.Token, + "URL": o.URL, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = heroku.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/heroku/list.go b/pkg/commands/logging/heroku/list.go index ee08da27e..3b34f9697 100644 --- a/pkg/commands/logging/heroku/list.go +++ b/pkg/commands/logging/heroku/list.go @@ -1,7 +1,6 @@ package heroku import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Heroku logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListHerokusInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - herokus, err := c.Globals.APIClient.ListHerokus(&c.Input) + o, err := c.Globals.APIClient.ListHerokus(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(herokus) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, heroku := range herokus { + for _, heroku := range o { tw.AddLine(heroku.ServiceID, heroku.ServiceVersion, heroku.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, heroku := range herokus { - fmt.Fprintf(out, "\tHeroku %d/%d\n", i+1, len(herokus)) + for i, heroku := range o { + fmt.Fprintf(out, "\tHeroku %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", heroku.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", heroku.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", heroku.Name) diff --git a/pkg/commands/logging/honeycomb/describe.go b/pkg/commands/logging/honeycomb/describe.go index 9810d17e0..cb485aa67 100644 --- a/pkg/commands/logging/honeycomb/describe.go +++ b/pkg/commands/logging/honeycomb/describe.go @@ -1,8 +1,6 @@ package honeycomb import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Honeycomb logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetHoneycombInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,37 +84,28 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - honeycomb, err := c.Globals.APIClient.GetHoneycomb(&c.Input) + o, err := c.Globals.APIClient.GetHoneycomb(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(honeycomb) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Dataset": honeycomb.Dataset, - "Format version": honeycomb.FormatVersion, - "Format": honeycomb.Format, - "Name": honeycomb.Name, - "Placement": honeycomb.Placement, - "Response condition": honeycomb.ResponseCondition, - "Token": honeycomb.Token, - "Version": honeycomb.ServiceVersion, + "Dataset": o.Dataset, + "Format version": o.FormatVersion, + "Format": o.Format, + "Name": o.Name, + "Placement": o.Placement, + "Response condition": o.ResponseCondition, + "Token": o.Token, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = honeycomb.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/honeycomb/list.go b/pkg/commands/logging/honeycomb/list.go index bf1e4211b..81b787676 100644 --- a/pkg/commands/logging/honeycomb/list.go +++ b/pkg/commands/logging/honeycomb/list.go @@ -1,7 +1,6 @@ package honeycomb import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Honeycomb logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListHoneycombsInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - honeycombs, err := c.Globals.APIClient.ListHoneycombs(&c.Input) + o, err := c.Globals.APIClient.ListHoneycombs(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(honeycombs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, honeycomb := range honeycombs { + for _, honeycomb := range o { tw.AddLine(honeycomb.ServiceID, honeycomb.ServiceVersion, honeycomb.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, honeycomb := range honeycombs { - fmt.Fprintf(out, "\tHoneycomb %d/%d\n", i+1, len(honeycombs)) + for i, honeycomb := range o { + fmt.Fprintf(out, "\tHoneycomb %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", honeycomb.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", honeycomb.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", honeycomb.Name) diff --git a/pkg/commands/logging/https/describe.go b/pkg/commands/logging/https/describe.go index ff96ef5eb..e47150d8e 100644 --- a/pkg/commands/logging/https/describe.go +++ b/pkg/commands/logging/https/describe.go @@ -1,8 +1,6 @@ package https import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe an HTTPS logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetHTTPSInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,48 +84,39 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - https, err := c.Globals.APIClient.GetHTTPS(&c.Input) + o, err := c.Globals.APIClient.GetHTTPS(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(https) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Content type": https.ContentType, - "Format version": https.FormatVersion, - "Format": https.Format, - "Header name": https.HeaderName, - "Header value": https.HeaderValue, - "JSON format": https.JSONFormat, - "Message type": https.MessageType, - "Method": https.Method, - "Name": https.Name, - "Placement": https.Placement, - "Request max bytes": https.RequestMaxBytes, - "Request max entries": https.RequestMaxEntries, - "Response condition": https.ResponseCondition, - "TLS CA certificate": https.TLSCACert, - "TLS client certificate": https.TLSClientCert, - "TLS client key": https.TLSClientKey, - "TLS hostname": https.TLSHostname, - "URL": https.URL, - "Version": https.ServiceVersion, + "Content type": o.ContentType, + "Format version": o.FormatVersion, + "Format": o.Format, + "Header name": o.HeaderName, + "Header value": o.HeaderValue, + "JSON format": o.JSONFormat, + "Message type": o.MessageType, + "Method": o.Method, + "Name": o.Name, + "Placement": o.Placement, + "Request max bytes": o.RequestMaxBytes, + "Request max entries": o.RequestMaxEntries, + "Response condition": o.ResponseCondition, + "TLS CA certificate": o.TLSCACert, + "TLS client certificate": o.TLSClientCert, + "TLS client key": o.TLSClientKey, + "TLS hostname": o.TLSHostname, + "URL": o.URL, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = https.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/https/list.go b/pkg/commands/logging/https/list.go index c76acd4d0..36ef6718b 100644 --- a/pkg/commands/logging/https/list.go +++ b/pkg/commands/logging/https/list.go @@ -1,7 +1,6 @@ package https import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list HTTPS logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListHTTPSInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - httpss, err := c.Globals.APIClient.ListHTTPS(&c.Input) + o, err := c.Globals.APIClient.ListHTTPS(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(httpss) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, https := range httpss { + for _, https := range o { tw.AddLine(https.ServiceID, https.ServiceVersion, https.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, https := range httpss { - fmt.Fprintf(out, "\tHTTPS %d/%d\n", i+1, len(httpss)) + for i, https := range o { + fmt.Fprintf(out, "\tHTTPS %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", https.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", https.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", https.Name) diff --git a/pkg/commands/logging/kafka/describe.go b/pkg/commands/logging/kafka/describe.go index 5a732591b..00eb69757 100644 --- a/pkg/commands/logging/kafka/describe.go +++ b/pkg/commands/logging/kafka/describe.go @@ -1,8 +1,6 @@ package kafka import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Kafka logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetKafkaInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,49 +84,40 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - kafka, err := c.Globals.APIClient.GetKafka(&c.Input) + o, err := c.Globals.APIClient.GetKafka(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(kafka) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Brokers": kafka.Brokers, - "Compression codec": kafka.CompressionCodec, - "Format version": kafka.FormatVersion, - "Format": kafka.Format, - "Max batch size": kafka.RequestMaxBytes, - "Name": kafka.Name, - "Parse log key-values": kafka.ParseLogKeyvals, - "Placement": kafka.Placement, - "Required acks": kafka.RequiredACKs, - "Response condition": kafka.ResponseCondition, - "SASL authentication method": kafka.AuthMethod, - "SASL authentication password": kafka.Password, - "SASL authentication username": kafka.User, - "TLS CA certificate": kafka.TLSCACert, - "TLS client certificate": kafka.TLSClientCert, - "TLS client key": kafka.TLSClientKey, - "TLS hostname": kafka.TLSHostname, - "Topic": kafka.Topic, - "Use TLS": kafka.UseTLS, - "Version": kafka.ServiceVersion, + "Brokers": o.Brokers, + "Compression codec": o.CompressionCodec, + "Format version": o.FormatVersion, + "Format": o.Format, + "Max batch size": o.RequestMaxBytes, + "Name": o.Name, + "Parse log key-values": o.ParseLogKeyvals, + "Placement": o.Placement, + "Required acks": o.RequiredACKs, + "Response condition": o.ResponseCondition, + "SASL authentication method": o.AuthMethod, + "SASL authentication password": o.Password, + "SASL authentication username": o.User, + "TLS CA certificate": o.TLSCACert, + "TLS client certificate": o.TLSClientCert, + "TLS client key": o.TLSClientKey, + "TLS hostname": o.TLSHostname, + "Topic": o.Topic, + "Use TLS": o.UseTLS, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = kafka.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/kafka/list.go b/pkg/commands/logging/kafka/list.go index 4aa287894..a1f431525 100644 --- a/pkg/commands/logging/kafka/list.go +++ b/pkg/commands/logging/kafka/list.go @@ -1,7 +1,6 @@ package kafka import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Kafka logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListKafkasInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - kafkas, err := c.Globals.APIClient.ListKafkas(&c.Input) + o, err := c.Globals.APIClient.ListKafkas(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(kafkas) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, kafka := range kafkas { + for _, kafka := range o { tw.AddLine(kafka.ServiceID, kafka.ServiceVersion, kafka.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, kafka := range kafkas { - fmt.Fprintf(out, "\tKafka %d/%d\n", i+1, len(kafkas)) + for i, kafka := range o { + fmt.Fprintf(out, "\tKafka %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", kafka.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", kafka.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", kafka.Name) diff --git a/pkg/commands/logging/kinesis/describe.go b/pkg/commands/logging/kinesis/describe.go index dbeb02a08..7b76129cb 100644 --- a/pkg/commands/logging/kinesis/describe.go +++ b/pkg/commands/logging/kinesis/describe.go @@ -1,8 +1,6 @@ package kinesis import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe an Amazon Kinesis logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetKinesisInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,45 +84,36 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - kinesis, err := c.Globals.APIClient.GetKinesis(&c.Input) + o, err := c.Globals.APIClient.GetKinesis(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(kinesis) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Format version": kinesis.FormatVersion, - "Format": kinesis.Format, - "Name": kinesis.Name, - "Placement": kinesis.Placement, - "Region": kinesis.Region, - "Response condition": kinesis.ResponseCondition, - "Stream name": kinesis.StreamName, - "Version": kinesis.ServiceVersion, + "Format version": o.FormatVersion, + "Format": o.Format, + "Name": o.Name, + "Placement": o.Placement, + "Region": o.Region, + "Response condition": o.ResponseCondition, + "Stream name": o.StreamName, + "Version": o.ServiceVersion, } - if kinesis.AccessKey != "" || kinesis.SecretKey != "" { - lines["Access key"] = kinesis.AccessKey - lines["Secret key"] = kinesis.SecretKey + if o.AccessKey != "" || o.SecretKey != "" { + lines["Access key"] = o.AccessKey + lines["Secret key"] = o.SecretKey } - if kinesis.IAMRole != "" { - lines["IAM role"] = kinesis.IAMRole + if o.IAMRole != "" { + lines["IAM role"] = o.IAMRole } if !c.Globals.Verbose() { - lines["Service ID"] = kinesis.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/kinesis/list.go b/pkg/commands/logging/kinesis/list.go index 23593576e..d05dad53b 100644 --- a/pkg/commands/logging/kinesis/list.go +++ b/pkg/commands/logging/kinesis/list.go @@ -1,7 +1,6 @@ package kinesis import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Amazon Kinesis logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListKinesisInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - kineses, err := c.Globals.APIClient.ListKinesis(&c.Input) + o, err := c.Globals.APIClient.ListKinesis(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(kineses) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, kinesis := range kineses { + for _, kinesis := range o { tw.AddLine(kinesis.ServiceID, kinesis.ServiceVersion, kinesis.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, kinesis := range kineses { - fmt.Fprintf(out, "\tKinesis %d/%d\n", i+1, len(kineses)) + for i, kinesis := range o { + fmt.Fprintf(out, "\tKinesis %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", kinesis.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", kinesis.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", kinesis.Name) diff --git a/pkg/commands/logging/loggly/describe.go b/pkg/commands/logging/loggly/describe.go index bfb56c056..ea9dbd88f 100644 --- a/pkg/commands/logging/loggly/describe.go +++ b/pkg/commands/logging/loggly/describe.go @@ -1,8 +1,6 @@ package loggly import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Loggly logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetLogglyInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,36 +84,27 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - loggly, err := c.Globals.APIClient.GetLoggly(&c.Input) + o, err := c.Globals.APIClient.GetLoggly(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(loggly) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Format version": loggly.FormatVersion, - "Format": loggly.Format, - "Name": loggly.Name, - "Placement": loggly.Placement, - "Response condition": loggly.ResponseCondition, - "Token": loggly.Token, - "Version": loggly.ServiceVersion, + "Format version": o.FormatVersion, + "Format": o.Format, + "Name": o.Name, + "Placement": o.Placement, + "Response condition": o.ResponseCondition, + "Token": o.Token, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = loggly.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/loggly/list.go b/pkg/commands/logging/loggly/list.go index 493330d9a..487159b97 100644 --- a/pkg/commands/logging/loggly/list.go +++ b/pkg/commands/logging/loggly/list.go @@ -1,7 +1,6 @@ package loggly import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Loggly logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListLogglyInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - logglys, err := c.Globals.APIClient.ListLoggly(&c.Input) + o, err := c.Globals.APIClient.ListLoggly(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(logglys) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, loggly := range logglys { + for _, loggly := range o { tw.AddLine(loggly.ServiceID, loggly.ServiceVersion, loggly.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, loggly := range logglys { - fmt.Fprintf(out, "\tLoggly %d/%d\n", i+1, len(logglys)) + for i, loggly := range o { + fmt.Fprintf(out, "\tLoggly %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", loggly.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", loggly.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", loggly.Name) diff --git a/pkg/commands/logging/logshuttle/describe.go b/pkg/commands/logging/logshuttle/describe.go index 450d0732c..863ed2c51 100644 --- a/pkg/commands/logging/logshuttle/describe.go +++ b/pkg/commands/logging/logshuttle/describe.go @@ -1,8 +1,6 @@ package logshuttle import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Logshuttle logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetLogshuttleInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,37 +84,28 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - logshuttle, err := c.Globals.APIClient.GetLogshuttle(&c.Input) + o, err := c.Globals.APIClient.GetLogshuttle(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(logshuttle) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Format version": logshuttle.FormatVersion, - "Format": logshuttle.Format, - "Name": logshuttle.Name, - "Placement": logshuttle.Placement, - "Response condition": logshuttle.ResponseCondition, - "Token": logshuttle.Token, - "URL": logshuttle.URL, - "Version": logshuttle.ServiceVersion, + "Format version": o.FormatVersion, + "Format": o.Format, + "Name": o.Name, + "Placement": o.Placement, + "Response condition": o.ResponseCondition, + "Token": o.Token, + "URL": o.URL, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = logshuttle.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/logshuttle/list.go b/pkg/commands/logging/logshuttle/list.go index 2d877d9a4..55ccaf666 100644 --- a/pkg/commands/logging/logshuttle/list.go +++ b/pkg/commands/logging/logshuttle/list.go @@ -1,7 +1,6 @@ package logshuttle import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Logshuttle logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListLogshuttlesInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - logshuttles, err := c.Globals.APIClient.ListLogshuttles(&c.Input) + o, err := c.Globals.APIClient.ListLogshuttles(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(logshuttles) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, logshuttle := range logshuttles { + for _, logshuttle := range o { tw.AddLine(logshuttle.ServiceID, logshuttle.ServiceVersion, logshuttle.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, logshuttle := range logshuttles { - fmt.Fprintf(out, "\tLogshuttle %d/%d\n", i+1, len(logshuttles)) + for i, logshuttle := range o { + fmt.Fprintf(out, "\tLogshuttle %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", logshuttle.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", logshuttle.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", logshuttle.Name) diff --git a/pkg/commands/logging/newrelic/describe.go b/pkg/commands/logging/newrelic/describe.go index c0bc97ae4..101c00229 100644 --- a/pkg/commands/logging/newrelic/describe.go +++ b/pkg/commands/logging/newrelic/describe.go @@ -1,8 +1,6 @@ package newrelic import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -33,12 +31,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -58,8 +51,8 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput - json bool manifest manifest.Data name string serviceName cmd.OptionalServiceNameID @@ -68,7 +61,7 @@ type DescribeCommand struct { // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -91,7 +84,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { input := c.constructInput(serviceID, serviceVersion.Number) - a, err := c.Globals.APIClient.GetNewRelic(input) + o, err := c.Globals.APIClient.GetNewRelic(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -100,7 +93,11 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, a) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. @@ -116,19 +113,6 @@ func (c *DescribeCommand) constructInput(serviceID string, serviceVersion int) * // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, nr *fastly.NewRelic) error { - if c.json { - data, err := json.Marshal(nr) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - lines := text.Lines{ "Format Version": nr.FormatVersion, "Format": nr.Format, diff --git a/pkg/commands/logging/newrelic/list.go b/pkg/commands/logging/newrelic/list.go index 3aa778416..3055b20b7 100644 --- a/pkg/commands/logging/newrelic/list.go +++ b/pkg/commands/logging/newrelic/list.go @@ -1,7 +1,6 @@ package newrelic import ( - "encoding/json" "fmt" "io" @@ -32,12 +31,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -57,8 +51,8 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput - json bool manifest manifest.Data serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion @@ -66,7 +60,7 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +83,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { input := c.constructInput(serviceID, serviceVersion.Number) - l, err := c.Globals.APIClient.ListNewRelic(input) + o, err := c.Globals.APIClient.ListNewRelic(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,10 +92,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - c.printVerbose(out, serviceVersion.Number, l) + c.printVerbose(out, serviceVersion.Number, o) } else { - err = c.printSummary(out, l) + err = c.printSummary(out, o) if err != nil { return err } @@ -148,19 +146,6 @@ func (c *ListCommand) printVerbose(out io.Writer, serviceVersion int, ls []*fast // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, nrs []*fastly.NewRelic) error { - if c.json { - data, err := json.Marshal(nrs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("SERVICE ID", "VERSION", "NAME") for _, nr := range nrs { diff --git a/pkg/commands/logging/openstack/describe.go b/pkg/commands/logging/openstack/describe.go index e1337370c..447147583 100644 --- a/pkg/commands/logging/openstack/describe.go +++ b/pkg/commands/logging/openstack/describe.go @@ -1,8 +1,6 @@ package openstack import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe an OpenStack logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetOpenstackInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,46 +84,37 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - openstack, err := c.Globals.APIClient.GetOpenstack(&c.Input) + o, err := c.Globals.APIClient.GetOpenstack(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(openstack) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Access key": openstack.AccessKey, - "Bucket": openstack.BucketName, - "Compression codec": openstack.CompressionCodec, - "Format version": openstack.FormatVersion, - "Format": openstack.Format, - "GZip level": openstack.GzipLevel, - "Message type": openstack.MessageType, - "Name": openstack.Name, - "Path": openstack.Path, - "Period": openstack.Period, - "Placement": openstack.Placement, - "Public key": openstack.PublicKey, - "Response condition": openstack.ResponseCondition, - "Timestamp format": openstack.TimestampFormat, - "URL": openstack.URL, - "User": openstack.User, - "Version": openstack.ServiceVersion, + "Access key": o.AccessKey, + "Bucket": o.BucketName, + "Compression codec": o.CompressionCodec, + "Format version": o.FormatVersion, + "Format": o.Format, + "GZip level": o.GzipLevel, + "Message type": o.MessageType, + "Name": o.Name, + "Path": o.Path, + "Period": o.Period, + "Placement": o.Placement, + "Public key": o.PublicKey, + "Response condition": o.ResponseCondition, + "Timestamp format": o.TimestampFormat, + "URL": o.URL, + "User": o.User, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = openstack.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/openstack/list.go b/pkg/commands/logging/openstack/list.go index 7e9b587f5..9d4678b48 100644 --- a/pkg/commands/logging/openstack/list.go +++ b/pkg/commands/logging/openstack/list.go @@ -1,7 +1,6 @@ package openstack import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list OpenStack logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListOpenstackInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - openstacks, err := c.Globals.APIClient.ListOpenstack(&c.Input) + o, err := c.Globals.APIClient.ListOpenstack(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(openstacks) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, openstack := range openstacks { + for _, openstack := range o { tw.AddLine(openstack.ServiceID, openstack.ServiceVersion, openstack.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, openstack := range openstacks { - fmt.Fprintf(out, "\tOpenstack %d/%d\n", i+1, len(openstacks)) + for i, openstack := range o { + fmt.Fprintf(out, "\tOpenstack %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", openstack.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", openstack.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", openstack.Name) diff --git a/pkg/commands/logging/papertrail/describe.go b/pkg/commands/logging/papertrail/describe.go index c6d9670e4..dbfb3b47d 100644 --- a/pkg/commands/logging/papertrail/describe.go +++ b/pkg/commands/logging/papertrail/describe.go @@ -1,8 +1,6 @@ package papertrail import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Papertrail logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetPapertrailInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,37 +84,28 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - papertrail, err := c.Globals.APIClient.GetPapertrail(&c.Input) + o, err := c.Globals.APIClient.GetPapertrail(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(papertrail) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Address": papertrail.Address, - "Format version": papertrail.FormatVersion, - "Format": papertrail.Format, - "Name": papertrail.Name, - "Placement": papertrail.Placement, - "Port": papertrail.Port, - "Response condition": papertrail.ResponseCondition, - "Version": papertrail.ServiceVersion, + "Address": o.Address, + "Format version": o.FormatVersion, + "Format": o.Format, + "Name": o.Name, + "Placement": o.Placement, + "Port": o.Port, + "Response condition": o.ResponseCondition, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = papertrail.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/papertrail/list.go b/pkg/commands/logging/papertrail/list.go index f248bbb48..1ed9fbcbc 100644 --- a/pkg/commands/logging/papertrail/list.go +++ b/pkg/commands/logging/papertrail/list.go @@ -1,7 +1,6 @@ package papertrail import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Papertrail logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListPapertrailsInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - papertrails, err := c.Globals.APIClient.ListPapertrails(&c.Input) + o, err := c.Globals.APIClient.ListPapertrails(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(papertrails) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, papertrail := range papertrails { + for _, papertrail := range o { tw.AddLine(papertrail.ServiceID, papertrail.ServiceVersion, papertrail.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, papertrail := range papertrails { - fmt.Fprintf(out, "\tPapertrail %d/%d\n", i+1, len(papertrails)) + for i, papertrail := range o { + fmt.Fprintf(out, "\tPapertrail %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", papertrail.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", papertrail.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", papertrail.Name) diff --git a/pkg/commands/logging/s3/describe.go b/pkg/commands/logging/s3/describe.go index 5ac89a8ed..69c1bd292 100644 --- a/pkg/commands/logging/s3/describe.go +++ b/pkg/commands/logging/s3/describe.go @@ -1,8 +1,6 @@ package s3 import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe an Amazon S3 logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetS3Input - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,53 +84,44 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - s3, err := c.Globals.APIClient.GetS3(&c.Input) + o, err := c.Globals.APIClient.GetS3(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(s3) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Bucket": s3.BucketName, - "Compression codec": s3.CompressionCodec, - "Format version": s3.FormatVersion, - "Format": s3.Format, - "GZip level": s3.GzipLevel, - "Message type": s3.MessageType, - "Name": s3.Name, - "Path": s3.Path, - "Period": s3.Period, - "Placement": s3.Placement, - "Public key": s3.PublicKey, - "Redundancy": s3.Redundancy, - "Response condition": s3.ResponseCondition, - "Server-side encryption KMS key ID": s3.ServerSideEncryption, - "Server-side encryption": s3.ServerSideEncryption, - "Timestamp format": s3.TimestampFormat, - "Version": s3.ServiceVersion, + "Bucket": o.BucketName, + "Compression codec": o.CompressionCodec, + "Format version": o.FormatVersion, + "Format": o.Format, + "GZip level": o.GzipLevel, + "Message type": o.MessageType, + "Name": o.Name, + "Path": o.Path, + "Period": o.Period, + "Placement": o.Placement, + "Public key": o.PublicKey, + "Redundancy": o.Redundancy, + "Response condition": o.ResponseCondition, + "Server-side encryption KMS key ID": o.ServerSideEncryption, + "Server-side encryption": o.ServerSideEncryption, + "Timestamp format": o.TimestampFormat, + "Version": o.ServiceVersion, } - if s3.AccessKey != "" || s3.SecretKey != "" { - lines["Access key"] = s3.AccessKey - lines["Secret key"] = s3.SecretKey + if o.AccessKey != "" || o.SecretKey != "" { + lines["Access key"] = o.AccessKey + lines["Secret key"] = o.SecretKey } - if s3.IAMRole != "" { - lines["IAM role"] = s3.IAMRole + if o.IAMRole != "" { + lines["IAM role"] = o.IAMRole } if !c.Globals.Verbose() { - lines["Service ID"] = s3.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/s3/list.go b/pkg/commands/logging/s3/list.go index 56d44335a..7fd6d3fa1 100644 --- a/pkg/commands/logging/s3/list.go +++ b/pkg/commands/logging/s3/list.go @@ -1,7 +1,6 @@ package s3 import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Amazon S3 logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListS3sInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - s3s, err := c.Globals.APIClient.ListS3s(&c.Input) + o, err := c.Globals.APIClient.ListS3s(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(s3s) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, s3 := range s3s { + for _, s3 := range o { tw.AddLine(s3.ServiceID, s3.ServiceVersion, s3.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, s3 := range s3s { - fmt.Fprintf(out, "\tS3 %d/%d\n", i+1, len(s3s)) + for i, s3 := range o { + fmt.Fprintf(out, "\tS3 %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", s3.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", s3.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", s3.Name) diff --git a/pkg/commands/logging/scalyr/describe.go b/pkg/commands/logging/scalyr/describe.go index 777043a95..2ffcd93f7 100644 --- a/pkg/commands/logging/scalyr/describe.go +++ b/pkg/commands/logging/scalyr/describe.go @@ -1,8 +1,6 @@ package scalyr import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Scalyr logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetScalyrInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,37 +84,28 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - scalyr, err := c.Globals.APIClient.GetScalyr(&c.Input) + o, err := c.Globals.APIClient.GetScalyr(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(scalyr) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Format version": scalyr.FormatVersion, - "Format": scalyr.Format, - "Name": scalyr.Name, - "Placement": scalyr.Placement, - "Region": scalyr.Region, - "Response condition": scalyr.ResponseCondition, - "Token": scalyr.Token, - "Version": scalyr.ServiceVersion, + "Format version": o.FormatVersion, + "Format": o.Format, + "Name": o.Name, + "Placement": o.Placement, + "Region": o.Region, + "Response condition": o.ResponseCondition, + "Token": o.Token, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = scalyr.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/scalyr/list.go b/pkg/commands/logging/scalyr/list.go index 23320a116..ef873404e 100644 --- a/pkg/commands/logging/scalyr/list.go +++ b/pkg/commands/logging/scalyr/list.go @@ -1,7 +1,6 @@ package scalyr import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Scalyr logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListScalyrsInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - scalyrs, err := c.Globals.APIClient.ListScalyrs(&c.Input) + o, err := c.Globals.APIClient.ListScalyrs(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(scalyrs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, scalyr := range scalyrs { + for _, scalyr := range o { tw.AddLine(scalyr.ServiceID, scalyr.ServiceVersion, scalyr.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, scalyr := range scalyrs { - fmt.Fprintf(out, "\tScalyr %d/%d\n", i+1, len(scalyrs)) + for i, scalyr := range o { + fmt.Fprintf(out, "\tScalyr %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", scalyr.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", scalyr.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", scalyr.Name) diff --git a/pkg/commands/logging/sftp/describe.go b/pkg/commands/logging/sftp/describe.go index 7b1dc78c6..f16cf7193 100644 --- a/pkg/commands/logging/sftp/describe.go +++ b/pkg/commands/logging/sftp/describe.go @@ -1,8 +1,6 @@ package sftp import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe an SFTP logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetSFTPInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,48 +84,39 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - sftp, err := c.Globals.APIClient.GetSFTP(&c.Input) + o, err := c.Globals.APIClient.GetSFTP(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(sftp) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Address": sftp.Address, - "Compression codec": sftp.CompressionCodec, - "Format version": sftp.FormatVersion, - "Format": sftp.Format, - "GZip level": sftp.GzipLevel, - "Message type": sftp.MessageType, - "Name": sftp.Name, - "Password": sftp.Password, - "Path": sftp.Path, - "Period": sftp.Period, - "Placement": sftp.Placement, - "Port": sftp.Port, - "Public key": sftp.PublicKey, - "Response condition": sftp.ResponseCondition, - "Secret key": sftp.SecretKey, - "SSH known hosts": sftp.SSHKnownHosts, - "Timestamp format": sftp.TimestampFormat, - "User": sftp.User, - "Version": sftp.ServiceVersion, + "Address": o.Address, + "Compression codec": o.CompressionCodec, + "Format version": o.FormatVersion, + "Format": o.Format, + "GZip level": o.GzipLevel, + "Message type": o.MessageType, + "Name": o.Name, + "Password": o.Password, + "Path": o.Path, + "Period": o.Period, + "Placement": o.Placement, + "Port": o.Port, + "Public key": o.PublicKey, + "Response condition": o.ResponseCondition, + "Secret key": o.SecretKey, + "SSH known hosts": o.SSHKnownHosts, + "Timestamp format": o.TimestampFormat, + "User": o.User, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = sftp.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/sftp/list.go b/pkg/commands/logging/sftp/list.go index ef75d9330..6f69ce6f4 100644 --- a/pkg/commands/logging/sftp/list.go +++ b/pkg/commands/logging/sftp/list.go @@ -1,7 +1,6 @@ package sftp import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list SFTP logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListSFTPsInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - sftps, err := c.Globals.APIClient.ListSFTPs(&c.Input) + o, err := c.Globals.APIClient.ListSFTPs(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(sftps) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, sftp := range sftps { + for _, sftp := range o { tw.AddLine(sftp.ServiceID, sftp.ServiceVersion, sftp.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, sftp := range sftps { - fmt.Fprintf(out, "\tSFTP %d/%d\n", i+1, len(sftps)) + for i, sftp := range o { + fmt.Fprintf(out, "\tSFTP %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", sftp.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", sftp.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", sftp.Name) diff --git a/pkg/commands/logging/splunk/describe.go b/pkg/commands/logging/splunk/describe.go index a5741de82..60da42ea2 100644 --- a/pkg/commands/logging/splunk/describe.go +++ b/pkg/commands/logging/splunk/describe.go @@ -1,8 +1,6 @@ package splunk import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Splunk logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetSplunkInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,41 +84,32 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - splunk, err := c.Globals.APIClient.GetSplunk(&c.Input) + o, err := c.Globals.APIClient.GetSplunk(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(splunk) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Format version": splunk.FormatVersion, - "Format": splunk.Format, - "Name": splunk.Name, - "Placement": splunk.Placement, - "Response condition": splunk.ResponseCondition, - "TLS CA certificate": splunk.TLSCACert, - "TLS client certificate": splunk.TLSClientCert, - "TLS client key": splunk.TLSClientKey, - "TLS hostname": splunk.TLSHostname, - "Token": splunk.Token, - "URL": splunk.URL, - "Version": splunk.ServiceVersion, + "Format version": o.FormatVersion, + "Format": o.Format, + "Name": o.Name, + "Placement": o.Placement, + "Response condition": o.ResponseCondition, + "TLS CA certificate": o.TLSCACert, + "TLS client certificate": o.TLSClientCert, + "TLS client key": o.TLSClientKey, + "TLS hostname": o.TLSHostname, + "Token": o.Token, + "URL": o.URL, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = splunk.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/splunk/list.go b/pkg/commands/logging/splunk/list.go index 9dbbde9c8..0ca1ae368 100644 --- a/pkg/commands/logging/splunk/list.go +++ b/pkg/commands/logging/splunk/list.go @@ -1,7 +1,6 @@ package splunk import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Splunk logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListSplunksInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - splunks, err := c.Globals.APIClient.ListSplunks(&c.Input) + o, err := c.Globals.APIClient.ListSplunks(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(splunks) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, splunk := range splunks { + for _, splunk := range o { tw.AddLine(splunk.ServiceID, splunk.ServiceVersion, splunk.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, splunk := range splunks { - fmt.Fprintf(out, "\tSplunk %d/%d\n", i+1, len(splunks)) + for i, splunk := range o { + fmt.Fprintf(out, "\tSplunk %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", splunk.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", splunk.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", splunk.Name) diff --git a/pkg/commands/logging/sumologic/describe.go b/pkg/commands/logging/sumologic/describe.go index bd0f65430..c45741754 100644 --- a/pkg/commands/logging/sumologic/describe.go +++ b/pkg/commands/logging/sumologic/describe.go @@ -1,8 +1,6 @@ package sumologic import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Sumologic logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetSumologicInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,37 +84,28 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - sumologic, err := c.Globals.APIClient.GetSumologic(&c.Input) + o, err := c.Globals.APIClient.GetSumologic(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(sumologic) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Format version": sumologic.FormatVersion, - "Format": sumologic.Format, - "Message type": sumologic.MessageType, - "Name": sumologic.Name, - "Placement": sumologic.Placement, - "Response condition": sumologic.ResponseCondition, - "URL": sumologic.URL, - "Version": sumologic.ServiceVersion, + "Format version": o.FormatVersion, + "Format": o.Format, + "Message type": o.MessageType, + "Name": o.Name, + "Placement": o.Placement, + "Response condition": o.ResponseCondition, + "URL": o.URL, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = sumologic.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/sumologic/list.go b/pkg/commands/logging/sumologic/list.go index 6f4be3d7e..6c6daddce 100644 --- a/pkg/commands/logging/sumologic/list.go +++ b/pkg/commands/logging/sumologic/list.go @@ -1,7 +1,6 @@ package sumologic import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Sumologic logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListSumologicsInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - sumologics, err := c.Globals.APIClient.ListSumologics(&c.Input) + o, err := c.Globals.APIClient.ListSumologics(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(sumologics) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, sumologic := range sumologics { + for _, sumologic := range o { tw.AddLine(sumologic.ServiceID, sumologic.ServiceVersion, sumologic.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, sumologic := range sumologics { - fmt.Fprintf(out, "\tSumologic %d/%d\n", i+1, len(sumologics)) + for i, sumologic := range o { + fmt.Fprintf(out, "\tSumologic %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", sumologic.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", sumologic.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", sumologic.Name) diff --git a/pkg/commands/logging/syslog/describe.go b/pkg/commands/logging/syslog/describe.go index 01bb52768..9db654809 100644 --- a/pkg/commands/logging/syslog/describe.go +++ b/pkg/commands/logging/syslog/describe.go @@ -1,8 +1,6 @@ package syslog import ( - "encoding/json" - "fmt" "io" "github.com/fastly/cli/pkg/cmd" @@ -16,9 +14,10 @@ import ( // DescribeCommand calls the Fastly API to describe a Syslog logging endpoint. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetSyslogInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -43,12 +42,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -66,7 +60,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,46 +84,37 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - syslog, err := c.Globals.APIClient.GetSyslog(&c.Input) + o, err := c.Globals.APIClient.GetSyslog(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if c.json { - data, err := json.Marshal(syslog) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil + if ok, err := c.WriteJSON(out, o); ok { + return err } lines := text.Lines{ - "Address": syslog.Address, - "Format version": syslog.FormatVersion, - "Format": syslog.Format, - "Hostname": syslog.Hostname, - "IPV4": syslog.IPV4, - "Message type": syslog.MessageType, - "Name": syslog.Name, - "Placement": syslog.Placement, - "Port": syslog.Port, - "Response condition": syslog.ResponseCondition, - "TLS CA certificate": syslog.TLSCACert, - "TLS client certificate": syslog.TLSClientCert, - "TLS client key": syslog.TLSClientKey, - "TLS hostname": syslog.TLSHostname, - "Token": syslog.Token, - "Use TLS": syslog.UseTLS, - "Version": syslog.ServiceVersion, + "Address": o.Address, + "Format version": o.FormatVersion, + "Format": o.Format, + "Hostname": o.Hostname, + "IPV4": o.IPV4, + "Message type": o.MessageType, + "Name": o.Name, + "Placement": o.Placement, + "Port": o.Port, + "Response condition": o.ResponseCondition, + "TLS CA certificate": o.TLSCACert, + "TLS client certificate": o.TLSClientCert, + "TLS client key": o.TLSClientKey, + "TLS hostname": o.TLSHostname, + "Token": o.Token, + "Use TLS": o.UseTLS, + "Version": o.ServiceVersion, } if !c.Globals.Verbose() { - lines["Service ID"] = syslog.ServiceID + lines["Service ID"] = o.ServiceID } text.PrintLines(out, lines) diff --git a/pkg/commands/logging/syslog/list.go b/pkg/commands/logging/syslog/list.go index f1b9151c2..5ccae8b96 100644 --- a/pkg/commands/logging/syslog/list.go +++ b/pkg/commands/logging/syslog/list.go @@ -1,7 +1,6 @@ package syslog import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // ListCommand calls the Fastly API to list Syslog logging endpoints. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListSyslogsInput - json bool serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion } @@ -42,12 +42,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -65,7 +60,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,29 +84,20 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID c.Input.ServiceVersion = serviceVersion.Number - syslogs, err := c.Globals.APIClient.ListSyslogs(&c.Input) + o, err := c.Globals.APIClient.ListSyslogs(&c.Input) if err != nil { c.Globals.ErrLog.Add(err) return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(syslogs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("SERVICE", "VERSION", "NAME") - for _, syslog := range syslogs { + for _, syslog := range o { tw.AddLine(syslog.ServiceID, syslog.ServiceVersion, syslog.Name) } tw.Print() @@ -119,8 +105,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } fmt.Fprintf(out, "Version: %d\n", c.Input.ServiceVersion) - for i, syslog := range syslogs { - fmt.Fprintf(out, "\tSyslog %d/%d\n", i+1, len(syslogs)) + for i, syslog := range o { + fmt.Fprintf(out, "\tSyslog %d/%d\n", i+1, len(o)) fmt.Fprintf(out, "\t\tService ID: %s\n", syslog.ServiceID) fmt.Fprintf(out, "\t\tVersion: %d\n", syslog.ServiceVersion) fmt.Fprintf(out, "\t\tName: %s\n", syslog.Name) diff --git a/pkg/commands/profile/list.go b/pkg/commands/profile/list.go index cdbe52dc1..86febbb1e 100644 --- a/pkg/commands/profile/list.go +++ b/pkg/commands/profile/list.go @@ -1,7 +1,6 @@ package profile import ( - "encoding/json" "fmt" "io" @@ -16,7 +15,7 @@ import ( // ListCommand represents a Kingpin command. type ListCommand struct { cmd.Base - json bool + cmd.JSONOutput } // NewListCommand returns a usable command registered under the parent. @@ -24,34 +23,18 @@ func NewListCommand(parent cmd.Registerer, g *global.Data) *ListCommand { var c ListCommand c.Globals = g c.CmdClause = parent.Command("list", "List user profiles") - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(c.Globals.Config.Profiles) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, c.Globals.Config.Profiles); ok { + return err } if c.Globals.Config.Profiles == nil { diff --git a/pkg/commands/resourcelink/create.go b/pkg/commands/resourcelink/create.go index 48f467409..e30876df1 100644 --- a/pkg/commands/resourcelink/create.go +++ b/pkg/commands/resourcelink/create.go @@ -109,7 +109,7 @@ func (c *CreateCommand) Exec(_ io.Reader, out io.Writer) error { c.input.ServiceID = serviceID c.input.ServiceVersion = serviceVersion.Number - resource, err := c.Globals.APIClient.CreateResource(&c.input) + o, err := c.Globals.APIClient.CreateResource(&c.input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "ID": c.input.ResourceID, @@ -119,10 +119,10 @@ func (c *CreateCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if ok, err := c.WriteJSON(out, resource); ok { + if ok, err := c.WriteJSON(out, o); ok { return err } - text.Success(out, "Created service resource link %q (%s) on service %s version %s", resource.Name, resource.ID, resource.ServiceID, resource.ServiceVersion) + text.Success(out, "Created service resource link %q (%s) on service %s version %s", o.Name, o.ID, o.ServiceID, o.ServiceVersion) return nil } diff --git a/pkg/commands/resourcelink/describe.go b/pkg/commands/resourcelink/describe.go index a694860f6..9c460f8c9 100644 --- a/pkg/commands/resourcelink/describe.go +++ b/pkg/commands/resourcelink/describe.go @@ -88,7 +88,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.input.ServiceID = serviceID c.input.ServiceVersion = serviceVersion.Number - resource, err := c.Globals.APIClient.GetResource(&c.input) + o, err := c.Globals.APIClient.GetResource(&c.input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "ID": c.input.ID, @@ -98,15 +98,15 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if ok, err := c.WriteJSON(out, resource); ok { + if ok, err := c.WriteJSON(out, o); ok { return err } if !c.Globals.Verbose() { - text.Output(out, "Service ID: %s", resource.ServiceID) + text.Output(out, "Service ID: %s", o.ServiceID) } - text.Output(out, "Service Version: %s", resource.ServiceVersion) - text.PrintResource(out, "", resource) + text.Output(out, "Service Version: %s", o.ServiceVersion) + text.PrintResource(out, "", o) return nil } diff --git a/pkg/commands/resourcelink/list.go b/pkg/commands/resourcelink/list.go index 31fbd9636..93406d97d 100644 --- a/pkg/commands/resourcelink/list.go +++ b/pkg/commands/resourcelink/list.go @@ -83,7 +83,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.input.ServiceID = serviceID c.input.ServiceVersion = serviceVersion.Number - resources, err := c.Globals.APIClient.ListResources(&c.input) + o, err := c.Globals.APIClient.ListResources(&c.input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": c.input.ServiceID, @@ -92,7 +92,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if ok, err := c.WriteJSON(out, resources); ok { + if ok, err := c.WriteJSON(out, o); ok { return err } @@ -101,8 +101,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } text.Output(out, "Service Version: %d\n", c.input.ServiceVersion) - for i, resource := range resources { - fmt.Fprintf(out, "Resource Link %d/%d\n", i+1, len(resources)) + for i, resource := range o { + fmt.Fprintf(out, "Resource Link %d/%d\n", i+1, len(o)) text.PrintResource(out, "\t", resource) fmt.Fprintln(out) } diff --git a/pkg/commands/resourcelink/update.go b/pkg/commands/resourcelink/update.go index aeacff2f9..5c8d1fca5 100644 --- a/pkg/commands/resourcelink/update.go +++ b/pkg/commands/resourcelink/update.go @@ -108,7 +108,7 @@ func (c *UpdateCommand) Exec(_ io.Reader, out io.Writer) error { c.input.ServiceID = serviceID c.input.ServiceVersion = serviceVersion.Number - resource, err := c.Globals.APIClient.UpdateResource(&c.input) + o, err := c.Globals.APIClient.UpdateResource(&c.input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "ID": c.input.ID, @@ -118,10 +118,10 @@ func (c *UpdateCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if ok, err := c.WriteJSON(out, resource); ok { + if ok, err := c.WriteJSON(out, o); ok { return err } - text.Success(out, "Updated service resource link %s on service %s version %s", resource.ID, resource.ServiceID, resource.ServiceVersion) + text.Success(out, "Updated service resource link %s on service %s version %s", o.ID, o.ServiceID, o.ServiceVersion) return nil } diff --git a/pkg/commands/service/describe.go b/pkg/commands/service/describe.go index bc9351d88..0684628ce 100644 --- a/pkg/commands/service/describe.go +++ b/pkg/commands/service/describe.go @@ -1,7 +1,6 @@ package service import ( - "encoding/json" "fmt" "io" "strconv" @@ -18,9 +17,10 @@ import ( // DescribeCommand calls the Fastly API to describe a service. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetServiceInput - json bool serviceName cmd.OptionalServiceNameID } @@ -35,12 +35,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) c.CmdClause = parent.Command("describe", "Show detailed information about a Fastly service").Alias("get") // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -58,7 +53,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -78,7 +73,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ID = serviceID - service, err := c.Globals.APIClient.GetServiceDetails(&c.Input) + o, err := c.Globals.APIClient.GetServiceDetails(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -86,23 +81,14 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(service, out) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(o, out) } func (c *DescribeCommand) print(s *fastly.ServiceDetail, out io.Writer) error { - if c.json { - data, err := json.Marshal(s) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - activeVersion := "none" if s.ActiveVersion.Active { activeVersion = strconv.Itoa(s.ActiveVersion.Number) diff --git a/pkg/commands/service/list.go b/pkg/commands/service/list.go index fc1e7390f..496b505de 100644 --- a/pkg/commands/service/list.go +++ b/pkg/commands/service/list.go @@ -1,7 +1,6 @@ package service import ( - "encoding/json" "fmt" "io" @@ -16,8 +15,9 @@ import ( // ListCommand calls the Fastly API to list services. type ListCommand struct { cmd.Base + cmd.JSONOutput + input fastly.ListServicesInput - json bool } // NewListCommand returns a usable command registered under the parent. @@ -31,12 +31,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data) *ListCommand { // optional c.CmdClause.Flag("direction", "Direction in which to sort results").Default(cmd.PaginationDirection[0]).HintOptions(cmd.PaginationDirection...).EnumVar(&c.input.Direction, cmd.PaginationDirection...) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.CmdClause.Flag("page", "Page number of data set to fetch").IntVar(&c.input.Page) c.CmdClause.Flag("per-page", "Number of records per page").IntVar(&c.input.PerPage) c.CmdClause.Flag("sort", "Field on which to sort").Default("created").StringVar(&c.input.Sort) @@ -45,13 +40,13 @@ func NewListCommand(parent cmd.Registerer, g *global.Data) *ListCommand { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } paginator := c.Globals.APIClient.NewListServicesPaginator(&c.input) - var ss []*fastly.Service + var o []*fastly.Service for paginator.HasNext() { data, err := paginator.GetNext() if err != nil { @@ -60,26 +55,17 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { }) return err } - ss = append(ss, data...) + o = append(o, data...) } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(ss) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("NAME", "ID", "TYPE", "ACTIVE VERSION", "LAST EDITED (UTC)") - for _, service := range ss { + for _, service := range o { updatedAt := "n/a" if service.UpdatedAt != nil { updatedAt = service.UpdatedAt.UTC().Format(time.Format) @@ -98,8 +84,8 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return nil } - for i, service := range ss { - fmt.Fprintf(out, "Service %d/%d\n", i+1, len(ss)) + for i, service := range o { + fmt.Fprintf(out, "Service %d/%d\n", i+1, len(o)) text.PrintService(out, "\t", service) fmt.Fprintln(out) } diff --git a/pkg/commands/serviceauth/describe.go b/pkg/commands/serviceauth/describe.go index 93c10d76b..f7ae4b123 100644 --- a/pkg/commands/serviceauth/describe.go +++ b/pkg/commands/serviceauth/describe.go @@ -1,7 +1,6 @@ package serviceauth import ( - "encoding/json" "fmt" "io" @@ -16,9 +15,10 @@ import ( // DescribeCommand calls the Fastly API to describe a service authorization. type DescribeCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.GetServiceAuthorizationInput - json bool } // NewDescribeCommand returns a usable command registered under the parent. @@ -35,22 +35,17 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) c.CmdClause.Flag("id", "ID of the service authorization to retrieve").Required().StringVar(&c.Input.ID) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } - service, err := c.Globals.APIClient.GetServiceAuthorization(&c.Input) + o, err := c.Globals.APIClient.GetServiceAuthorization(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service Authorization ID": c.Input.ID, @@ -58,23 +53,14 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(service, out) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(o, out) } func (c *DescribeCommand) print(s *fastly.ServiceAuthorization, out io.Writer) error { - if c.json { - data, err := json.Marshal(s) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - fmt.Fprintf(out, "Auth ID: %s\n", s.ID) fmt.Fprintf(out, "User ID: %s\n", s.User.ID) fmt.Fprintf(out, "Service ID: %s\n", s.Service.ID) diff --git a/pkg/commands/serviceauth/list.go b/pkg/commands/serviceauth/list.go index 3c09f8c2c..a15508b78 100644 --- a/pkg/commands/serviceauth/list.go +++ b/pkg/commands/serviceauth/list.go @@ -1,7 +1,6 @@ package serviceauth import ( - "encoding/json" "fmt" "io" @@ -16,8 +15,9 @@ import ( // ListCommand calls the Fastly API to list service authorizations. type ListCommand struct { cmd.Base + cmd.JSONOutput + input fastly.ListServiceAuthorizationsInput - json bool } // NewListCommand returns a usable command registered under the parent. @@ -27,12 +27,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data) *ListCommand { c.CmdClause = parent.Command("list", "List service authorizations") // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.CmdClause.Flag("page", "Page number of data set to fetch").IntVar(&c.input.PageNumber) c.CmdClause.Flag("per-page", "Number of records per page").IntVar(&c.input.PageSize) return &c @@ -40,11 +35,11 @@ func NewListCommand(parent cmd.Registerer, g *global.Data) *ListCommand { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } - resp, err := c.Globals.APIClient.ListServiceAuthorizations(&c.input) + o, err := c.Globals.APIClient.ListServiceAuthorizations(&c.input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Page Number": c.input.PageNumber, @@ -53,25 +48,16 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(resp) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } - if len(resp.Items) > 0 { + if !c.Globals.Verbose() { + if len(o.Items) > 0 { tw := text.NewTable(out) tw.AddHeader("AUTH ID", "USER ID", "SERVICE ID", "PERMISSION") - for _, s := range resp.Items { + for _, s := range o.Items { tw.AddLine(s.ID, s.User.ID, s.Service.ID, s.Permission) } tw.Print() @@ -80,7 +66,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { } } - for _, s := range resp.Items { + for _, s := range o.Items { fmt.Fprintf(out, "Auth ID: %s\n", s.ID) fmt.Fprintf(out, "User ID: %s\n", s.User.ID) fmt.Fprintf(out, "Service ID: %s\n", s.Service.ID) diff --git a/pkg/commands/serviceversion/list.go b/pkg/commands/serviceversion/list.go index b87fbc180..17d6c775c 100644 --- a/pkg/commands/serviceversion/list.go +++ b/pkg/commands/serviceversion/list.go @@ -1,7 +1,6 @@ package serviceversion import ( - "encoding/json" "fmt" "io" @@ -17,9 +16,10 @@ import ( // ListCommand calls the Fastly API to list services. type ListCommand struct { cmd.Base + cmd.JSONOutput + manifest manifest.Data Input fastly.ListVersionsInput - json bool serviceName cmd.OptionalServiceNameID } @@ -32,12 +32,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis manifest: m, } c.CmdClause = parent.Command("list", "List Fastly service versions") - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -55,7 +50,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -69,7 +64,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { c.Input.ServiceID = serviceID - versions, err := c.Globals.APIClient.ListVersions(&c.Input) + o, err := c.Globals.APIClient.ListVersions(&c.Input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -77,32 +72,23 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } - if !c.Globals.Verbose() { - if c.json { - data, err := json.Marshal(versions) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if !c.Globals.Verbose() { tw := text.NewTable(out) tw.AddHeader("NUMBER", "ACTIVE", "LAST EDITED (UTC)") - for _, version := range versions { + for _, version := range o { tw.AddLine(version.Number, version.Active, version.UpdatedAt.UTC().Format(time.Format)) } tw.Print() return nil } - fmt.Fprintf(out, "Versions: %d\n", len(versions)) - for i, version := range versions { - fmt.Fprintf(out, "\tVersion %d/%d\n", i+1, len(versions)) + fmt.Fprintf(out, "Versions: %d\n", len(o)) + for i, version := range o { + fmt.Fprintf(out, "\tVersion %d/%d\n", i+1, len(o)) text.PrintVersion(out, "\t\t", version) } fmt.Fprintln(out) diff --git a/pkg/commands/tls/config/describe.go b/pkg/commands/tls/config/describe.go index 1346422b2..42295fdab 100644 --- a/pkg/commands/tls/config/describe.go +++ b/pkg/commands/tls/config/describe.go @@ -1,7 +1,6 @@ package config import ( - "encoding/json" "fmt" "io" @@ -26,12 +25,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // optional c.CmdClause.Flag("include", "Include related objects (comma-separated values)").HintOptions(include).EnumVar(&c.include, include) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } @@ -39,22 +33,22 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput id string include string - json bool manifest manifest.Data } // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - r, err := c.Globals.APIClient.GetCustomTLSConfiguration(input) + o, err := c.Globals.APIClient.GetCustomTLSConfiguration(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "TLS Configuration ID": c.id, @@ -62,7 +56,11 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, r) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. @@ -80,19 +78,6 @@ func (c *DescribeCommand) constructInput() *fastly.GetCustomTLSConfigurationInpu // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, r *fastly.CustomTLSConfiguration) error { - if c.json { - data, err := json.Marshal(r) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - fmt.Fprintf(out, "\nID: %s\n", r.ID) fmt.Fprintf(out, "Name: %s\n", r.Name) diff --git a/pkg/commands/tls/config/list.go b/pkg/commands/tls/config/list.go index 8855f932d..6ec904bd4 100644 --- a/pkg/commands/tls/config/list.go +++ b/pkg/commands/tls/config/list.go @@ -1,7 +1,6 @@ package config import ( - "encoding/json" "fmt" "io" "strings" @@ -24,12 +23,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // optional c.CmdClause.Flag("filter-bulk", "Optionally filter by the bulk attribute").Action(c.filterBulk.Set).BoolVar(&c.filterBulk.Value) c.CmdClause.Flag("include", "Include related objects (comma-separated values)").HintOptions(include).EnumVar(&c.include, include) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.CmdClause.Flag("page", "Page number of data set to fetch").IntVar(&c.pageNumber) c.CmdClause.Flag("per-page", "Number of records per page").IntVar(&c.pageSize) @@ -39,10 +33,10 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput filterBulk cmd.OptionalBool include string - json bool manifest manifest.Data pageNumber int pageSize int @@ -50,13 +44,13 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - rs, err := c.Globals.APIClient.ListCustomTLSConfigurations(input) + o, err := c.Globals.APIClient.ListCustomTLSConfigurations(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Filter Bulk": c.filterBulk, @@ -67,10 +61,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - c.printVerbose(out, rs) + c.printVerbose(out, o) } else { - err = c.printSummary(out, rs) + err = c.printSummary(out, o) if err != nil { return err } @@ -144,19 +142,6 @@ func (c *ListCommand) printVerbose(out io.Writer, rs []*fastly.CustomTLSConfigur // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, rs []*fastly.CustomTLSConfiguration) error { - if c.json { - data, err := json.Marshal(rs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("NAME", "ID", "BULK", "DEFAULT", "TLS PROTOCOLS", "HTTP PROTOCOLS", "DNS RECORDS") for _, r := range rs { diff --git a/pkg/commands/tls/custom/activation/describe.go b/pkg/commands/tls/custom/activation/describe.go index aa0fc896d..0d1d0d89e 100644 --- a/pkg/commands/tls/custom/activation/describe.go +++ b/pkg/commands/tls/custom/activation/describe.go @@ -1,7 +1,6 @@ package activation import ( - "encoding/json" "fmt" "io" @@ -26,12 +25,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // optional c.CmdClause.Flag("include", "Include related objects (comma-separated values)").HintOptions(include...).EnumVar(&c.include, include...) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } @@ -39,22 +33,22 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput id string include string - json bool manifest manifest.Data } // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - r, err := c.Globals.APIClient.GetTLSActivation(input) + o, err := c.Globals.APIClient.GetTLSActivation(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "TLS Activation ID": c.id, @@ -62,7 +56,11 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, r) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. @@ -80,19 +78,6 @@ func (c *DescribeCommand) constructInput() *fastly.GetTLSActivationInput { // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, r *fastly.TLSActivation) error { - if c.json { - data, err := json.Marshal(r) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - fmt.Fprintf(out, "\nID: %s\n", r.ID) if r.CreatedAt != nil { diff --git a/pkg/commands/tls/custom/activation/list.go b/pkg/commands/tls/custom/activation/list.go index 6c4e97e8e..1adb17faf 100644 --- a/pkg/commands/tls/custom/activation/list.go +++ b/pkg/commands/tls/custom/activation/list.go @@ -1,7 +1,6 @@ package activation import ( - "encoding/json" "fmt" "io" @@ -25,12 +24,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis c.CmdClause.Flag("filter-config", "Limit the returned activations to a specific TLS configuration").StringVar(&c.filterTLSConfigID) c.CmdClause.Flag("filter-domain", "Limit the returned rules to a specific domain name").StringVar(&c.filterTLSDomainID) c.CmdClause.Flag("include", "Include related objects (comma-separated values)").HintOptions(include...).EnumVar(&c.include, include...) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.CmdClause.Flag("page", "Page number of data set to fetch").IntVar(&c.pageNumber) c.CmdClause.Flag("per-page", "Number of records per page").IntVar(&c.pageSize) @@ -40,12 +34,12 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput filterTLSCertID string filterTLSConfigID string filterTLSDomainID string include string - json bool manifest manifest.Data pageNumber int pageSize int @@ -53,13 +47,13 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - rs, err := c.Globals.APIClient.ListTLSActivations(input) + o, err := c.Globals.APIClient.ListTLSActivations(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Filter TLS Certificate ID": c.filterTLSCertID, @@ -72,10 +66,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - c.printVerbose(out, rs) + c.printVerbose(out, o) } else { - err = c.printSummary(out, rs) + err = c.printSummary(out, o) if err != nil { return err } @@ -126,19 +124,6 @@ func (c *ListCommand) printVerbose(out io.Writer, rs []*fastly.TLSActivation) { // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, rs []*fastly.TLSActivation) error { - if c.json { - data, err := json.Marshal(rs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("ID", "CREATED_AT") for _, r := range rs { diff --git a/pkg/commands/tls/custom/certificate/describe.go b/pkg/commands/tls/custom/certificate/describe.go index 363fe3a65..7960d2dd2 100644 --- a/pkg/commands/tls/custom/certificate/describe.go +++ b/pkg/commands/tls/custom/certificate/describe.go @@ -1,7 +1,6 @@ package certificate import ( - "encoding/json" "fmt" "io" @@ -23,12 +22,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) c.CmdClause.Flag("id", "Alphanumeric string identifying a TLS certificate").Required().StringVar(&c.id) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } @@ -36,21 +30,21 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput id string - json bool manifest manifest.Data } // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - r, err := c.Globals.APIClient.GetCustomTLSCertificate(input) + o, err := c.Globals.APIClient.GetCustomTLSCertificate(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "TLS Certificate ID": c.id, @@ -58,7 +52,11 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, r) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. @@ -72,19 +70,6 @@ func (c *DescribeCommand) constructInput() *fastly.GetCustomTLSCertificateInput // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, r *fastly.CustomTLSCertificate) error { - if c.json { - data, err := json.Marshal(r) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - fmt.Fprintf(out, "\nID: %s\n", r.ID) fmt.Fprintf(out, "Issued to: %s\n", r.IssuedTo) fmt.Fprintf(out, "Issuer: %s\n", r.Issuer) diff --git a/pkg/commands/tls/custom/certificate/list.go b/pkg/commands/tls/custom/certificate/list.go index 2dda8e894..8890e5db3 100644 --- a/pkg/commands/tls/custom/certificate/list.go +++ b/pkg/commands/tls/custom/certificate/list.go @@ -1,7 +1,6 @@ package certificate import ( - "encoding/json" "fmt" "io" @@ -26,12 +25,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis c.CmdClause.Flag("filter-not-after", "Limit the returned certificates to those that expire prior to the specified date in UTC").StringVar(&c.filterNotAfter) c.CmdClause.Flag("filter-domain", "Limit the returned certificates to those that include the specific domain").StringVar(&c.filterTLSDomainID) c.CmdClause.Flag("include", "Include related objects (comma-separated values)").HintOptions("tls_activations").EnumVar(&c.include, "tls_activations") - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.CmdClause.Flag("page", "Page number of data set to fetch").IntVar(&c.pageNumber) c.CmdClause.Flag("per-page", "Number of records per page").IntVar(&c.pageSize) c.CmdClause.Flag("sort", "The order in which to list the results by creation date").StringVar(&c.sort) @@ -42,11 +36,11 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput filterNotAfter string filterTLSDomainID string include string - json bool manifest manifest.Data pageNumber int pageSize int @@ -55,13 +49,13 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - rs, err := c.Globals.APIClient.ListCustomTLSCertificates(input) + o, err := c.Globals.APIClient.ListCustomTLSCertificates(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Filter Not After": c.filterNotAfter, @@ -74,10 +68,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - printVerbose(out, rs) + printVerbose(out, o) } else { - err = c.printSummary(out, rs) + err = c.printSummary(out, o) if err != nil { return err } @@ -145,19 +143,6 @@ func printVerbose(out io.Writer, rs []*fastly.CustomTLSCertificate) { // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, rs []*fastly.CustomTLSCertificate) error { - if c.json { - data, err := json.Marshal(rs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("ID", "ISSUED TO", "NAME", "REPLACE", "SIGNATURE ALGORITHM") for _, r := range rs { diff --git a/pkg/commands/tls/custom/domain/list.go b/pkg/commands/tls/custom/domain/list.go index 7b9e0d7f8..29f143a9e 100644 --- a/pkg/commands/tls/custom/domain/list.go +++ b/pkg/commands/tls/custom/domain/list.go @@ -1,7 +1,6 @@ package domain import ( - "encoding/json" "fmt" "io" @@ -27,12 +26,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis c.CmdClause.Flag("filter-in-use", "Limit the returned domains to those currently using Fastly to terminate TLS with SNI").Action(c.filterInUse.Set).BoolVar(&c.filterInUse.Value) c.CmdClause.Flag("filter-subscription", "Limit the returned domains to those for a given TLS subscription").StringVar(&c.filterTLSSubsID) c.CmdClause.Flag("include", "Include related objects (comma-separated values)").HintOptions("tls_activations").EnumVar(&c.include, "tls_activations") - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.CmdClause.Flag("page", "Page number of data set to fetch").IntVar(&c.pageNumber) c.CmdClause.Flag("per-page", "Number of records per page").IntVar(&c.pageSize) c.CmdClause.Flag("sort", "The order in which to list the results by creation date").StringVar(&c.sort) @@ -43,12 +37,12 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput filterInUse cmd.OptionalBool filterTLSCertsID string filterTLSSubsID string include string - json bool manifest manifest.Data pageNumber int pageSize int @@ -57,13 +51,13 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - rs, err := c.Globals.APIClient.ListTLSDomains(input) + o, err := c.Globals.APIClient.ListTLSDomains(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Filter In Use": c.filterInUse, @@ -77,10 +71,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - printVerbose(out, rs) + printVerbose(out, o) } else { - err = c.printSummary(out, rs) + err = c.printSummary(out, o) if err != nil { return err } @@ -130,19 +128,6 @@ func printVerbose(out io.Writer, rs []*fastly.TLSDomain) { // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, rs []*fastly.TLSDomain) error { - if c.json { - data, err := json.Marshal(rs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("ID", "TYPE") for _, r := range rs { diff --git a/pkg/commands/tls/custom/privatekey/describe.go b/pkg/commands/tls/custom/privatekey/describe.go index e49008f4a..fc4979e14 100644 --- a/pkg/commands/tls/custom/privatekey/describe.go +++ b/pkg/commands/tls/custom/privatekey/describe.go @@ -1,7 +1,6 @@ package privatekey import ( - "encoding/json" "fmt" "io" @@ -23,12 +22,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) c.CmdClause.Flag("id", "Alphanumeric string identifying a private Key").Required().StringVar(&c.id) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } @@ -36,21 +30,21 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput id string - json bool manifest manifest.Data } // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - r, err := c.Globals.APIClient.GetPrivateKey(input) + o, err := c.Globals.APIClient.GetPrivateKey(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "TLS Certificate ID": c.id, @@ -58,7 +52,11 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, r) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. @@ -72,19 +70,6 @@ func (c *DescribeCommand) constructInput() *fastly.GetPrivateKeyInput { // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, r *fastly.PrivateKey) error { - if c.json { - data, err := json.Marshal(r) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - fmt.Fprintf(out, "\nID: %s\n", r.ID) fmt.Fprintf(out, "Name: %s\n", r.Name) fmt.Fprintf(out, "Key Length: %d\n", r.KeyLength) diff --git a/pkg/commands/tls/custom/privatekey/list.go b/pkg/commands/tls/custom/privatekey/list.go index 96a4f60c7..8752364e9 100644 --- a/pkg/commands/tls/custom/privatekey/list.go +++ b/pkg/commands/tls/custom/privatekey/list.go @@ -1,7 +1,6 @@ package privatekey import ( - "encoding/json" "fmt" "io" @@ -22,12 +21,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // optional c.CmdClause.Flag("filter-in-use", "Limit the returned keys to those without any matching TLS certificates").HintOptions("false").EnumVar(&c.filterInUse, "false") - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.CmdClause.Flag("page", "Page number of data set to fetch").IntVar(&c.pageNumber) c.CmdClause.Flag("per-page", "Number of records per page").IntVar(&c.pageSize) @@ -37,9 +31,9 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput filterInUse string - json bool manifest manifest.Data pageNumber int pageSize int @@ -47,13 +41,13 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - rs, err := c.Globals.APIClient.ListPrivateKeys(input) + o, err := c.Globals.APIClient.ListPrivateKeys(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Filter In Use": c.filterInUse, @@ -63,10 +57,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - printVerbose(out, rs) + printVerbose(out, o) } else { - err = c.printSummary(out, rs) + err = c.printSummary(out, o) if err != nil { return err } @@ -113,19 +111,6 @@ func printVerbose(out io.Writer, rs []*fastly.PrivateKey) { // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, rs []*fastly.PrivateKey) error { - if c.json { - data, err := json.Marshal(rs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("ID", "NAME", "KEY LENGTH", "KEY TYPE", "PUBLIC KEY SHA1", "REPLACE") for _, r := range rs { diff --git a/pkg/commands/tls/platform/describe.go b/pkg/commands/tls/platform/describe.go index 45cb56b4e..1938f64db 100644 --- a/pkg/commands/tls/platform/describe.go +++ b/pkg/commands/tls/platform/describe.go @@ -1,7 +1,6 @@ package platform import ( - "encoding/json" "fmt" "io" @@ -23,12 +22,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) c.CmdClause.Flag("id", "Alphanumeric string identifying a TLS bulk certificate").Required().StringVar(&c.id) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } @@ -36,21 +30,21 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput id string - json bool manifest manifest.Data } // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - r, err := c.Globals.APIClient.GetBulkCertificate(input) + o, err := c.Globals.APIClient.GetBulkCertificate(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "TLS Bulk Certificate ID": c.id, @@ -58,7 +52,11 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, r) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. @@ -72,19 +70,6 @@ func (c *DescribeCommand) constructInput() *fastly.GetBulkCertificateInput { // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, r *fastly.BulkCertificate) error { - if c.json { - data, err := json.Marshal(r) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - fmt.Fprintf(out, "\nID: %s\n", r.ID) if r.NotAfter != nil { diff --git a/pkg/commands/tls/platform/list.go b/pkg/commands/tls/platform/list.go index 5b9c21588..f113f2ede 100644 --- a/pkg/commands/tls/platform/list.go +++ b/pkg/commands/tls/platform/list.go @@ -1,7 +1,6 @@ package platform import ( - "encoding/json" "fmt" "io" @@ -22,12 +21,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // optional c.CmdClause.Flag("filter-domain", "Optionally filter by the bulk attribute").StringVar(&c.filterTLSDomainID) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.CmdClause.Flag("page", "Page number of data set to fetch").IntVar(&c.pageNumber) c.CmdClause.Flag("per-page", "Number of records per page").IntVar(&c.pageSize) c.CmdClause.Flag("sort", "The order in which to list the results by creation date").StringVar(&c.sort) @@ -38,9 +32,9 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput filterTLSDomainID string - json bool manifest manifest.Data pageNumber int pageSize int @@ -49,13 +43,13 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - rs, err := c.Globals.APIClient.ListBulkCertificates(input) + o, err := c.Globals.APIClient.ListBulkCertificates(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Filter TLS Domain ID": c.filterTLSDomainID, @@ -66,10 +60,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - printVerbose(out, rs) + printVerbose(out, o) } else { - err = c.printSummary(out, rs) + err = c.printSummary(out, o) if err != nil { return err } @@ -124,19 +122,6 @@ func printVerbose(out io.Writer, rs []*fastly.BulkCertificate) { // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, rs []*fastly.BulkCertificate) error { - if c.json { - data, err := json.Marshal(rs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("ID", "REPLACE", "NOT BEFORE", "NOT AFTER", "CREATED") for _, r := range rs { diff --git a/pkg/commands/tls/subscription/describe.go b/pkg/commands/tls/subscription/describe.go index f7b993558..a70e7c51b 100644 --- a/pkg/commands/tls/subscription/describe.go +++ b/pkg/commands/tls/subscription/describe.go @@ -1,7 +1,6 @@ package subscription import ( - "encoding/json" "fmt" "io" @@ -26,12 +25,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // optional c.CmdClause.Flag("include", "Include related objects (comma-separated values)").HintOptions(include...).EnumVar(&c.include, include...) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } @@ -39,22 +33,22 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput id string include string - json bool manifest manifest.Data } // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - r, err := c.Globals.APIClient.GetTLSSubscription(input) + o, err := c.Globals.APIClient.GetTLSSubscription(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "TLS Subscription ID": c.id, @@ -63,7 +57,11 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, r) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. @@ -81,20 +79,6 @@ func (c *DescribeCommand) constructInput() *fastly.GetTLSSubscriptionInput { // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, r *fastly.TLSSubscription) error { - if c.json { - data, err := json.Marshal(r) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - - return nil - } - fmt.Fprintf(out, "\nID: %s\n", r.ID) fmt.Fprintf(out, "Certificate Authority: %s\n", r.CertificateAuthority) fmt.Fprintf(out, "State: %s\n", r.State) diff --git a/pkg/commands/tls/subscription/list.go b/pkg/commands/tls/subscription/list.go index 7ce24e415..0771f979f 100644 --- a/pkg/commands/tls/subscription/list.go +++ b/pkg/commands/tls/subscription/list.go @@ -1,7 +1,6 @@ package subscription import ( - "encoding/json" "fmt" "io" @@ -27,12 +26,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis c.CmdClause.Flag("filter-domain", "Limit the returned subscriptions to those that include the specific domain").StringVar(&c.filterTLSDomainID) c.CmdClause.Flag("filter-state", "Limit the returned subscriptions by state").HintOptions(states...).EnumVar(&c.filterState, states...) c.CmdClause.Flag("include", "Include related objects (comma-separated values)").HintOptions(include...).EnumVar(&c.include, include...) // include is defined in ./describe.go - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.CmdClause.Flag("page", "Page number of data set to fetch").IntVar(&c.pageNumber) c.CmdClause.Flag("per-page", "Number of records per page").IntVar(&c.pageSize) c.CmdClause.Flag("sort", "The order in which to list the results by creation date").StringVar(&c.sort) @@ -43,12 +37,12 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput filterHasActiveOrder bool filterState string filterTLSDomainID string include string - json bool manifest manifest.Data pageNumber int pageSize int @@ -57,13 +51,13 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } input := c.constructInput() - rs, err := c.Globals.APIClient.ListTLSSubscriptions(input) + o, err := c.Globals.APIClient.ListTLSSubscriptions(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Filter Active": c.filterHasActiveOrder, @@ -77,10 +71,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - c.printVerbose(out, rs) + c.printVerbose(out, o) } else { - err = c.printSummary(out, rs) + err = c.printSummary(out, o) if err != nil { return err } @@ -139,19 +137,6 @@ func (c *ListCommand) printVerbose(out io.Writer, rs []*fastly.TLSSubscription) // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, rs []*fastly.TLSSubscription) error { - if c.json { - data, err := json.Marshal(rs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("ID", "CERT AUTHORITY", "STATE", "CREATED") for _, r := range rs { diff --git a/pkg/commands/user/describe.go b/pkg/commands/user/describe.go index c617b623a..f5d61313d 100644 --- a/pkg/commands/user/describe.go +++ b/pkg/commands/user/describe.go @@ -5,7 +5,7 @@ import ( "io" "github.com/fastly/cli/pkg/cmd" - "github.com/fastly/cli/pkg/errors" + fsterr "github.com/fastly/cli/pkg/errors" "github.com/fastly/cli/pkg/global" "github.com/fastly/cli/pkg/lookup" "github.com/fastly/cli/pkg/manifest" @@ -20,22 +20,17 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) c.manifest = m c.CmdClause.Flag("current", "Get the logged in user").BoolVar(&c.current) c.CmdClause.Flag("id", "Alphanumeric string identifying the user").StringVar(&c.id) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput current bool id string - json bool manifest manifest.Data } @@ -43,17 +38,25 @@ type DescribeCommand struct { func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { _, s := c.Globals.Token() if s == lookup.SourceUndefined { - return errors.ErrNoToken + return fsterr.ErrNoToken + } + + if c.Globals.Verbose() && c.JSONOutput.Enabled { + return fsterr.ErrInvalidVerboseJSONCombo } if c.current { - r, err := c.Globals.APIClient.GetCurrentUser() + o, err := c.Globals.APIClient.GetCurrentUser() if err != nil { c.Globals.ErrLog.Add(err) return err } - c.print(out, r) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + c.print(out, o) return nil } @@ -62,13 +65,17 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - r, err := c.Globals.APIClient.GetUser(input) + o, err := c.Globals.APIClient.GetUser(input) if err != nil { c.Globals.ErrLog.Add(err) return err } - c.print(out, r) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + c.print(out, o) return nil } @@ -77,7 +84,7 @@ func (c *DescribeCommand) constructInput() (*fastly.GetUserInput, error) { var input fastly.GetUserInput if c.id == "" { - return nil, errors.RemediationError{ + return nil, fsterr.RemediationError{ Inner: fmt.Errorf("error parsing arguments: must provide --id flag"), Remediation: "Alternatively pass --current to validate the logged in user.", } diff --git a/pkg/commands/user/list.go b/pkg/commands/user/list.go index 63bbde61a..d2a28cabf 100644 --- a/pkg/commands/user/list.go +++ b/pkg/commands/user/list.go @@ -1,7 +1,6 @@ package user import ( - "encoding/json" "fmt" "io" @@ -26,21 +25,16 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis Dst: &c.customerID.Value, Action: c.customerID.Set, }) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json return &c } // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput customerID cmd.OptionalCustomerID - json bool manifest manifest.Data } @@ -50,7 +44,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { if s == lookup.SourceUndefined { return fsterr.ErrNoToken } - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } if err := c.customerID.Parse(); err != nil { @@ -59,7 +53,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { input := c.constructInput() - rs, err := c.Globals.APIClient.ListCustomerUsers(input) + o, err := c.Globals.APIClient.ListCustomerUsers(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Customer ID": c.customerID.Value, @@ -67,10 +61,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - c.printVerbose(out, rs) + c.printVerbose(out, o) } else { - err = c.printSummary(out, rs) + err = c.printSummary(out, o) if err != nil { return err } @@ -118,18 +116,6 @@ func (c *ListCommand) printVerbose(out io.Writer, us []*fastly.User) { // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, us []*fastly.User) error { - if c.json { - data, err := json.Marshal(us) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } t := text.NewTable(out) t.AddHeader("LOGIN", "NAME", "ROLE", "LOCKED", "ID") for _, u := range us { diff --git a/pkg/commands/vcl/custom/describe.go b/pkg/commands/vcl/custom/describe.go index b867b3663..17055d191 100644 --- a/pkg/commands/vcl/custom/describe.go +++ b/pkg/commands/vcl/custom/describe.go @@ -1,7 +1,6 @@ package custom import ( - "encoding/json" "fmt" "io" @@ -32,12 +31,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -57,8 +51,8 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput - json bool manifest manifest.Data name string serviceName cmd.OptionalServiceNameID @@ -67,7 +61,7 @@ type DescribeCommand struct { // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -90,7 +84,7 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { input := c.constructInput(serviceID, serviceVersion.Number) - v, err := c.Globals.APIClient.GetVCL(input) + o, err := c.Globals.APIClient.GetVCL(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -99,7 +93,11 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, v) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. @@ -115,19 +113,6 @@ func (c *DescribeCommand) constructInput(serviceID string, serviceVersion int) * // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, v *fastly.VCL) error { - if c.json { - data, err := json.Marshal(v) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - if !c.Globals.Verbose() { fmt.Fprintf(out, "\nService ID: %s\n", v.ServiceID) } diff --git a/pkg/commands/vcl/custom/list.go b/pkg/commands/vcl/custom/list.go index a96b914a9..1bb8a992f 100644 --- a/pkg/commands/vcl/custom/list.go +++ b/pkg/commands/vcl/custom/list.go @@ -1,7 +1,6 @@ package custom import ( - "encoding/json" "fmt" "io" @@ -32,12 +31,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -57,8 +51,8 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput - json bool manifest manifest.Data serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion @@ -66,7 +60,7 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +83,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { input := c.constructInput(serviceID, serviceVersion.Number) - vs, err := c.Globals.APIClient.ListVCLs(input) + o, err := c.Globals.APIClient.ListVCLs(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,10 +92,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - c.printVerbose(out, serviceVersion.Number, vs) + c.printVerbose(out, serviceVersion.Number, o) } else { - err = c.printSummary(out, vs) + err = c.printSummary(out, o) if err != nil { return err } @@ -143,19 +141,6 @@ func (c *ListCommand) printVerbose(out io.Writer, serviceVersion int, vs []*fast // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, vs []*fastly.VCL) error { - if c.json { - data, err := json.Marshal(vs) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("SERVICE ID", "VERSION", "NAME", "MAIN") for _, v := range vs { diff --git a/pkg/commands/vcl/snippet/describe.go b/pkg/commands/vcl/snippet/describe.go index eb66aa0c4..7b69334a7 100644 --- a/pkg/commands/vcl/snippet/describe.go +++ b/pkg/commands/vcl/snippet/describe.go @@ -1,7 +1,6 @@ package snippet import ( - "encoding/json" "fmt" "io" @@ -32,12 +31,7 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // optional c.CmdClause.Flag("dynamic", "Whether the VCL snippet is dynamic or versioned").Action(c.dynamic.Set).BoolVar(&c.dynamic.Value) - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.CmdClause.Flag("name", "The name of the VCL snippet").StringVar(&c.name) c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, @@ -59,9 +53,9 @@ func NewDescribeCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) // DescribeCommand calls the Fastly API to describe an appropriate resource. type DescribeCommand struct { cmd.Base + cmd.JSONOutput dynamic cmd.OptionalBool - json bool manifest manifest.Data name string serviceName cmd.OptionalServiceNameID @@ -71,7 +65,7 @@ type DescribeCommand struct { // Exec invokes the application logic for the command. func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -102,7 +96,8 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { }) return err } - v, err := c.Globals.APIClient.GetDynamicSnippet(input) + + o, err := c.Globals.APIClient.GetDynamicSnippet(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -110,7 +105,12 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { }) return err } - return c.printDynamic(out, v) + + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.printDynamic(out, o) } input, err := c.constructInput(serviceID, serviceVersion.Number) @@ -122,7 +122,8 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { }) return err } - v, err := c.Globals.APIClient.GetSnippet(input) + + o, err := c.Globals.APIClient.GetSnippet(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -131,7 +132,11 @@ func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { return err } - return c.print(out, v) + if ok, err := c.WriteJSON(out, o); ok { + return err + } + + return c.print(out, o) } // constructDynamicInput transforms values parsed from CLI flags into an object to be used by the API client library. @@ -165,19 +170,6 @@ func (c *DescribeCommand) constructInput(serviceID string, serviceVersion int) ( // print displays the 'dynamic' information returned from the API. func (c *DescribeCommand) printDynamic(out io.Writer, ds *fastly.DynamicSnippet) error { - if c.json { - data, err := json.Marshal(ds) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - fmt.Fprintf(out, "\nService ID: %s\n", ds.ServiceID) fmt.Fprintf(out, "ID: %s\n", ds.ID) fmt.Fprintf(out, "Content: \n%s\n", ds.Content) @@ -192,19 +184,6 @@ func (c *DescribeCommand) printDynamic(out io.Writer, ds *fastly.DynamicSnippet) // print displays the information returned from the API. func (c *DescribeCommand) print(out io.Writer, s *fastly.Snippet) error { - if c.json { - data, err := json.Marshal(s) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - if !c.Globals.Verbose() { fmt.Fprintf(out, "\nService ID: %s\n", s.ServiceID) } diff --git a/pkg/commands/vcl/snippet/list.go b/pkg/commands/vcl/snippet/list.go index 7b60a2eac..c4f57aa78 100644 --- a/pkg/commands/vcl/snippet/list.go +++ b/pkg/commands/vcl/snippet/list.go @@ -1,7 +1,6 @@ package snippet import ( - "encoding/json" "fmt" "io" @@ -32,12 +31,7 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis }) // optional - c.RegisterFlagBool(cmd.BoolFlagOpts{ - Name: cmd.FlagJSONName, - Description: cmd.FlagJSONDesc, - Dst: &c.json, - Short: 'j', - }) + c.RegisterFlagBool(c.JSONFlag()) // --json c.RegisterFlag(cmd.StringFlagOpts{ Name: cmd.FlagServiceIDName, Description: cmd.FlagServiceIDDesc, @@ -57,8 +51,8 @@ func NewListCommand(parent cmd.Registerer, g *global.Data, m manifest.Data) *Lis // ListCommand calls the Fastly API to list appropriate resources. type ListCommand struct { cmd.Base + cmd.JSONOutput - json bool manifest manifest.Data serviceName cmd.OptionalServiceNameID serviceVersion cmd.OptionalServiceVersion @@ -66,7 +60,7 @@ type ListCommand struct { // Exec invokes the application logic for the command. func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { - if c.Globals.Verbose() && c.json { + if c.Globals.Verbose() && c.JSONOutput.Enabled { return fsterr.ErrInvalidVerboseJSONCombo } @@ -89,7 +83,7 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { input := c.constructInput(serviceID, serviceVersion.Number) - vs, err := c.Globals.APIClient.ListSnippets(input) + o, err := c.Globals.APIClient.ListSnippets(input) if err != nil { c.Globals.ErrLog.AddWithContext(err, map[string]any{ "Service ID": serviceID, @@ -98,10 +92,14 @@ func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { return err } + if ok, err := c.WriteJSON(out, o); ok { + return err + } + if c.Globals.Verbose() { - c.printVerbose(out, serviceVersion.Number, vs) + c.printVerbose(out, serviceVersion.Number, o) } else { - err = c.printSummary(out, vs) + err = c.printSummary(out, o) if err != nil { return err } @@ -148,19 +146,6 @@ func (c *ListCommand) printVerbose(out io.Writer, serviceVersion int, vs []*fast // printSummary displays the information returned from the API in a summarised // format. func (c *ListCommand) printSummary(out io.Writer, ss []*fastly.Snippet) error { - if c.json { - data, err := json.Marshal(ss) - if err != nil { - return err - } - _, err = out.Write(data) - if err != nil { - c.Globals.ErrLog.Add(err) - return fmt.Errorf("error: unable to write data to stdout: %w", err) - } - return nil - } - t := text.NewTable(out) t.AddHeader("SERVICE ID", "VERSION", "NAME", "DYNAMIC", "SNIPPET ID") for _, s := range ss { From b02bd08aa14dd163c4e3d4d82550f1a3a8ce526c Mon Sep 17 00:00:00 2001 From: Integralist Date: Tue, 18 Apr 2023 13:48:54 +0100 Subject: [PATCH 2/2] tests: fix --- pkg/commands/backend/backend_test.go | 77 +++++++++++++++++++++++- pkg/commands/profile/profile_test.go | 17 +++++- pkg/commands/serviceauth/service_test.go | 46 ++++++++++++-- 3 files changed, 130 insertions(+), 10 deletions(-) diff --git a/pkg/commands/backend/backend_test.go b/pkg/commands/backend/backend_test.go index ee4bdcd96..e4286a2a9 100644 --- a/pkg/commands/backend/backend_test.go +++ b/pkg/commands/backend/backend_test.go @@ -135,7 +135,7 @@ func TestBackendList(t *testing.T) { ListVersionsFn: testutil.ListVersions, ListBackendsFn: listBackendsOK, }, - WantOutput: `[{"Address":"www.test.com","AutoLoadbalance":false,"BetweenBytesTimeout":0,"Comment":"test","ConnectTimeout":0,"CreatedAt":null,"DeletedAt":null,"ErrorThreshold":0,"FirstByteTimeout":0,"HealthCheck":"","Hostname":"","KeepAliveTime":0,"MaxConn":0,"MaxTLSVersion":"","MinTLSVersion":"","Name":"test.com","OverrideHost":"","Port":80,"RequestCondition":"","SSLCACert":"","SSLCertHostname":"","SSLCheckCert":false,"SSLCiphers":"","SSLClientCert":"","SSLClientKey":"","SSLHostname":"","SSLSNIHostname":"","ServiceID":"123","ServiceVersion":1,"Shield":"","UpdatedAt":null,"UseSSL":false,"Weight":0},{"Address":"www.example.com","AutoLoadbalance":false,"BetweenBytesTimeout":0,"Comment":"example","ConnectTimeout":0,"CreatedAt":null,"DeletedAt":null,"ErrorThreshold":0,"FirstByteTimeout":0,"HealthCheck":"","Hostname":"","KeepAliveTime":0,"MaxConn":0,"MaxTLSVersion":"","MinTLSVersion":"","Name":"example.com","OverrideHost":"","Port":443,"RequestCondition":"","SSLCACert":"","SSLCertHostname":"","SSLCheckCert":false,"SSLCiphers":"","SSLClientCert":"","SSLClientKey":"","SSLHostname":"","SSLSNIHostname":"","ServiceID":"123","ServiceVersion":1,"Shield":"","UpdatedAt":null,"UseSSL":false,"Weight":0}]`, + WantOutput: listBackendsJSONOutput, }, { Args: args("backend list --service-id 123 --version 1 --json --verbose"), @@ -379,6 +379,81 @@ func listBackendsError(i *fastly.ListBackendsInput) ([]*fastly.Backend, error) { return nil, errTest } +var listBackendsJSONOutput = strings.TrimSpace(` +[ + { + "Address": "www.test.com", + "AutoLoadbalance": false, + "BetweenBytesTimeout": 0, + "Comment": "test", + "ConnectTimeout": 0, + "CreatedAt": null, + "DeletedAt": null, + "ErrorThreshold": 0, + "FirstByteTimeout": 0, + "HealthCheck": "", + "Hostname": "", + "KeepAliveTime": 0, + "MaxConn": 0, + "MaxTLSVersion": "", + "MinTLSVersion": "", + "Name": "test.com", + "OverrideHost": "", + "Port": 80, + "RequestCondition": "", + "SSLCACert": "", + "SSLCertHostname": "", + "SSLCheckCert": false, + "SSLCiphers": "", + "SSLClientCert": "", + "SSLClientKey": "", + "SSLHostname": "", + "SSLSNIHostname": "", + "ServiceID": "123", + "ServiceVersion": 1, + "Shield": "", + "UpdatedAt": null, + "UseSSL": false, + "Weight": 0 + }, + { + "Address": "www.example.com", + "AutoLoadbalance": false, + "BetweenBytesTimeout": 0, + "Comment": "example", + "ConnectTimeout": 0, + "CreatedAt": null, + "DeletedAt": null, + "ErrorThreshold": 0, + "FirstByteTimeout": 0, + "HealthCheck": "", + "Hostname": "", + "KeepAliveTime": 0, + "MaxConn": 0, + "MaxTLSVersion": "", + "MinTLSVersion": "", + "Name": "example.com", + "OverrideHost": "", + "Port": 443, + "RequestCondition": "", + "SSLCACert": "", + "SSLCertHostname": "", + "SSLCheckCert": false, + "SSLCiphers": "", + "SSLClientCert": "", + "SSLClientKey": "", + "SSLHostname": "", + "SSLSNIHostname": "", + "ServiceID": "123", + "ServiceVersion": 1, + "Shield": "", + "UpdatedAt": null, + "UseSSL": false, + "Weight": 0 + } +] +`) + "\n" + var listBackendsShortOutput = strings.TrimSpace(` SERVICE VERSION NAME ADDRESS PORT COMMENT 123 1 test.com www.test.com 80 test diff --git a/pkg/commands/profile/profile_test.go b/pkg/commands/profile/profile_test.go index 792a72344..dcc1118a4 100644 --- a/pkg/commands/profile/profile_test.go +++ b/pkg/commands/profile/profile_test.go @@ -413,9 +413,20 @@ func TestList(t *testing.T) { }, { TestScenario: testutil.TestScenario{ - Name: "validate listing profiles with --json displays data correctly", - Args: args("profile list --json"), - WantOutput: `{"bar":{"default":false,"email":"bar@example.com","token":"456"},"foo":{"default":false,"email":"foo@example.com","token":"123"}}`, + Name: "validate listing profiles with --json displays data correctly", + Args: args("profile list --json"), + WantOutput: `{ + "bar": { + "default": false, + "email": "bar@example.com", + "token": "456" + }, + "foo": { + "default": false, + "email": "foo@example.com", + "token": "123" + } +}`, }, ConfigFile: config.File{ Profiles: config.Profiles{ diff --git a/pkg/commands/serviceauth/service_test.go b/pkg/commands/serviceauth/service_test.go index 93d8ab385..ab9d72474 100644 --- a/pkg/commands/serviceauth/service_test.go +++ b/pkg/commands/serviceauth/service_test.go @@ -71,9 +71,29 @@ func TestServiceAuthList(t *testing.T) { wantOutput: "AUTH ID USER ID SERVICE ID PERMISSION\n123 456 789 read_only\n", }, { - args: args("service-auth list --json"), - api: mock.API{ListServiceAuthorizationsFn: listServiceAuthOK}, - wantOutput: "{\"Info\":{\"links\":{},\"meta\":{}},\"Items\":[{\"CreatedAt\":null,\"DeletedAt\":null,\"ID\":\"123\",\"Permission\":\"read_only\",\"Service\":{\"ID\":\"789\"},\"UpdatedAt\":null,\"User\":{\"ID\":\"456\"}}]}", + args: args("service-auth list --json"), + api: mock.API{ListServiceAuthorizationsFn: listServiceAuthOK}, + wantOutput: `{ + "Info": { + "links": {}, + "meta": {} + }, + "Items": [ + { + "CreatedAt": null, + "DeletedAt": null, + "ID": "123", + "Permission": "read_only", + "Service": { + "ID": "789" + }, + "UpdatedAt": null, + "User": { + "ID": "456" + } + } + ] +}`, }, { args: args("service-auth list --verbose"), @@ -88,6 +108,7 @@ func TestServiceAuthList(t *testing.T) { opts := testutil.NewRunOpts(testcase.args, &stdout) opts.APIClient = mock.APIClient(testcase.api) err := app.Run(opts) + t.Log(stdout.String()) testutil.AssertErrorContains(t, err, testcase.wantError) testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) }) @@ -121,9 +142,21 @@ func TestServiceAuthDescribe(t *testing.T) { wantOutput: "Auth ID: 12345\nUser ID: 456\nService ID: 789\nPermission: read_only\n", }, { - args: args("service-auth describe --id 123 --json"), - api: mock.API{GetServiceAuthorizationFn: describeServiceAuthOK}, - wantOutput: "{\"CreatedAt\":null,\"DeletedAt\":null,\"ID\":\"12345\",\"Permission\":\"read_only\",\"Service\":{\"ID\":\"789\"},\"UpdatedAt\":null,\"User\":{\"ID\":\"456\"}}", + args: args("service-auth describe --id 123 --json"), + api: mock.API{GetServiceAuthorizationFn: describeServiceAuthOK}, + wantOutput: `{ + "CreatedAt": null, + "DeletedAt": null, + "ID": "12345", + "Permission": "read_only", + "Service": { + "ID": "789" + }, + "UpdatedAt": null, + "User": { + "ID": "456" + } +}`, }, } for testcaseIdx := range scenarios { @@ -133,6 +166,7 @@ func TestServiceAuthDescribe(t *testing.T) { opts := testutil.NewRunOpts(testcase.args, &stdout) opts.APIClient = mock.APIClient(testcase.api) err := app.Run(opts) + t.Log(stdout.String()) testutil.AssertErrorContains(t, err, testcase.wantError) testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) })