fix(client/v2): resolve keyring flags properly (#19060)
This commit is contained in:
parent
0698a9fb3f
commit
8f39bfb4e4
@ -1,6 +1,7 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"strings"
|
||||
@ -278,7 +279,7 @@ func readTxCommandFlags(clientCtx Context, flagSet *pflag.FlagSet) (Context, err
|
||||
from, _ := flagSet.GetString(flags.FlagFrom)
|
||||
fromAddr, fromName, keyType, err := GetFromFields(clientCtx, clientCtx.Keyring, from)
|
||||
if err != nil {
|
||||
return clientCtx, err
|
||||
return clientCtx, fmt.Errorf("failed to convert address field to address: %w", err)
|
||||
}
|
||||
|
||||
clientCtx = clientCtx.WithFrom(from).WithFromAddress(fromAddr).WithFromName(fromName)
|
||||
@ -358,13 +359,6 @@ func GetClientContextFromCmd(cmd *cobra.Command) Context {
|
||||
// SetCmdClientContext sets a command's Context value to the provided argument.
|
||||
// If the context has not been set, set the given context as the default.
|
||||
func SetCmdClientContext(cmd *cobra.Command, clientCtx Context) error {
|
||||
v := cmd.Context().Value(ClientContextKey)
|
||||
if v == nil {
|
||||
v = &clientCtx
|
||||
}
|
||||
|
||||
clientCtxPtr := v.(*Context)
|
||||
*clientCtxPtr = clientCtx
|
||||
|
||||
cmd.SetContext(context.WithValue(cmd.Context(), ClientContextKey, &clientCtx))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -41,7 +41,16 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
### Features
|
||||
|
||||
* [#18461](https://github.com/cosmos/cosmos-sdk/pull/18461) Support governance proposals.
|
||||
* [#19039](https://github.com/cosmos/cosmos-sdk/pull/19039) add support for pubkey in autocli.
|
||||
* [#19039](https://github.com/cosmos/cosmos-sdk/pull/19039) Add support for pubkey in autocli.
|
||||
|
||||
### Improvements
|
||||
|
||||
* [#19060](https://github.com/cosmos/cosmos-sdk/pull/19060) Use client context from root (or enhanced) command in autocli commands.
|
||||
* Note, the given command must have a `client.Context` in its context.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [#19060](https://github.com/cosmos/cosmos-sdk/pull/19060) Simplify key flag parsing logic in flag handler.
|
||||
|
||||
### API Breaking Changes
|
||||
|
||||
|
||||
@ -71,7 +71,6 @@ func (appOptions AppOptions) EnhanceRootCommand(rootCmd *cobra.Command) error {
|
||||
ValidatorAddressCodec: appOptions.ClientCtx.ValidatorAddressCodec,
|
||||
ConsensusAddressCodec: appOptions.ClientCtx.ConsensusAddressCodec,
|
||||
},
|
||||
ClientCtx: appOptions.ClientCtx,
|
||||
TxConfigOpts: appOptions.TxConfigOpts,
|
||||
GetClientConn: func(cmd *cobra.Command) (grpc.ClientConnInterface, error) {
|
||||
return client.GetClientQueryContext(cmd)
|
||||
@ -112,7 +111,7 @@ func (appOptions AppOptions) EnhanceRootCommandWithBuilder(rootCmd *cobra.Comman
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
queryCmd, err := builder.BuildQueryCommand(appOptions, customQueryCmds)
|
||||
queryCmd, err := builder.BuildQueryCommand(rootCmd.Context(), appOptions, customQueryCmds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -125,7 +124,7 @@ func (appOptions AppOptions) EnhanceRootCommandWithBuilder(rootCmd *cobra.Comman
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
subCmd, err := builder.BuildMsgCommand(appOptions, customMsgCmds)
|
||||
subCmd, err := builder.BuildMsgCommand(rootCmd.Context(), appOptions, customMsgCmds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -6,8 +6,6 @@ import (
|
||||
|
||||
"cosmossdk.io/client/v2/autocli/flag"
|
||||
authtx "cosmossdk.io/x/auth/tx"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
)
|
||||
|
||||
// Builder manages options for building CLI commands.
|
||||
@ -19,9 +17,6 @@ type Builder struct {
|
||||
// from a given context.
|
||||
GetClientConn func(*cobra.Command) (grpc.ClientConnInterface, error)
|
||||
|
||||
// ClientCtx contains the necessary information needed to execute the commands.
|
||||
ClientCtx client.Context
|
||||
|
||||
// TxConfigOptions is required to support sign mode textual
|
||||
TxConfigOpts authtx.ConfigOptions
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package autocli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@ -57,7 +56,6 @@ func (b *Builder) buildMethodCommandCommon(descriptor protoreflect.MethodDescrip
|
||||
Version: options.Version,
|
||||
}
|
||||
|
||||
cmd.SetContext(context.Background())
|
||||
binder, err := b.AddMessageFlags(cmd.Context(), cmd.Flags(), inputType, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -179,7 +177,7 @@ func (b *Builder) enhanceCommandCommon(
|
||||
// enhanceQuery enhances the provided query command with the autocli commands for a module.
|
||||
func enhanceQuery(builder *Builder, moduleName string, cmd *cobra.Command, modOpts *autocliv1.ModuleOptions) error {
|
||||
if queryCmdDesc := modOpts.Query; queryCmdDesc != nil {
|
||||
subCmd := topLevelCmd(moduleName, fmt.Sprintf("Querying commands for the %s module", moduleName))
|
||||
subCmd := topLevelCmd(cmd.Context(), moduleName, fmt.Sprintf("Querying commands for the %s module", moduleName))
|
||||
if err := builder.AddQueryServiceCommands(subCmd, queryCmdDesc); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -193,7 +191,7 @@ func enhanceQuery(builder *Builder, moduleName string, cmd *cobra.Command, modOp
|
||||
// enhanceMsg enhances the provided msg command with the autocli commands for a module.
|
||||
func enhanceMsg(builder *Builder, moduleName string, cmd *cobra.Command, modOpts *autocliv1.ModuleOptions) error {
|
||||
if txCmdDesc := modOpts.Tx; txCmdDesc != nil {
|
||||
subCmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
|
||||
subCmd := topLevelCmd(cmd.Context(), moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
|
||||
if err := builder.AddMsgServiceCommands(subCmd, txCmdDesc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -28,8 +28,9 @@ import (
|
||||
)
|
||||
|
||||
type fixture struct {
|
||||
conn *testClientConn
|
||||
b *Builder
|
||||
conn *testClientConn
|
||||
b *Builder
|
||||
clientCtx client.Context
|
||||
}
|
||||
|
||||
func initFixture(t *testing.T) *fixture {
|
||||
@ -60,8 +61,7 @@ func initFixture(t *testing.T) *fixture {
|
||||
interfaceRegistry := encodingConfig.Codec.InterfaceRegistry()
|
||||
banktypes.RegisterInterfaces(interfaceRegistry)
|
||||
|
||||
var initClientCtx client.Context
|
||||
initClientCtx = initClientCtx.
|
||||
clientCtx := client.Context{}.
|
||||
WithAddressCodec(addresscodec.NewBech32Codec("cosmos")).
|
||||
WithValidatorAddressCodec(addresscodec.NewBech32Codec("cosmosvaloper")).
|
||||
WithConsensusAddressCodec(addresscodec.NewBech32Codec("cosmosvalcons")).
|
||||
@ -79,9 +79,9 @@ func initFixture(t *testing.T) *fixture {
|
||||
Builder: flag.Builder{
|
||||
TypeResolver: protoregistry.GlobalTypes,
|
||||
FileResolver: protoregistry.GlobalFiles,
|
||||
AddressCodec: initClientCtx.AddressCodec,
|
||||
ValidatorAddressCodec: initClientCtx.ValidatorAddressCodec,
|
||||
ConsensusAddressCodec: initClientCtx.ConsensusAddressCodec,
|
||||
AddressCodec: clientCtx.AddressCodec,
|
||||
ValidatorAddressCodec: clientCtx.ValidatorAddressCodec,
|
||||
ConsensusAddressCodec: clientCtx.ConsensusAddressCodec,
|
||||
Keyring: akr,
|
||||
},
|
||||
GetClientConn: func(*cobra.Command) (grpc.ClientConnInterface, error) {
|
||||
@ -89,19 +89,19 @@ func initFixture(t *testing.T) *fixture {
|
||||
},
|
||||
AddQueryConnFlags: flags.AddQueryFlagsToCmd,
|
||||
AddTxConnFlags: flags.AddTxFlagsToCmd,
|
||||
ClientCtx: initClientCtx,
|
||||
}
|
||||
assert.NilError(t, b.ValidateAndComplete())
|
||||
|
||||
return &fixture{
|
||||
conn: conn,
|
||||
b: b,
|
||||
conn: conn,
|
||||
b: b,
|
||||
clientCtx: clientCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func runCmd(conn *testClientConn, b *Builder, command func(moduleName string, b *Builder) (*cobra.Command, error), args ...string) (*bytes.Buffer, error) {
|
||||
func runCmd(fixture *fixture, command func(moduleName string, f *fixture) (*cobra.Command, error), args ...string) (*bytes.Buffer, error) {
|
||||
out := &bytes.Buffer{}
|
||||
cmd, err := command("test", b)
|
||||
cmd, err := command("test", fixture)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
@ -215,14 +215,13 @@ func TestErrorBuildCommand(t *testing.T) {
|
||||
Tx: commandDescriptor,
|
||||
},
|
||||
},
|
||||
ClientCtx: b.ClientCtx,
|
||||
}
|
||||
|
||||
_, err := b.BuildMsgCommand(appOptions, nil)
|
||||
_, err := b.BuildMsgCommand(context.Background(), appOptions, nil)
|
||||
assert.ErrorContains(t, err, "can't find field un-existent-proto-field")
|
||||
|
||||
appOptions.ModuleOptions["test"].Tx = &autocliv1.ServiceCommandDescriptor{Service: "un-existent-service"}
|
||||
appOptions.ModuleOptions["test"].Query = &autocliv1.ServiceCommandDescriptor{Service: "un-existent-service"}
|
||||
_, err = b.BuildMsgCommand(appOptions, nil)
|
||||
_, err = b.BuildMsgCommand(context.Background(), appOptions, nil)
|
||||
assert.ErrorContains(t, err, "can't find service un-existent-service")
|
||||
}
|
||||
|
||||
@ -62,11 +62,9 @@ func (a *addressValue) Set(s string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = a.addressCodec.StringToBytes(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid account address or key name: %w", err)
|
||||
}
|
||||
|
||||
// failed all validation, just accept the input.
|
||||
// TODO(@julienrbrt), for final client/v2 2.0.0 revert the logic and
|
||||
// do a better keyring instantiation.
|
||||
a.value = s
|
||||
|
||||
return nil
|
||||
@ -129,7 +127,11 @@ func (a *consensusAddressValue) Set(s string) error {
|
||||
var pk cryptotypes.PubKey
|
||||
err2 := cdc.UnmarshalInterfaceJSON([]byte(s), &pk)
|
||||
if err2 != nil {
|
||||
return fmt.Errorf("input isn't a pubkey %w or is an invalid account address: %w", err, err2)
|
||||
// failed all validation, just accept the input.
|
||||
// TODO(@julienrbrt), for final client/v2 2.0.0 revert the logic and
|
||||
// do a better keyring instantiation.
|
||||
a.value = s
|
||||
return nil
|
||||
}
|
||||
|
||||
a.value, err = a.addressCodec.BytesToString(pk.Address())
|
||||
|
||||
@ -34,8 +34,9 @@ import (
|
||||
// BuildMsgCommand builds the msg commands for all the provided modules. If a custom command is provided for a
|
||||
// module, this is used instead of any automatically generated CLI commands. This allows apps to a fully dynamic client
|
||||
// with a more customized experience if a binary with custom commands is downloaded.
|
||||
func (b *Builder) BuildMsgCommand(appOptions AppOptions, customCmds map[string]*cobra.Command) (*cobra.Command, error) {
|
||||
msgCmd := topLevelCmd("tx", "Transaction subcommands")
|
||||
func (b *Builder) BuildMsgCommand(ctx context.Context, appOptions AppOptions, customCmds map[string]*cobra.Command) (*cobra.Command, error) {
|
||||
msgCmd := topLevelCmd(ctx, "tx", "Transaction subcommands")
|
||||
|
||||
if err := b.enhanceCommandCommon(msgCmd, msgCmdType, appOptions, customCmds); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -50,7 +51,7 @@ func (b *Builder) AddMsgServiceCommands(cmd *cobra.Command, cmdDescriptor *autoc
|
||||
for cmdName, subCmdDescriptor := range cmdDescriptor.SubCommands {
|
||||
subCmd := findSubCommand(cmd, cmdName)
|
||||
if subCmd == nil {
|
||||
subCmd = topLevelCmd(cmdName, fmt.Sprintf("Tx commands for the %s service", subCmdDescriptor.Service))
|
||||
subCmd = topLevelCmd(cmd.Context(), cmdName, fmt.Sprintf("Tx commands for the %s service", subCmdDescriptor.Service))
|
||||
}
|
||||
|
||||
// Add recursive sub-commands if there are any. This is used for nested services.
|
||||
@ -121,8 +122,6 @@ func (b *Builder) AddMsgServiceCommands(cmd *cobra.Command, cmdDescriptor *autoc
|
||||
// BuildMsgMethodCommand returns a command that outputs the JSON representation of the message.
|
||||
func (b *Builder) BuildMsgMethodCommand(descriptor protoreflect.MethodDescriptor, options *autocliv1.RpcCommandOptions) (*cobra.Command, error) {
|
||||
execFunc := func(cmd *cobra.Command, input protoreflect.Message) error {
|
||||
cmd.SetContext(context.WithValue(context.Background(), client.ClientContextKey, &b.ClientCtx))
|
||||
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package autocli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
@ -11,18 +12,22 @@ import (
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
|
||||
"cosmossdk.io/client/v2/internal/testpb"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
)
|
||||
|
||||
var buildModuleMsgCommand = func(moduleName string, b *Builder) (*cobra.Command, error) {
|
||||
cmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
|
||||
err := b.AddMsgServiceCommands(cmd, bankAutoCLI)
|
||||
var buildModuleMsgCommand = func(moduleName string, f *fixture) (*cobra.Command, error) {
|
||||
ctx := context.WithValue(context.Background(), client.ClientContextKey, &f.clientCtx)
|
||||
cmd := topLevelCmd(ctx, moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
|
||||
err := f.b.AddMsgServiceCommands(cmd, bankAutoCLI)
|
||||
return cmd, err
|
||||
}
|
||||
|
||||
func buildCustomModuleMsgCommand(cmdDescriptor *autocliv1.ServiceCommandDescriptor) func(moduleName string, b *Builder) (*cobra.Command, error) {
|
||||
return func(moduleName string, b *Builder) (*cobra.Command, error) {
|
||||
cmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
|
||||
err := b.AddMsgServiceCommands(cmd, cmdDescriptor)
|
||||
func buildCustomModuleMsgCommand(cmdDescriptor *autocliv1.ServiceCommandDescriptor) func(moduleName string, f *fixture) (*cobra.Command, error) {
|
||||
return func(moduleName string, f *fixture) (*cobra.Command, error) {
|
||||
ctx := context.WithValue(context.Background(), client.ClientContextKey, &f.clientCtx)
|
||||
cmd := topLevelCmd(ctx, moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
|
||||
err := f.b.AddMsgServiceCommands(cmd, cmdDescriptor)
|
||||
return cmd, err
|
||||
}
|
||||
}
|
||||
@ -42,7 +47,7 @@ var bankAutoCLI = &autocliv1.ServiceCommandDescriptor{
|
||||
|
||||
func TestMsg(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "send",
|
||||
out, err := runCmd(fixture, buildModuleMsgCommand, "send",
|
||||
"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk", "1foo",
|
||||
"--generate-only",
|
||||
"--output", "json",
|
||||
@ -50,7 +55,7 @@ func TestMsg(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
golden.Assert(t, out.String(), "msg-output.golden")
|
||||
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{
|
||||
out, err = runCmd(fixture, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{
|
||||
Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||
{
|
||||
@ -71,7 +76,7 @@ func TestMsg(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
golden.Assert(t, out.String(), "msg-output.golden")
|
||||
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{
|
||||
out, err = runCmd(fixture, buildCustomModuleMsgCommand(&autocliv1.ServiceCommandDescriptor{
|
||||
Service: bankv1beta1.Msg_ServiceDesc.ServiceName,
|
||||
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
|
||||
{
|
||||
@ -98,12 +103,12 @@ func TestMsg(t *testing.T) {
|
||||
func TestMsgOptionsError(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
_, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand,
|
||||
_, err := runCmd(fixture, buildModuleMsgCommand,
|
||||
"send", "5",
|
||||
)
|
||||
assert.ErrorContains(t, err, "accepts 3 arg(s)")
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand,
|
||||
_, err = runCmd(fixture, buildModuleMsgCommand,
|
||||
"send", "foo", "bar", "invalid",
|
||||
)
|
||||
assert.ErrorContains(t, err, "invalid argument")
|
||||
@ -112,11 +117,11 @@ func TestMsgOptionsError(t *testing.T) {
|
||||
func TestHelpMsg(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "-h")
|
||||
out, err := runCmd(fixture, buildModuleMsgCommand, "-h")
|
||||
assert.NilError(t, err)
|
||||
golden.Assert(t, out.String(), "help-toplevel-msg.golden")
|
||||
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildModuleMsgCommand, "send", "-h")
|
||||
out, err = runCmd(fixture, buildModuleMsgCommand, "send", "-h")
|
||||
assert.NilError(t, err)
|
||||
golden.Assert(t, out.String(), "help-echo-msg.golden")
|
||||
}
|
||||
@ -135,7 +140,7 @@ func TestBuildCustomMsgCommand(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
cmd, err := b.BuildMsgCommand(appOptions, map[string]*cobra.Command{
|
||||
cmd, err := b.BuildMsgCommand(context.Background(), appOptions, map[string]*cobra.Command{
|
||||
"test": {Use: "test", Run: func(cmd *cobra.Command, args []string) {
|
||||
customCommandCalled = true
|
||||
}},
|
||||
@ -153,7 +158,7 @@ func TestNotFoundErrorsMsg(t *testing.T) {
|
||||
b.AddTxConnFlags = nil
|
||||
|
||||
buildModuleMsgCommand := func(moduleName string, cmdDescriptor *autocliv1.ServiceCommandDescriptor) (*cobra.Command, error) {
|
||||
cmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
|
||||
cmd := topLevelCmd(context.Background(), moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
|
||||
|
||||
err := b.AddMsgServiceCommands(cmd, cmdDescriptor)
|
||||
return cmd, err
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
|
||||
"cosmossdk.io/x/tx/signing/aminojson"
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
@ -20,8 +19,8 @@ import (
|
||||
// BuildQueryCommand builds the query commands for all the provided modules. If a custom command is provided for a
|
||||
// module, this is used instead of any automatically generated CLI commands. This allows apps to a fully dynamic client
|
||||
// with a more customized experience if a binary with custom commands is downloaded.
|
||||
func (b *Builder) BuildQueryCommand(appOptions AppOptions, customCmds map[string]*cobra.Command) (*cobra.Command, error) {
|
||||
queryCmd := topLevelCmd("query", "Querying subcommands")
|
||||
func (b *Builder) BuildQueryCommand(ctx context.Context, appOptions AppOptions, customCmds map[string]*cobra.Command) (*cobra.Command, error) {
|
||||
queryCmd := topLevelCmd(ctx, "query", "Querying subcommands")
|
||||
queryCmd.Aliases = []string{"q"}
|
||||
|
||||
if err := b.enhanceCommandCommon(queryCmd, queryCmdType, appOptions, customCmds); err != nil {
|
||||
@ -38,7 +37,7 @@ func (b *Builder) AddQueryServiceCommands(cmd *cobra.Command, cmdDescriptor *aut
|
||||
for cmdName, subCmdDesc := range cmdDescriptor.SubCommands {
|
||||
subCmd := findSubCommand(cmd, cmdName)
|
||||
if subCmd == nil {
|
||||
subCmd = topLevelCmd(cmdName, fmt.Sprintf("Querying commands for the %s service", subCmdDesc.Service))
|
||||
subCmd = topLevelCmd(cmd.Context(), cmdName, fmt.Sprintf("Querying commands for the %s service", subCmdDesc.Service))
|
||||
}
|
||||
|
||||
if err := b.AddQueryServiceCommands(subCmd, subCmdDesc); err != nil {
|
||||
@ -86,7 +85,7 @@ func (b *Builder) AddQueryServiceCommands(cmd *cobra.Command, cmdDescriptor *aut
|
||||
continue
|
||||
}
|
||||
|
||||
methodCmd, err := b.BuildQueryMethodCommand(methodDescriptor, methodOpts)
|
||||
methodCmd, err := b.BuildQueryMethodCommand(cmd.Context(), methodDescriptor, methodOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -105,7 +104,7 @@ func (b *Builder) AddQueryServiceCommands(cmd *cobra.Command, cmdDescriptor *aut
|
||||
|
||||
// BuildQueryMethodCommand creates a gRPC query command for the given service method. This can be used to auto-generate
|
||||
// just a single command for a single service rpc method.
|
||||
func (b *Builder) BuildQueryMethodCommand(descriptor protoreflect.MethodDescriptor, options *autocliv1.RpcCommandOptions) (*cobra.Command, error) {
|
||||
func (b *Builder) BuildQueryMethodCommand(ctx context.Context, descriptor protoreflect.MethodDescriptor, options *autocliv1.RpcCommandOptions) (*cobra.Command, error) {
|
||||
getClientConn := b.GetClientConn
|
||||
serviceDescriptor := descriptor.Parent().(protoreflect.ServiceDescriptor)
|
||||
methodName := fmt.Sprintf("/%s/%s", serviceDescriptor.FullName(), descriptor.Name())
|
||||
@ -118,8 +117,6 @@ func (b *Builder) BuildQueryMethodCommand(descriptor protoreflect.MethodDescript
|
||||
}
|
||||
|
||||
cmd, err := b.buildMethodCommandCommon(descriptor, options, func(cmd *cobra.Command, input protoreflect.Message) error {
|
||||
cmd.SetContext(context.WithValue(context.Background(), client.ClientContextKey, &b.ClientCtx))
|
||||
|
||||
clientConn, err := getClientConn(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package autocli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
@ -18,26 +19,31 @@ import (
|
||||
queryv1beta1 "cosmossdk.io/api/cosmos/base/query/v1beta1"
|
||||
basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1"
|
||||
"cosmossdk.io/client/v2/internal/testpb"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
)
|
||||
|
||||
var buildModuleQueryCommand = func(moduleName string, b *Builder) (*cobra.Command, error) {
|
||||
cmd := topLevelCmd(moduleName, fmt.Sprintf("Querying commands for the %s module", moduleName))
|
||||
var buildModuleQueryCommand = func(moduleName string, f *fixture) (*cobra.Command, error) {
|
||||
ctx := context.WithValue(context.Background(), client.ClientContextKey, &f.clientCtx)
|
||||
cmd := topLevelCmd(ctx, moduleName, fmt.Sprintf("Querying commands for the %s module", moduleName))
|
||||
|
||||
err := b.AddQueryServiceCommands(cmd, testCmdDesc)
|
||||
err := f.b.AddQueryServiceCommands(cmd, testCmdDesc)
|
||||
return cmd, err
|
||||
}
|
||||
|
||||
var buildModuleQueryCommandOptional = func(moduleName string, b *Builder) (*cobra.Command, error) {
|
||||
cmd := topLevelCmd(moduleName, fmt.Sprintf("Querying commands for the %s module", moduleName))
|
||||
var buildModuleQueryCommandOptional = func(moduleName string, f *fixture) (*cobra.Command, error) {
|
||||
ctx := context.WithValue(context.Background(), client.ClientContextKey, &f.clientCtx)
|
||||
cmd := topLevelCmd(ctx, moduleName, fmt.Sprintf("Querying commands for the %s module", moduleName))
|
||||
|
||||
err := b.AddQueryServiceCommands(cmd, testCmdDescOptional)
|
||||
err := f.b.AddQueryServiceCommands(cmd, testCmdDescOptional)
|
||||
return cmd, err
|
||||
}
|
||||
|
||||
var buildModuleVargasOptional = func(moduleName string, b *Builder) (*cobra.Command, error) {
|
||||
cmd := topLevelCmd(moduleName, fmt.Sprintf("Querying commands for the %s module", moduleName))
|
||||
var buildModuleVargasOptional = func(moduleName string, f *fixture) (*cobra.Command, error) {
|
||||
ctx := context.WithValue(context.Background(), client.ClientContextKey, &f.clientCtx)
|
||||
cmd := topLevelCmd(ctx, moduleName, fmt.Sprintf("Querying commands for the %s module", moduleName))
|
||||
|
||||
err := b.AddQueryServiceCommands(cmd, testCmdDescInvalidOptAndVargas)
|
||||
err := f.b.AddQueryServiceCommands(cmd, testCmdDescInvalidOptAndVargas)
|
||||
return cmd, err
|
||||
}
|
||||
|
||||
@ -190,7 +196,7 @@ var testCmdDescInvalidOptAndVargas = &autocliv1.ServiceCommandDescriptor{
|
||||
func TestCoin(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
_, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err := runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
@ -200,7 +206,7 @@ func TestCoin(t *testing.T) {
|
||||
)
|
||||
assert.ErrorContains(t, err, "coin flag must be a single coin, specific multiple coins with multiple flags or spaces")
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err = runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
@ -241,7 +247,7 @@ func TestCoin(t *testing.T) {
|
||||
func TestOptional(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
_, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommandOptional,
|
||||
_, err := runCmd(fixture, buildModuleQueryCommandOptional,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
@ -251,7 +257,7 @@ func TestOptional(t *testing.T) {
|
||||
assert.Equal(t, request.Positional2, "abc")
|
||||
assert.DeepEqual(t, fixture.conn.lastRequest, fixture.conn.lastResponse.(*testpb.EchoResponse).Request, protocmp.Transform())
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommandOptional,
|
||||
_, err = runCmd(fixture, buildModuleQueryCommandOptional,
|
||||
"echo",
|
||||
"1",
|
||||
)
|
||||
@ -261,7 +267,7 @@ func TestOptional(t *testing.T) {
|
||||
assert.Equal(t, request.Positional2, "")
|
||||
assert.DeepEqual(t, fixture.conn.lastRequest, fixture.conn.lastResponse.(*testpb.EchoResponse).Request, protocmp.Transform())
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommandOptional,
|
||||
_, err = runCmd(fixture, buildModuleQueryCommandOptional,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
@ -269,7 +275,7 @@ func TestOptional(t *testing.T) {
|
||||
)
|
||||
assert.ErrorContains(t, err, "accepts between 1 and 2 arg(s), received 3")
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleVargasOptional,
|
||||
_, err = runCmd(fixture, buildModuleVargasOptional,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
@ -281,7 +287,7 @@ func TestOptional(t *testing.T) {
|
||||
func TestMap(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
_, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err := runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
@ -296,7 +302,7 @@ func TestMap(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, fixture.conn.lastRequest, fixture.conn.lastResponse.(*testpb.EchoResponse).Request, protocmp.Transform())
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err = runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
@ -308,7 +314,7 @@ func TestMap(t *testing.T) {
|
||||
)
|
||||
assert.ErrorContains(t, err, "invalid argument \"baz,100000foo\" for \"--map-string-coin\" flag: invalid format, expected key=value")
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err = runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
@ -320,7 +326,7 @@ func TestMap(t *testing.T) {
|
||||
)
|
||||
assert.ErrorContains(t, err, "invalid argument \"bar=not-unint32\" for \"--map-string-uint32\" flag: strconv.ParseUint: parsing \"not-unint32\": invalid syntax")
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err = runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
@ -338,7 +344,7 @@ func TestMap(t *testing.T) {
|
||||
func TestEverything(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
_, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err := runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1",
|
||||
"abc",
|
||||
@ -450,7 +456,7 @@ func TestEverything(t *testing.T) {
|
||||
func TestPubKeyParsingConsensusAddress(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
_, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err := runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1", "abc", "1foo",
|
||||
"--a-consensus-address", "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"j8qdbR+AlH/V6aBTCSWXRvX3JUESF2bV+SEzndBhF0o=\"}",
|
||||
@ -463,7 +469,7 @@ func TestPubKeyParsingConsensusAddress(t *testing.T) {
|
||||
func TestJSONParsing(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
_, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err := runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1", "abc", "1foo",
|
||||
"--some-messages", `{"bar":"baz"}`,
|
||||
@ -472,7 +478,7 @@ func TestJSONParsing(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, fixture.conn.lastRequest, fixture.conn.lastResponse.(*testpb.EchoResponse).Request, protocmp.Transform())
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err = runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1", "abc", "1foo",
|
||||
"--some-messages", "testdata/some_message.json",
|
||||
@ -485,7 +491,7 @@ func TestJSONParsing(t *testing.T) {
|
||||
func TestOptions(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
_, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err := runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1", "abc", "123foo",
|
||||
"-u", "27", // shorthand
|
||||
@ -552,7 +558,7 @@ func TestBinaryFlag(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err := runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1", "abc", `100foo`,
|
||||
"--bz", tc.input,
|
||||
@ -569,23 +575,25 @@ func TestBinaryFlag(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAddressValidation(t *testing.T) {
|
||||
t.Skip() // TODO(@julienrbrt) re-able with better keyring instiantiation
|
||||
|
||||
fixture := initFixture(t)
|
||||
|
||||
_, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err := runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1", "abc", "1foo",
|
||||
"--an-address", "cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk",
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err = runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1", "abc", "1foo",
|
||||
"--an-address", "regen1y74p8wyy4enfhfn342njve6cjmj5c8dtlqj7ule2",
|
||||
)
|
||||
assert.ErrorContains(t, err, "invalid account address")
|
||||
|
||||
_, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
_, err = runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1", "abc", "1foo",
|
||||
"--an-address", "cosmps1BAD_ENCODING",
|
||||
@ -596,7 +604,7 @@ func TestAddressValidation(t *testing.T) {
|
||||
func TestOutputFormat(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
out, err := runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1", "abc", "1foo",
|
||||
"--output", "json",
|
||||
@ -604,7 +612,7 @@ func TestOutputFormat(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, strings.Contains(out.String(), "{"))
|
||||
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand,
|
||||
out, err = runCmd(fixture, buildModuleQueryCommand,
|
||||
"echo",
|
||||
"1", "abc", "1foo",
|
||||
"--output", "text",
|
||||
@ -616,19 +624,19 @@ func TestOutputFormat(t *testing.T) {
|
||||
func TestHelpQuery(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand, "-h")
|
||||
out, err := runCmd(fixture, buildModuleQueryCommand, "-h")
|
||||
assert.NilError(t, err)
|
||||
golden.Assert(t, out.String(), "help-toplevel.golden")
|
||||
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand, "echo", "-h")
|
||||
out, err = runCmd(fixture, buildModuleQueryCommand, "echo", "-h")
|
||||
assert.NilError(t, err)
|
||||
golden.Assert(t, out.String(), "help-echo.golden")
|
||||
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand, "deprecatedecho", "echo", "-h")
|
||||
out, err = runCmd(fixture, buildModuleQueryCommand, "deprecatedecho", "echo", "-h")
|
||||
assert.NilError(t, err)
|
||||
golden.Assert(t, out.String(), "help-deprecated.golden")
|
||||
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand, "skipecho", "-h")
|
||||
out, err = runCmd(fixture, buildModuleQueryCommand, "skipecho", "-h")
|
||||
assert.NilError(t, err)
|
||||
golden.Assert(t, out.String(), "help-skip.golden")
|
||||
}
|
||||
@ -636,12 +644,12 @@ func TestHelpQuery(t *testing.T) {
|
||||
func TestDeprecatedQuery(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand, "echo",
|
||||
out, err := runCmd(fixture, buildModuleQueryCommand, "echo",
|
||||
"1", "abc", "--deprecated-field", "foo")
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, strings.Contains(out.String(), "--deprecated-field has been deprecated"))
|
||||
|
||||
out, err = runCmd(fixture.conn, fixture.b, buildModuleQueryCommand, "echo",
|
||||
out, err = runCmd(fixture, buildModuleQueryCommand, "echo",
|
||||
"1", "abc", "-s", "foo")
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, strings.Contains(out.String(), "--shorthand-deprecated-field has been deprecated"))
|
||||
@ -659,7 +667,7 @@ func TestBuildCustomQueryCommand(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
cmd, err := b.BuildQueryCommand(appOptions, map[string]*cobra.Command{
|
||||
cmd, err := b.BuildQueryCommand(context.Background(), appOptions, map[string]*cobra.Command{
|
||||
"test": {Use: "test", Run: func(cmd *cobra.Command, args []string) {
|
||||
customCommandCalled = true
|
||||
}},
|
||||
@ -677,7 +685,7 @@ func TestNotFoundErrorsQuery(t *testing.T) {
|
||||
b.AddTxConnFlags = nil
|
||||
|
||||
buildModuleQueryCommand := func(moduleName string, cmdDescriptor *autocliv1.ServiceCommandDescriptor) (*cobra.Command, error) {
|
||||
cmd := topLevelCmd("query", "Querying subcommands")
|
||||
cmd := topLevelCmd(context.Background(), "query", "Querying subcommands")
|
||||
err := b.AddMsgServiceCommands(cmd, cmdDescriptor)
|
||||
return cmd, err
|
||||
}
|
||||
@ -727,7 +735,7 @@ func TestNotFoundErrorsQuery(t *testing.T) {
|
||||
func TestDurationMarshal(t *testing.T) {
|
||||
fixture := initFixture(t)
|
||||
|
||||
out, err := runCmd(fixture.conn, fixture.b, buildModuleQueryCommand, "echo", "1", "abc", "--duration", "1s")
|
||||
out, err := runCmd(fixture, buildModuleQueryCommand, "echo", "1", "abc", "--duration", "1s")
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, strings.Contains(out.String(), "duration: 1s"))
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package autocli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@ -31,14 +32,17 @@ func findSubCommand(cmd *cobra.Command, subCmdName string) *cobra.Command {
|
||||
// topLevelCmd creates a new top-level command with the provided name and
|
||||
// description. The command will have DisableFlagParsing set to false and
|
||||
// SuggestionsMinimumDistance set to 2.
|
||||
func topLevelCmd(use, short string) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
func topLevelCmd(ctx context.Context, use, short string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: use,
|
||||
Short: short,
|
||||
DisableFlagParsing: false,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: validateCmd,
|
||||
}
|
||||
cmd.SetContext(ctx)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func protoNameToCliName(name protoreflect.Name) string {
|
||||
|
||||
@ -9,8 +9,8 @@ $SIMD_BIN config set client chain-id demo
|
||||
$SIMD_BIN config set client keyring-backend test
|
||||
$SIMD_BIN config set client keyring-default-keyname alice
|
||||
$SIMD_BIN config set app api.enable true
|
||||
$SIMD_BIN keys add alice
|
||||
$SIMD_BIN keys add bob
|
||||
$SIMD_BIN keys add alice --indiscreet
|
||||
$SIMD_BIN keys add bob --indiscreet
|
||||
$SIMD_BIN init test --chain-id demo
|
||||
$SIMD_BIN genesis add-genesis-account alice 5000000000stake --keyring-backend test
|
||||
$SIMD_BIN genesis add-genesis-account bob 5000000000stake --keyring-backend test
|
||||
|
||||
Loading…
Reference in New Issue
Block a user