feat(client/v2): combine autocli and custom cmd within a module (#17088)
This commit is contained in:
@@ -102,11 +102,11 @@ func (appOptions AppOptions) EnhanceRootCommandWithBuilder(rootCmd *cobra.Comman
|
||||
}
|
||||
|
||||
if queryCmd := findSubCommand(rootCmd, "query"); queryCmd != nil {
|
||||
if err := builder.enhanceCommandCommon(queryCmd, appOptions, customQueryCmds, enhanceQuery); err != nil {
|
||||
if err := builder.enhanceCommandCommon(queryCmd, queryCmdType, appOptions, customQueryCmds); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
queryCmd, err := builder.BuildQueryCommand(appOptions, customQueryCmds, enhanceQuery)
|
||||
queryCmd, err := builder.BuildQueryCommand(appOptions, customQueryCmds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -115,11 +115,11 @@ func (appOptions AppOptions) EnhanceRootCommandWithBuilder(rootCmd *cobra.Comman
|
||||
}
|
||||
|
||||
if msgCmd := findSubCommand(rootCmd, "tx"); msgCmd != nil {
|
||||
if err := builder.enhanceCommandCommon(msgCmd, appOptions, customMsgCmds, enhanceMsg); err != nil {
|
||||
if err := builder.enhanceCommandCommon(msgCmd, msgCmdType, appOptions, customMsgCmds); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
subCmd, err := builder.BuildMsgCommand(appOptions, customMsgCmds, enhanceMsg)
|
||||
subCmd, err := builder.BuildMsgCommand(appOptions, customMsgCmds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+57
-15
@@ -16,6 +16,13 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
)
|
||||
|
||||
type cmdType int
|
||||
|
||||
const (
|
||||
queryCmdType cmdType = iota
|
||||
msgCmdType
|
||||
)
|
||||
|
||||
func (b *Builder) buildMethodCommandCommon(descriptor protoreflect.MethodDescriptor, options *autocliv1.RpcCommandOptions, exec func(cmd *cobra.Command, input protoreflect.Message) error) (*cobra.Command, error) {
|
||||
if options == nil {
|
||||
// use the defaults
|
||||
@@ -73,9 +80,9 @@ func (b *Builder) buildMethodCommandCommon(descriptor protoreflect.MethodDescrip
|
||||
// automatically fill in missing commands.
|
||||
func (b *Builder) enhanceCommandCommon(
|
||||
cmd *cobra.Command,
|
||||
cmdType cmdType,
|
||||
appOptions AppOptions,
|
||||
customCmds map[string]*cobra.Command,
|
||||
buildModuleCommand enhanceCommandFunc,
|
||||
) error {
|
||||
moduleOptions := appOptions.ModuleOptions
|
||||
if len(moduleOptions) == 0 {
|
||||
@@ -89,38 +96,54 @@ func (b *Builder) enhanceCommandCommon(
|
||||
|
||||
modules := append(maps.Keys(appOptions.Modules), maps.Keys(moduleOptions)...)
|
||||
for _, moduleName := range modules {
|
||||
modOpts, hasModuleOptions := moduleOptions[moduleName]
|
||||
|
||||
// if we have an existing command skip adding one here
|
||||
if findSubCommand(cmd, moduleName) != nil {
|
||||
if subCmd := findSubCommand(cmd, moduleName); subCmd != nil {
|
||||
if hasModuleOptions {
|
||||
if err := enhanceCustomCmd(b, subCmd, cmdType, modOpts); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// if we have a custom command use that instead of generating one
|
||||
if custom := customCmds[moduleName]; custom != nil {
|
||||
// custom commands get added lower down
|
||||
if custom, ok := customCmds[moduleName]; ok {
|
||||
if hasModuleOptions {
|
||||
if err := enhanceCustomCmd(b, custom, cmdType, modOpts); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cmd.AddCommand(custom)
|
||||
continue
|
||||
}
|
||||
|
||||
// check for autocli options
|
||||
modOpts := moduleOptions[moduleName]
|
||||
if modOpts == nil {
|
||||
// if we don't have module options, skip adding a command as we don't have anything to add
|
||||
if !hasModuleOptions {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := buildModuleCommand(b, moduleName, cmd, modOpts); err != nil {
|
||||
return err
|
||||
switch cmdType {
|
||||
case queryCmdType:
|
||||
if err := enhanceQuery(b, moduleName, cmd, modOpts); err != nil {
|
||||
return err
|
||||
}
|
||||
case msgCmdType:
|
||||
if err := enhanceMsg(b, moduleName, cmd, modOpts); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type enhanceCommandFunc func(builder *Builder, moduleName string, cmd *cobra.Command, modOpts *autocliv1.ModuleOptions) error
|
||||
|
||||
// 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 {
|
||||
queryCmdDesc := modOpts.Query
|
||||
if queryCmdDesc != nil {
|
||||
if queryCmdDesc := modOpts.Query; queryCmdDesc != nil {
|
||||
subCmd := topLevelCmd(moduleName, fmt.Sprintf("Querying commands for the %s module", moduleName))
|
||||
if err := builder.AddQueryServiceCommands(subCmd, queryCmdDesc); err != nil {
|
||||
return err
|
||||
@@ -134,8 +157,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 {
|
||||
txCmdDesc := modOpts.Tx
|
||||
if txCmdDesc != nil {
|
||||
if txCmdDesc := modOpts.Tx; txCmdDesc != nil {
|
||||
subCmd := topLevelCmd(moduleName, fmt.Sprintf("Transactions commands for the %s module", moduleName))
|
||||
if err := builder.AddMsgServiceCommands(subCmd, txCmdDesc); err != nil {
|
||||
return err
|
||||
@@ -147,6 +169,26 @@ func enhanceMsg(builder *Builder, moduleName string, cmd *cobra.Command, modOpts
|
||||
return nil
|
||||
}
|
||||
|
||||
// enhanceCustomCmd enhances the provided custom query or msg command autocli commands for a module.
|
||||
func enhanceCustomCmd(builder *Builder, cmd *cobra.Command, cmdType cmdType, modOpts *autocliv1.ModuleOptions) error {
|
||||
switch cmdType {
|
||||
case queryCmdType:
|
||||
if modOpts.Query != nil && modOpts.Query.EnhanceCustomCommand {
|
||||
if err := builder.AddQueryServiceCommands(cmd, modOpts.Query); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case msgCmdType:
|
||||
if modOpts.Tx != nil && modOpts.Tx.EnhanceCustomCommand {
|
||||
if err := builder.AddMsgServiceCommands(cmd, modOpts.Tx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -13,9 +13,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, buildModuleCommand enhanceCommandFunc) (*cobra.Command, error) {
|
||||
func (b *Builder) BuildMsgCommand(appOptions AppOptions, customCmds map[string]*cobra.Command) (*cobra.Command, error) {
|
||||
msgCmd := topLevelCmd("tx", "Transaction subcommands")
|
||||
if err := b.enhanceCommandCommon(msgCmd, appOptions, customCmds, enhanceMsg); err != nil {
|
||||
if err := b.enhanceCommandCommon(msgCmd, msgCmdType, appOptions, customCmds); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -75,6 +75,12 @@ func (b *Builder) AddMsgServiceCommands(cmd *cobra.Command, cmdDescriptor *autoc
|
||||
return err
|
||||
}
|
||||
|
||||
if findSubCommand(cmd, methodCmd.Name()) != nil {
|
||||
// do not overwrite existing commands
|
||||
// @julienrbrt: should we display a warning?
|
||||
continue
|
||||
}
|
||||
|
||||
if methodCmd != nil {
|
||||
cmd.AddCommand(methodCmd)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
|
||||
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, testCmdMsgDesc)
|
||||
return cmd, err
|
||||
}
|
||||
@@ -258,7 +257,7 @@ func TestBuildMsgCommand(t *testing.T) {
|
||||
"test": {Use: "test", Run: func(cmd *cobra.Command, args []string) {
|
||||
customCommandCalled = true
|
||||
}},
|
||||
}, enhanceMsg)
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
cmd.SetArgs([]string{"test", "tx"})
|
||||
assert.NilError(t, cmd.Execute())
|
||||
@@ -295,12 +294,12 @@ func TestErrorBuildMsgCommand(t *testing.T) {
|
||||
ValidatorAddressCodec: b.ValidatorAddressCodec,
|
||||
}
|
||||
|
||||
_, err := b.BuildMsgCommand(appOptions, nil, enhanceMsg)
|
||||
_, err := b.BuildMsgCommand(appOptions, nil)
|
||||
assert.ErrorContains(t, err, "can't find field un-existent-proto-field")
|
||||
|
||||
nonExistentService := &autocliv1.ServiceCommandDescriptor{Service: "un-existent-service"}
|
||||
appOptions.ModuleOptions["test"].Tx = nonExistentService
|
||||
_, err = b.BuildMsgCommand(appOptions, nil, enhanceMsg)
|
||||
_, err = b.BuildMsgCommand(appOptions, nil)
|
||||
assert.ErrorContains(t, err, "can't find service un-existent-service")
|
||||
}
|
||||
|
||||
@@ -368,7 +367,7 @@ func TestEnhanceMessageCommand(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := b.enhanceCommandCommon(cmd, appOptions, map[string]*cobra.Command{}, enhanceMsg)
|
||||
err := b.enhanceCommandCommon(cmd, msgCmdType, appOptions, map[string]*cobra.Command{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
cmd = &cobra.Command{Use: "test"}
|
||||
@@ -377,7 +376,7 @@ func TestEnhanceMessageCommand(t *testing.T) {
|
||||
customCommands := map[string]*cobra.Command{
|
||||
"test2": {Use: "test"},
|
||||
}
|
||||
err = b.enhanceCommandCommon(cmd, appOptions, customCommands, enhanceMsg)
|
||||
err = b.enhanceCommandCommon(cmd, msgCmdType, appOptions, customCommands)
|
||||
assert.NilError(t, err)
|
||||
|
||||
cmd = &cobra.Command{Use: "test"}
|
||||
@@ -387,6 +386,6 @@ func TestEnhanceMessageCommand(t *testing.T) {
|
||||
},
|
||||
}
|
||||
customCommands = map[string]*cobra.Command{}
|
||||
err = b.enhanceCommandCommon(cmd, appOptions, customCommands, enhanceMsg)
|
||||
err = b.enhanceCommandCommon(cmd, msgCmdType, appOptions, customCommands)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@ 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, enhanceQuery enhanceCommandFunc) (*cobra.Command, error) {
|
||||
func (b *Builder) BuildQueryCommand(appOptions AppOptions, customCmds map[string]*cobra.Command) (*cobra.Command, error) {
|
||||
queryCmd := topLevelCmd("query", "Querying subcommands")
|
||||
queryCmd.Aliases = []string{"q"}
|
||||
|
||||
if err := b.enhanceCommandCommon(queryCmd, appOptions, customCmds, enhanceQuery); err != nil {
|
||||
if err := b.enhanceCommandCommon(queryCmd, queryCmdType, appOptions, customCmds); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -80,6 +80,12 @@ func (b *Builder) AddQueryServiceCommands(cmd *cobra.Command, cmdDescriptor *aut
|
||||
return err
|
||||
}
|
||||
|
||||
if findSubCommand(cmd, methodCmd.Name()) != nil {
|
||||
// do not overwrite existing commands
|
||||
// @julienrbrt: should we display a warning?
|
||||
continue
|
||||
}
|
||||
|
||||
cmd.AddCommand(methodCmd)
|
||||
}
|
||||
|
||||
|
||||
@@ -576,7 +576,7 @@ func TestBuildCustomQueryCommand(t *testing.T) {
|
||||
"test": {Use: "test", Run: func(cmd *cobra.Command, args []string) {
|
||||
customCommandCalled = true
|
||||
}},
|
||||
}, enhanceQuery)
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
cmd.SetArgs([]string{"test", "query"})
|
||||
assert.NilError(t, cmd.Execute())
|
||||
@@ -591,7 +591,6 @@ func TestNotFoundErrors(t *testing.T) {
|
||||
|
||||
buildModuleQueryCommand := func(moduleName string, cmdDescriptor *autocliv1.ServiceCommandDescriptor) (*cobra.Command, error) {
|
||||
cmd := topLevelCmd("query", "Querying subcommands")
|
||||
|
||||
err := b.AddMsgServiceCommands(cmd, cmdDescriptor)
|
||||
return cmd, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user