diff --git a/CHANGELOG.md b/CHANGELOG.md index b6a03be609..674e57a761 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -172,7 +172,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### CLI Breaking Changes -* [\#9695](https://github.com/cosmos/cosmos-sdk/pull/9695) ` keys migrate` CLI command now takes no arguments +* (cli) [\#11818](https://github.com/cosmos/cosmos-sdk/pull/11818) CLI transactions preview now respect the chosen `--output` flag format (json or text). +* [\#9695](https://github.com/cosmos/cosmos-sdk/pull/9695) ` keys migrate` CLI command now takes no arguments. * [\#9246](https://github.com/cosmos/cosmos-sdk/pull/9246) Removed the CLI flag `--setup-config-only` from the `testnet` command and added the subcommand `init-files`. * [\#9780](https://github.com/cosmos/cosmos-sdk/pull/9780) Use sigs.k8s.io for yaml, which might lead to minor YAML output changes * [\#10625](https://github.com/cosmos/cosmos-sdk/pull/10625) Rename `--fee-account` CLI flag to `--fee-granter` diff --git a/client/context.go b/client/context.go index 1d5925b933..be5c84af60 100644 --- a/client/context.go +++ b/client/context.go @@ -2,6 +2,7 @@ package client import ( "bufio" + "encoding/json" "fmt" "io" "os" @@ -305,6 +306,12 @@ func (ctx Context) PrintObjectLegacy(toPrint interface{}) error { return ctx.printOutput(out) } +// PrintRaw is a variant of PrintProto that doesn't require a proto.Message type +// and uses a raw JSON message. No marshaling is performed. +func (ctx Context) PrintRaw(toPrint json.RawMessage) error { + return ctx.printOutput(toPrint) +} + func (ctx Context) printOutput(out []byte) error { var err error if ctx.OutputFormat == "text" { diff --git a/client/context_test.go b/client/context_test.go index 0efae1e634..82feeebe4d 100644 --- a/client/context_test.go +++ b/client/context_test.go @@ -3,6 +3,7 @@ package client_test import ( "bytes" "context" + "encoding/json" "os" "strings" "testing" @@ -25,7 +26,7 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -func TestContext_PrintObject(t *testing.T) { +func TestContext_PrintProto(t *testing.T) { ctx := client.Context{} animal := &testdata.Dog{ @@ -39,9 +40,7 @@ func TestContext_PrintObject(t *testing.T) { X: 10, } - // // proto - // registry := testdata.NewTestInterfaceRegistry() ctx = ctx.WithCodec(codec.NewProtoCodec(registry)) @@ -68,15 +67,28 @@ func TestContext_PrintObject(t *testing.T) { size: big x: "10" `, buf.String()) +} + +func TestContext_PrintObjectLegacy(t *testing.T) { + ctx := client.Context{} + + animal := &testdata.Dog{ + Size_: "big", + Name: "Spot", + } + any, err := types.NewAnyWithValue(animal) + require.NoError(t, err) + hasAnimal := &testdata.HasAnimal{ + Animal: any, + X: 10, + } - // // amino - // amino := testdata.NewTestAmino() ctx = ctx.WithLegacyAmino(&codec.LegacyAmino{Amino: amino}) // json - buf = &bytes.Buffer{} + buf := &bytes.Buffer{} ctx = ctx.WithOutput(buf) ctx.OutputFormat = "json" err = ctx.PrintObjectLegacy(hasAnimal) @@ -103,6 +115,35 @@ value: `, buf.String()) } +func TestContext_PrintRaw(t *testing.T) { + ctx := client.Context{} + hasAnimal := json.RawMessage(`{"animal":{"@type":"/testdata.Dog","size":"big","name":"Spot"},"x":"10"}`) + + // json + buf := &bytes.Buffer{} + ctx = ctx.WithOutput(buf) + ctx.OutputFormat = "json" + err := ctx.PrintRaw(hasAnimal) + require.NoError(t, err) + require.Equal(t, + `{"animal":{"@type":"/testdata.Dog","size":"big","name":"Spot"},"x":"10"} +`, buf.String()) + + // yaml + buf = &bytes.Buffer{} + ctx = ctx.WithOutput(buf) + ctx.OutputFormat = "text" + err = ctx.PrintRaw(hasAnimal) + require.NoError(t, err) + require.Equal(t, + `animal: + '@type': /testdata.Dog + name: Spot + size: big +x: "10" +`, buf.String()) +} + func TestCLIQueryConn(t *testing.T) { cfg := network.DefaultConfig() cfg.NumValidators = 1 diff --git a/client/tx/tx.go b/client/tx/tx.go index d9a82c49fc..4605d4991c 100644 --- a/client/tx/tx.go +++ b/client/tx/tx.go @@ -3,6 +3,7 @@ package tx import ( "bufio" "context" + "encoding/json" "errors" "fmt" "os" @@ -87,12 +88,14 @@ func BroadcastTx(clientCtx client.Context, txf Factory, msgs ...sdk.Msg) error { } if !clientCtx.SkipConfirm { - out, err := clientCtx.TxConfig.TxJSONEncoder()(tx.GetTx()) + txBytes, err := clientCtx.TxConfig.TxJSONEncoder()(tx.GetTx()) if err != nil { return err } - _, _ = fmt.Fprintf(os.Stderr, "%s\n\n", out) + if err := clientCtx.PrintRaw(json.RawMessage(txBytes)); err != nil { + _, _ = fmt.Fprintf(os.Stderr, "%s\n", txBytes) + } buf := bufio.NewReader(os.Stdin) ok, err := input.GetConfirmation("confirm transaction before signing and broadcasting", buf, os.Stderr)