Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

show formatted json for machine readable output #2267

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions pkg/machineoutput/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type GenericSuccess struct {

// OutputSuccess outputs a "successful" machine-readable output format in json
func OutputSuccess(machineOutput interface{}) {
printableOutput, err := json.Marshal(machineOutput)
printableOutput, err := MarshalJSONIndented(machineOutput)

// If we error out... there's no way to output it (since we disable logging when using -o json)
if err != nil {
Expand All @@ -44,7 +44,7 @@ func OutputSuccess(machineOutput interface{}) {

// OutputError outputs a "successful" machine-readable output format in json
func OutputError(machineOutput interface{}) {
printableOutput, err := json.Marshal(machineOutput)
printableOutput, err := MarshalJSONIndented(machineOutput)

// If we error out... there's no way to output it (since we disable logging when using -o json)
if err != nil {
Expand All @@ -53,3 +53,8 @@ func OutputError(machineOutput interface{}) {
fmt.Fprintf(log.GetStderr(), "%s\n", string(printableOutput))
}
}

// MarshalJSONIndented returns indented json representation of obj
func MarshalJSONIndented(obj interface{}) ([]byte, error) {
return json.MarshalIndent(obj, "", " ")
}
4 changes: 2 additions & 2 deletions pkg/odo/cli/application/describe.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package application

import (
"encoding/json"
"fmt"

"github.com/openshift/odo/pkg/application"
"github.com/openshift/odo/pkg/component"
"github.com/openshift/odo/pkg/log"
"github.com/openshift/odo/pkg/machineoutput"
"github.com/openshift/odo/pkg/odo/cli/project"
"github.com/openshift/odo/pkg/odo/genericclioptions"
"github.com/openshift/odo/pkg/odo/util"
Expand Down Expand Up @@ -65,7 +65,7 @@ func (o *DescribeOptions) Validate() (err error) {
func (o *DescribeOptions) Run() (err error) {
if log.IsJSON() {
appDef := application.GetMachineReadableFormat(o.Client, o.appName, o.Project)
out, err := json.Marshal(appDef)
out, err := machineoutput.MarshalJSONIndented(appDef)
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/odo/cli/application/list.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package application

import (
"encoding/json"
"fmt"
"os"
"text/tabwriter"

"github.com/openshift/odo/pkg/application"
"github.com/openshift/odo/pkg/log"
"github.com/openshift/odo/pkg/machineoutput"
"github.com/openshift/odo/pkg/odo/cli/project"
"github.com/openshift/odo/pkg/odo/genericclioptions"
"github.com/openshift/odo/pkg/odo/util"
Expand Down Expand Up @@ -68,7 +68,7 @@ func (o *ListOptions) Run() (err error) {
}

appListDef := application.GetMachineReadableFormatForList(appList)
out, err := json.Marshal(appListDef)
out, err := machineoutput.MarshalJSONIndented(appListDef)
if err != nil {
return err
}
Expand All @@ -91,7 +91,7 @@ func (o *ListOptions) Run() (err error) {
}
} else {
if log.IsJSON() {
out, err := json.Marshal(application.GetMachineReadableFormatForList([]application.App{}))
out, err := machineoutput.MarshalJSONIndented(application.GetMachineReadableFormatForList([]application.App{}))
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/odo/cli/component/describe.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package component

import (
"encoding/json"
"fmt"

"github.com/openshift/odo/pkg/config"
"github.com/openshift/odo/pkg/log"
"github.com/openshift/odo/pkg/machineoutput"
"github.com/openshift/odo/pkg/odo/genericclioptions"

"github.com/openshift/odo/pkg/component"
Expand Down Expand Up @@ -70,7 +70,7 @@ func (do *DescribeOptions) Run() (err error) {
}
if log.IsJSON() {
componentDesc.Spec.Ports = do.localConfigInfo.GetPorts()
out, err := json.Marshal(componentDesc)
out, err := machineoutput.MarshalJSONIndented(componentDesc)
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/odo/cli/component/list.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package component

import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"text/tabwriter"

"github.com/golang/glog"
"github.com/openshift/odo/pkg/application"
"github.com/openshift/odo/pkg/machineoutput"
"github.com/pkg/errors"
"github.com/spf13/cobra"

Expand Down Expand Up @@ -67,7 +67,7 @@ func (lo *ListOptions) Run() (err error) {
return err
}
if log.IsJSON() {
out, err := json.Marshal(components)
out, err := machineoutput.MarshalJSONIndented(components)
if err != nil {
return err
}
Expand Down Expand Up @@ -123,7 +123,7 @@ func (lo *ListOptions) Run() (err error) {

if log.IsJSON() {

out, err := json.Marshal(components)
out, err := machineoutput.MarshalJSONIndented(components)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/odo/cli/project/list.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package project

import (
"encoding/json"
"fmt"
"os"
"text/tabwriter"

"github.com/openshift/odo/pkg/log"
"github.com/openshift/odo/pkg/machineoutput"
"github.com/openshift/odo/pkg/odo/genericclioptions"
"github.com/openshift/odo/pkg/project"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -53,7 +53,7 @@ func (plo *ProjectListOptions) Run() (err error) {
return err
}
if log.IsJSON() {
out, err := json.Marshal(projects)
out, err := machineoutput.MarshalJSONIndented(projects)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/odo/cli/storage/create.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package storage

import (
"encoding/json"
"fmt"

"github.com/openshift/odo/pkg/config"
"github.com/openshift/odo/pkg/log"
"github.com/openshift/odo/pkg/machineoutput"
"github.com/openshift/odo/pkg/odo/genericclioptions"
"github.com/openshift/odo/pkg/odo/util/completion"
"github.com/openshift/odo/pkg/storage"
Expand Down Expand Up @@ -70,7 +70,7 @@ func (o *StorageCreateOptions) Run() (err error) {
storageResultMachineReadable := storage.GetMachineReadableFormat(storageResult.Name, storageResult.Size, storageResult.Path)

if log.IsJSON() {
out, err := json.Marshal(storageResultMachineReadable)
out, err := machineoutput.MarshalJSONIndented(storageResultMachineReadable)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/odo/cli/storage/list.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package storage

import (
"encoding/json"
"fmt"
"os"

"github.com/openshift/odo/pkg/config"
"github.com/openshift/odo/pkg/machineoutput"
"github.com/openshift/odo/pkg/odo/util/completion"
"github.com/openshift/odo/pkg/storage"

Expand Down Expand Up @@ -70,7 +70,7 @@ func (o *StorageListOptions) Run() (err error) {
storageListResultMachineReadable := storage.GetMachineReadableFormatForList(storageListMachineReadable)

if log.IsJSON() {
out, err := json.Marshal(storageListResultMachineReadable)
out, err := machineoutput.MarshalJSONIndented(storageListResultMachineReadable)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/odo/cli/url/list.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package url

import (
"encoding/json"
"fmt"
"os"
"text/tabwriter"

"github.com/openshift/odo/pkg/config"
"github.com/openshift/odo/pkg/log"
"github.com/openshift/odo/pkg/machineoutput"
"github.com/openshift/odo/pkg/odo/genericclioptions"
"github.com/openshift/odo/pkg/odo/util"
"github.com/openshift/odo/pkg/odo/util/completion"
Expand Down Expand Up @@ -63,7 +63,7 @@ func (o *URLListOptions) Run() (err error) {
}

if log.IsJSON() {
out, err := json.Marshal(urls)
out, err := machineoutput.MarshalJSONIndented(urls)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package util

import (
"bufio"
"encoding/json"
"fmt"
"io"
"math/rand"
Expand All @@ -21,6 +20,7 @@ import (

"github.com/gobwas/glob"
"github.com/golang/glog"
"github.com/openshift/odo/pkg/machineoutput"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
Expand Down Expand Up @@ -590,7 +590,7 @@ func MachineOutput(outputFlag string, resource interface{}) (string, error) {
switch outputFlag {
case "json":
// If `-o json` is provided
out, err = json.Marshal(resource)
out, err = machineoutput.MarshalJSONIndented(resource)
}

return string(out), err
Expand Down
16 changes: 16 additions & 0 deletions tests/helper/helper_generic.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package helper

import (
"encoding/json"
"fmt"
"math/rand"
"strings"
Expand Down Expand Up @@ -63,3 +64,18 @@ func DontMatchAllInOutput(output string, tonotmatch []string) {
Expect(output).ToNot(ContainSubstring(i))
}
}

// Unindented returns the unindented version of the jsonStr passed to it
func Unindented(jsonStr string) (string, error) {
var tmpMap map[string]interface{}
err := json.Unmarshal([]byte(jsonStr), &tmpMap)
if err != nil {
return "", err
}

obj, err := json.Marshal(tmpMap)
if err != nil {
return "", err
}
return string(obj), err
}
22 changes: 17 additions & 5 deletions tests/integration/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,12 @@ func componentTests(args ...string) {
} else {
contextPath = strings.TrimSpace(context)
}
desired := fmt.Sprintf(`{"kind":"Component","apiVersion":"odo.openshift.io/v1alpha1","metadata":{"name":"nodejs","namespace":"%s","creationTimestamp":null},"spec":{"app":"app","type":"nodejs","source":"./","ports":["8080/TCP"]},"status":{"context":"%s","state":"Not Pushed"}}`, project, contextPath)
actual := helper.CmdShouldPass("odo", append(args, "list", "-o", "json", "--path", filepath.Dir(context))...)
// this orders the json
desired, err := helper.Unindented(fmt.Sprintf(`{"kind":"Component","apiVersion":"odo.openshift.io/v1alpha1","metadata":{"name":"nodejs","namespace":"%s","creationTimestamp":null},"spec":{"app":"app","type":"nodejs","source":"./","ports":["8080/TCP"]},"status":{"context":"%s","state":"Not Pushed"}}`, project, contextPath))
Expect(err).Should(BeNil())

actual, err := helper.Unindented(helper.CmdShouldPass("odo", append(args, "list", "-o", "json", "--path", filepath.Dir(context))...))
Expect(err).Should(BeNil())
// since the tests are run parallel, there might be many odo component directories in the root folder
// so we only check for the presence of the current one
Expect(actual).Should(ContainSubstring(desired))
Expand Down Expand Up @@ -136,12 +140,20 @@ func componentTests(args ...string) {
contextPath2 = strings.TrimSpace(context2)
}

actual := helper.CmdShouldPass("odo", append(args, "list", "-o", "json", "--path", filepath.Dir(context))...)
actual, err := helper.Unindented(helper.CmdShouldPass("odo", append(args, "list", "-o", "json", "--path", filepath.Dir(context))...))
Expect(err).Should(BeNil())
helper.Chdir(context)
helper.DeleteDir(context2)
helper.DeleteProject(project2)
Expect(actual).Should(ContainSubstring(fmt.Sprintf(`{"kind":"Component","apiVersion":"odo.openshift.io/v1alpha1","metadata":{"name":"nodejs","namespace":"%s","creationTimestamp":null},"spec":{"app":"app","type":"nodejs","source":"./","ports":["8080/TCP"]},"status":{"context":"%s","state":"Pushed"}}`, project, contextPath)))
Expect(actual).Should(ContainSubstring(fmt.Sprintf(`{"kind":"Component","apiVersion":"odo.openshift.io/v1alpha1","metadata":{"name":"python","namespace":"%s","creationTimestamp":null},"spec":{"app":"app","type":"python","source":"./","ports":["8080/TCP"]},"status":{"context":"%s","state":"Pushed"}}`, project2, contextPath2)))
// this orders the json
expected, err := helper.Unindented(fmt.Sprintf(`{"kind":"Component","apiVersion":"odo.openshift.io/v1alpha1","metadata":{"name":"nodejs","namespace":"%s","creationTimestamp":null},"spec":{"app":"app","type":"nodejs","source":"./","ports":["8080/TCP"]},"status":{"context":"%s","state":"Pushed"}}`, project, contextPath))
Expect(err).Should(BeNil())
Expect(actual).Should(ContainSubstring(expected))
// this orders the json
expected, err = helper.Unindented(fmt.Sprintf(`{"kind":"Component","apiVersion":"odo.openshift.io/v1alpha1","metadata":{"name":"python","namespace":"%s","creationTimestamp":null},"spec":{"app":"app","type":"python","source":"./","ports":["8080/TCP"]},"status":{"context":"%s","state":"Pushed"}}`, project2, contextPath2))
Expect(err).Should(BeNil())
Expect(actual).Should(ContainSubstring(expected))

})

It("should create the component from the branch ref when provided", func() {
Expand Down
9 changes: 6 additions & 3 deletions tests/integration/project/cmd_project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,16 @@ var _ = Describe("odo project command tests", func() {
})

Context("when running project command app parameter in directory that doesn't contain .odo config directory", func() {
It("should successfully execute list along with machine readable output", func() {
FIt("should successfully execute list along with machine readable output", func() {
listOutput := helper.CmdShouldPass("odo", "project", "list")
Expect(listOutput).To(ContainSubstring(project))

// project deletion doesn't happen immediately, so we test subset of the string
listOutputJson := helper.CmdShouldPass("odo", "project", "list", "-o", "json")
Expect(listOutputJson).To(ContainSubstring(`{"kind":"Project","apiVersion":"odo.openshift.io/v1alpha1","metadata":{"name":"` + project + `","namespace":"` + project + `","creationTimestamp":null},"spec":{},"status":{"active":true}}`))
listOutputJSON, err := helper.Unindented(helper.CmdShouldPass("odo", "project", "list", "-o", "json"))
Expect(err).Should(BeNil())
expected, err := helper.Unindented(`{"kind":"Project","apiVersion":"odo.openshift.io/v1alpha1","metadata":{"name":"` + project + `","namespace":"` + project + `","creationTimestamp":null},"spec":{},"status":{"active":true}}`)
Expect(err).Should(BeNil())
Expect(listOutputJSON).To(ContainSubstring(expected))
})
})
})