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

feat(autocli): add text|json output for flag output #15252

Merged
merged 9 commits into from
Mar 3, 2023
1 change: 1 addition & 0 deletions client/v2/autocli/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func (appOptions AppOptions) EnhanceRootCommand(rootCmd *cobra.Command) error {
return client.GetClientQueryContext(cmd)
},
AddQueryConnFlags: flags.AddQueryFlagsToCmd,
AddTxConnFlags: flags.AddTxFlagsToCmd,
}

return appOptions.EnhanceRootCommandWithBuilder(rootCmd, builder)
Expand Down
2 changes: 2 additions & 0 deletions client/v2/autocli/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ type Builder struct {
GetClientConn func(*cobra.Command) (grpc.ClientConnInterface, error)

AddQueryConnFlags func(*cobra.Command)

AddTxConnFlags func(*cobra.Command)
}
26 changes: 26 additions & 0 deletions client/v2/autocli/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package autocli

import (
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"fmt"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/spf13/cobra"
"google.golang.org/protobuf/reflect/protoreflect"
"sigs.k8s.io/yaml"

"cosmossdk.io/client/v2/internal/util"
)
Expand Down Expand Up @@ -62,6 +65,10 @@ func (b *Builder) buildMethodCommandCommon(descriptor protoreflect.MethodDescrip
b.AddQueryConnFlags(cmd)
}

if b.AddTxConnFlags != nil {
b.AddTxConnFlags(cmd)
}

return cmd, nil
}

Expand Down Expand Up @@ -108,3 +115,22 @@ func (b *Builder) enhanceCommandCommon(cmd *cobra.Command, moduleOptions map[str

return nil
}

// outOrStdoutFormat formats the output based on the output flag and writes it to the command's output stream.
func (b *Builder) outOrStdoutFormat(cmd *cobra.Command, out []byte) error {
var err error
outputType := cmd.Flag(flags.FlagOutput)
if outputType == nil {
return fmt.Errorf("output flag not found")

}
if outputType.Value.String() == "text" {
out, err = yaml.JSONToYAML(out)
if err != nil {
return err
}
}
_, err = fmt.Fprintln(cmd.OutOrStdout(), string(out))

return nil
}
2 changes: 2 additions & 0 deletions client/v2/autocli/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package autocli
import (
"bytes"
"cosmossdk.io/client/v2/internal/testpb"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"gotest.tools/v3/assert"
Expand Down Expand Up @@ -43,6 +44,7 @@ func testExecCommon(t *testing.T, buildModuleCommand func(string, *Builder) (*co
GetClientConn: func(*cobra.Command) (grpc.ClientConnInterface, error) {
return conn, nil
},
AddQueryConnFlags: flags.AddQueryFlagsToCmd,
}

cmd, err := buildModuleCommand("test", b)
Expand Down
2 changes: 1 addition & 1 deletion client/v2/autocli/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor
return err
}

_, err = fmt.Fprintln(cmd.OutOrStdout(), string(bz))
err = b.outOrStdoutFormat(cmd, bz)
return err
})
}
17 changes: 17 additions & 0 deletions client/v2/autocli/msg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ func TestMsgOptions(t *testing.T) {
"send", "5", "6", `{"denom":"foo","amount":"1"}`,
"--uint32", "7",
"--u64", "8",
"--output", "json",
)
response := conn.out.String()
var output testpb.MsgRequest
Expand All @@ -114,6 +115,21 @@ func TestMsgOptions(t *testing.T) {
assert.Equal(t, output.GetPositional2(), "6")
}

func TestMsgOutputFormat(t *testing.T) {
conn := testExecCommon(t, buildModuleMsgCommand,
"send", "5", "6", `{"denom":"foo","amount":"1"}`,
"--output", "json",
)
assert.Assert(t, strings.Contains(conn.out.String(), "{"))
conn = testExecCommon(t, buildModuleMsgCommand,
"send", "5", "6", `{"denom":"foo","amount":"1"}`,
"--output", "text",
)

assert.Assert(t, strings.Contains(conn.out.String(), "positional1: 5"))

}

func TestMsgOptionsError(t *testing.T) {
conn := testExecCommon(t, buildModuleMsgCommand,
"send", "5",
Expand Down Expand Up @@ -151,6 +167,7 @@ func TestEverythingMsg(t *testing.T) {
"abc",
`{"denom":"foo","amount":"1234"}`,
`{"denom":"bar","amount":"4321"}`,
"--output", "json",
"--a-bool",
"--an-enum", "two",
"--a-message", `{"bar":"abc", "baz":-3}`,
Expand Down
6 changes: 1 addition & 5 deletions client/v2/autocli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,12 @@ func (b *Builder) BuildQueryMethodCommand(descriptor protoreflect.MethodDescript
return err
}

_, err = fmt.Fprintln(cmd.OutOrStdout(), string(bz))
err = b.outOrStdoutFormat(cmd, bz)
return err
})
if err != nil {
return nil, err
}

if b.AddQueryConnFlags != nil {
b.AddQueryConnFlags(cmd)
}

return cmd, nil
}
17 changes: 17 additions & 0 deletions client/v2/autocli/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,23 @@ func TestOptions(t *testing.T) {
assert.Equal(t, uint64(5), lastReq.U64) // no opt default value got set
}

func TestOutputFormat(t *testing.T) {
conn := testExecCommon(t, buildModuleQueryCommand,
"echo",
"1", "abc", `{"denom":"foo","amount":"1"}`,
"--output", "json",
)
assert.Assert(t, strings.Contains(conn.out.String(), "{"))
conn = testExecCommon(t, buildModuleQueryCommand,
"echo",
"1", "abc", `{"denom":"foo","amount":"1"}`,
"--output", "text",
)
fmt.Println(conn.out.String())
assert.Assert(t, strings.Contains(conn.out.String(), " positional1: 1"))

}

func TestHelp(t *testing.T) {
conn := testExecCommon(t, buildModuleQueryCommand, "-h")
golden.Assert(t, conn.out.String(), "help-toplevel.golden")
Expand Down
5 changes: 5 additions & 0 deletions client/v2/autocli/testdata/help-deprecated-msg.golden
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@ Flags:
--duration duration
--durations duration (repeated)
--enums Enum (unspecified | one | two | five | neg-three) (repeated)
--grpc-addr string the gRPC endpoint to use for this chain
--grpc-insecure allow gRPC over insecure channels, if not the server must use TLS
--height int Use a specific height to query state at (this can error if the node is pruning state)
-h, --help help for send
--hidden-bool
--i32 int32
--i64 int
--node string <host>:<port> to CometBFT RPC interface for this chain (default "tcp://localhost:26657")
-o, --output string Output format (text|json) (default "text")
--page-count-total
--page-key bytesBase64
--page-limit uint
Expand Down
5 changes: 5 additions & 0 deletions client/v2/autocli/testdata/help-deprecated.golden
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@ Flags:
--duration duration
--durations duration (repeated)
--enums Enum (unspecified | one | two | five | neg-three) (repeated)
--grpc-addr string the gRPC endpoint to use for this chain
--grpc-insecure allow gRPC over insecure channels, if not the server must use TLS
--height int Use a specific height to query state at (this can error if the node is pruning state)
-h, --help help for echo
--hidden-bool
--i32 int32
--i64 int
--node string <host>:<port> to CometBFT RPC interface for this chain (default "tcp://localhost:26657")
-o, --output string Output format (text|json) (default "text")
--page-count-total
--page-key bytesBase64
--page-limit uint
Expand Down
5 changes: 5 additions & 0 deletions client/v2/autocli/testdata/help-echo-msg.golden
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ Flags:
--duration duration
--durations duration (repeated)
--enums Enum (unspecified | one | two | five | neg-three) (repeated)
--grpc-addr string the gRPC endpoint to use for this chain
--grpc-insecure allow gRPC over insecure channels, if not the server must use TLS
--height int Use a specific height to query state at (this can error if the node is pruning state)
-h, --help help for send
--i32 int32 some random int32
--i64 int
--node string <host>:<port> to CometBFT RPC interface for this chain (default "tcp://localhost:26657")
-o, --output string Output format (text|json) (default "text")
--page-count-total
--page-key bytesBase64
--page-limit uint
Expand Down
5 changes: 5 additions & 0 deletions client/v2/autocli/testdata/help-echo.golden
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ Flags:
--duration duration
--durations duration (repeated)
--enums Enum (unspecified | one | two | five | neg-three) (repeated)
--grpc-addr string the gRPC endpoint to use for this chain
--grpc-insecure allow gRPC over insecure channels, if not the server must use TLS
--height int Use a specific height to query state at (this can error if the node is pruning state)
-h, --help help for echo
--i32 int32 some random int32
--i64 int
--node string <host>:<port> to CometBFT RPC interface for this chain (default "tcp://localhost:26657")
-o, --output string Output format (text|json) (default "text")
--page-count-total
--page-key bytesBase64
--page-limit uint
Expand Down