Skip to content

Commit

Permalink
feat(printer): add support for YAML output (#1308)
Browse files Browse the repository at this point in the history
  • Loading branch information
remyleone authored Aug 25, 2020
1 parent 9a8a67e commit 9a0e923
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 1 deletion.
28 changes: 27 additions & 1 deletion internal/core/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"

"github.com/scaleway/scaleway-cli/internal/human"
"gopkg.in/yaml.v2"
)

// Type defines an formatter format.
Expand All @@ -21,6 +22,9 @@ const (
// PrinterTypeJSON defines a JSON formatter.
PrinterTypeJSON = PrinterType("json")

// PrinterTypeYAML defines a YAML formatter.
PrinterTypeYAML = PrinterType("yaml")

// PrinterTypeHuman defines a human readable formatted formatter.
PrinterTypeHuman = PrinterType("human")

Expand Down Expand Up @@ -58,7 +62,8 @@ func NewPrinter(config *PrinterConfig) (*Printer, error) {
if err != nil {
return nil, err
}

case PrinterTypeYAML.String():
printer.printerType = PrinterTypeYAML
default:
return nil, fmt.Errorf("invalid output format: %s", printerName)
}
Expand Down Expand Up @@ -110,6 +115,8 @@ func (p *Printer) Print(data interface{}, opt *human.MarshalOpt) error {
err = p.printHuman(data, opt)
case PrinterTypeJSON:
err = p.printJSON(data)
case PrinterTypeYAML:
err = p.printYAML(data)
default:
err = fmt.Errorf("unknown format: %s", p.printerType)
}
Expand Down Expand Up @@ -199,3 +206,22 @@ func (p *Printer) printJSON(data interface{}) error {

return encoder.Encode(data)
}

func (p *Printer) printYAML(data interface{}) error {
_, implementMarshaler := data.(yaml.Marshaler)
err, isError := data.(error)

if isError && !implementMarshaler {
data = map[string]string{
"error": err.Error(),
}
}

writer := p.stdout
if isError {
writer = p.stderr
}
encoder := yaml.NewEncoder(writer)

return encoder.Encode(data)
}
73 changes: 73 additions & 0 deletions internal/core/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,76 @@ func Test_CorePrinter(t *testing.T) {
Check: TestCheckGolden(),
}))
}

func Test_YamlPrinter(t *testing.T) {
type Human struct {
ID string `json:"id"`
Name string `json:"name"`
}

commands := NewCommands(
&Command{
Namespace: "get",
ArgsType: reflect.TypeOf(struct{}{}),
Run: func(ctx context.Context, argsI interface{}) (interface{}, error) {
return Human{
ID: "111111111-111111111",
Name: "David Copperfield",
}, nil
},
},
&Command{
Namespace: "list",
ArgsType: reflect.TypeOf(struct{}{}),
Run: func(ctx context.Context, argsI interface{}) (interface{}, error) {
return []*Human{
{ID: "111111111-111111111", Name: "David Copperfield"},
{ID: "222222222-222222222", Name: "Xavier Niel"},
}, nil
},
},
&Command{
Namespace: "NilSlice",
ArgsType: reflect.TypeOf(struct{}{}),
Run: func(ctx context.Context, argsI interface{}) (interface{}, error) {
return []Human{}, nil
},
},
)

t.Run("human-simple-without-option", Test(&TestConfig{
Commands: commands,
Cmd: "scw get -o yaml",
Check: TestCheckGolden(),
}))

t.Run("human-simple-with-options", Test(&TestConfig{
Commands: commands,
Cmd: "scw get -o yaml=ID,Name",
Check: TestCheckGolden(),
}))

t.Run("human-list-without-option", Test(&TestConfig{
Commands: commands,
Cmd: "scw list -o yaml",
Check: TestCheckGolden(),
}))

t.Run("human-list-with-options", Test(&TestConfig{
Commands: commands,
Cmd: "scw list -o yaml=Name,ID",
Check: TestCheckGolden(),
}))

t.Run("human-list-with-options-unknown-column", Test(&TestConfig{
Commands: commands,
Cmd: "scw -D list -o yaml=Name,ID,Unknown",
Check: TestCheckGolden(),
}))

t.Run("nil-slice", Test(&TestConfig{
Commands: commands,
Cmd: "scw NilSlice -o yaml",
Check: TestCheckGolden(),
}))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
🟩🟩🟩 STDOUT️ 🟩🟩🟩️
- id: 111111111-111111111
name: David Copperfield
- id: 222222222-222222222
name: Xavier Niel
🟩🟩🟩 JSON STDOUT 🟩🟩🟩
[
{
"id": "111111111-111111111",
"name": "David Copperfield"
},
{
"id": "222222222-222222222",
"name": "Xavier Niel"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
🟩🟩🟩 STDOUT️ 🟩🟩🟩️
- id: 111111111-111111111
name: David Copperfield
- id: 222222222-222222222
name: Xavier Niel
🟩🟩🟩 JSON STDOUT 🟩🟩🟩
[
{
"id": "111111111-111111111",
"name": "David Copperfield"
},
{
"id": "222222222-222222222",
"name": "Xavier Niel"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
🟩🟩🟩 STDOUT️ 🟩🟩🟩️
- id: 111111111-111111111
name: David Copperfield
- id: 222222222-222222222
name: Xavier Niel
🟩🟩🟩 JSON STDOUT 🟩🟩🟩
[
{
"id": "111111111-111111111",
"name": "David Copperfield"
},
{
"id": "222222222-222222222",
"name": "Xavier Niel"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
🟩🟩🟩 STDOUT️ 🟩🟩🟩️
id: 111111111-111111111
name: David Copperfield
🟩🟩🟩 JSON STDOUT 🟩🟩🟩
{
"id": "111111111-111111111",
"name": "David Copperfield"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
🟩🟩🟩 STDOUT️ 🟩🟩🟩️
id: 111111111-111111111
name: David Copperfield
🟩🟩🟩 JSON STDOUT 🟩🟩🟩
{
"id": "111111111-111111111",
"name": "David Copperfield"
}
5 changes: 5 additions & 0 deletions internal/core/testdata/test-yaml-printer-nil-slice.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
🟩🟩🟩 STDOUT️ 🟩🟩🟩️
[]
🟩🟩🟩 JSON STDOUT 🟩🟩🟩
[]

0 comments on commit 9a0e923

Please sign in to comment.