feat(version): Add JSON/YAML output formats for version command (#709)

* feat(version): Add JSON/YAML output format for version command

 Fixes #513

* Loop for supported apis in template
This commit is contained in:
Navid Shaikh 2020-03-09 23:41:29 +05:30 committed by GitHub
parent 158c8f8980
commit 14a5e83765
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 105 additions and 38 deletions

View File

@ -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]

View File

@ -14,6 +14,7 @@ kn version [flags]
```
-h, --help help for version
-o, --output string Output format. One of: json|yaml.
```
### Options inherited from parent commands

View File

@ -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
@ -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)
@ -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
}

View File

@ -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 (
@ -53,7 +47,8 @@ func TestVersion(t *testing.T) {
var (
versionCmd *cobra.Command
knParams *commands.KnParams
expectedVersionOutput string
expectedOutput string
knVersionObj knVersion
output *bytes.Buffer
)
@ -61,43 +56,68 @@ func TestVersion(t *testing.T) {
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)
}
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()
}