Skip to content

Commit

Permalink
feat(version): Add JSON/YAML output formats for version command (#709)
Browse files Browse the repository at this point in the history
* feat(version): Add JSON/YAML output format for version command

 Fixes #513

* Loop for supported apis in template
  • Loading branch information
navidshaikh authored Mar 9, 2020
1 parent 158c8f8 commit 14a5e83
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 38 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
|===
| | Description | PR

| 🎁
| Add JSON/YAML output format for version command
| https://github.com/knative/client/pull/709[#709]

| 🐣
| Replaced `kn source cron` with `kn source ping`. `--schedule` is not mandatory anymore and defaults to "* * * * *" (every minute)
| https://github.com/knative/client/issues/564[#564]
Expand Down
3 changes: 2 additions & 1 deletion docs/cmd/kn_version.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ kn version [flags]
### Options

```
-h, --help help for version
-h, --help help for version
-o, --output string Output format. One of: json|yaml.
```

### Options inherited from parent commands
Expand Down
48 changes: 45 additions & 3 deletions pkg/kn/commands/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
package version

import (
"encoding/json"
"fmt"

"knative.dev/client/pkg/kn/commands"

"github.com/spf13/cobra"
"sigs.k8s.io/yaml"

"knative.dev/client/pkg/kn/commands"
)

var Version string
Expand All @@ -38,12 +40,22 @@ var apiVersions = map[string][]string{
},
}

type knVersion struct {
Version string
BuildDate string
GitRevision string
SupportedAPIs map[string][]string
}

// NewVersionCommand implements 'kn version' command
func NewVersionCommand(p *commands.KnParams) *cobra.Command {
versionCmd := &cobra.Command{
Use: "version",
Short: "Prints the client version",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed("output") {
return printVersionMachineReadable(cmd)
}
out := cmd.OutOrStdout()
fmt.Fprintf(out, "Version: %s\n", Version)
fmt.Fprintf(out, "Build Date: %s\n", BuildDate)
Expand All @@ -57,7 +69,37 @@ func NewVersionCommand(p *commands.KnParams) *cobra.Command {
for _, api := range apiVersions["eventing"] {
fmt.Fprintf(out, " - %s\n", api)
}
return nil
},
}
versionCmd.Flags().StringP(
"output",
"o",
"",
"Output format. One of: json|yaml.",
)
return versionCmd
}

func printVersionMachineReadable(cmd *cobra.Command) error {
out := cmd.OutOrStdout()
v := knVersion{Version, BuildDate, GitRevision, apiVersions}
format := cmd.Flag("output").Value.String()
switch format {
case "JSON", "json":
b, err := json.MarshalIndent(v, "", "\t")
if err != nil {
return err
}
fmt.Fprint(out, string(b))
case "YAML", "yaml":
b, err := yaml.Marshal(v)
if err != nil {
return err
}
fmt.Fprint(out, string(b))
default:
return fmt.Errorf("Invalid value for output flag, choose one among 'json' or 'yaml'.")
}
return nil
}
88 changes: 54 additions & 34 deletions pkg/kn/commands/version/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,25 @@ package version

import (
"bytes"
"encoding/json"
"testing"
"text/template"

"knative.dev/client/pkg/kn/commands"

"github.com/spf13/cobra"
"gotest.tools/assert"
)
"sigs.k8s.io/yaml"

type versionOutput struct {
Version string
BuildDate string
GitRevision string
}
"knative.dev/client/pkg/kn/commands"
)

var versionOutputTemplate = `Version: {{.Version}}
Build Date: {{.BuildDate}}
Git Revision: {{.GitRevision}}
Supported APIs:
* Serving
- serving.knative.dev/v1 (knative-serving v0.13.0)
* Eventing
- sources.eventing.knative.dev/v1alpha1 (knative-eventing v0.13.1)
- sources.eventing.knative.dev/v1alpha2 (knative-eventing v0.13.1)
- eventing.knative.dev/v1alpha1 (knative-eventing v0.13.1)
* Serving{{range $apis := .SupportedAPIs.serving }}
- {{$apis}}{{end}}
* Eventing{{range $apis := .SupportedAPIs.eventing }}
- {{$apis}}{{end}}
`

const (
Expand All @@ -51,53 +45,79 @@ const (

func TestVersion(t *testing.T) {
var (
versionCmd *cobra.Command
knParams *commands.KnParams
expectedVersionOutput string
output *bytes.Buffer
versionCmd *cobra.Command
knParams *commands.KnParams
expectedOutput string
knVersionObj knVersion
output *bytes.Buffer
)

setup := func() {
Version = fakeVersion
BuildDate = fakeBuildDate
GitRevision = fakeGitRevision

expectedVersionOutput = genVersionOuput(t, versionOutputTemplate,
versionOutput{
fakeVersion,
fakeBuildDate,
fakeGitRevision})

knVersionObj = knVersion{fakeVersion, fakeBuildDate, fakeGitRevision, apiVersions}
expectedOutput = genVersionOuput(t, knVersionObj)
knParams = &commands.KnParams{}
versionCmd = NewVersionCommand(knParams)
output = new(bytes.Buffer)
versionCmd.SetOutput(output)
}

t.Run("creates a VersionCommand", func(t *testing.T) {
runVersionCmd := func(args []string) error {
setup()
versionCmd.SetArgs(args)
return versionCmd.Execute()
}

t.Run("creates a VersionCommand", func(t *testing.T) {
setup()
assert.Equal(t, versionCmd.Use, "version")
assert.Equal(t, versionCmd.Short, "Prints the client version")
assert.Assert(t, versionCmd.Run != nil)
assert.Assert(t, versionCmd.RunE != nil)
})

t.Run("prints version, build date, git revision, supported APIs", func(t *testing.T) {
setup()
err := runVersionCmd([]string{})
assert.NilError(t, err)
assert.Equal(t, output.String(), expectedOutput)
})

versionCmd.Run(versionCmd, []string{})
assert.Equal(t, output.String(), expectedVersionOutput)
t.Run("print version command with machine readable output", func(t *testing.T) {
t.Run("json", func(t *testing.T) {
err := runVersionCmd([]string{"-oJSON"})
assert.NilError(t, err)
in := knVersion{}
err = json.Unmarshal(output.Bytes(), &in)
assert.NilError(t, err)
assert.DeepEqual(t, in, knVersionObj)
})

t.Run("yaml", func(t *testing.T) {
err := runVersionCmd([]string{"-oyaml"})
assert.NilError(t, err)
jsonData, err := yaml.YAMLToJSON(output.Bytes())
assert.NilError(t, err)
in := knVersion{}
err = json.Unmarshal(jsonData, &in)
assert.NilError(t, err)
assert.DeepEqual(t, in, knVersionObj)
})

t.Run("invalid format", func(t *testing.T) {
err := runVersionCmd([]string{"-o", "jsonpath"})
assert.Assert(t, err != nil)
assert.ErrorContains(t, err, "Invalid", "output", "flag", "choose", "among")
})
})

}

func genVersionOuput(t *testing.T, templ string, vOutput versionOutput) string {
func genVersionOuput(t *testing.T, obj knVersion) string {
tmpl, err := template.New("versionOutput").Parse(versionOutputTemplate)
assert.NilError(t, err)

buf := bytes.Buffer{}
err = tmpl.Execute(&buf, vOutput)
err = tmpl.Execute(&buf, obj)
assert.NilError(t, err)

return buf.String()
}

0 comments on commit 14a5e83

Please sign in to comment.