127 lines
3.8 KiB
Go
127 lines
3.8 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/creachadair/tomledit"
|
|
"github.com/creachadair/tomledit/parser"
|
|
"github.com/creachadair/tomledit/transform"
|
|
"github.com/spf13/cobra"
|
|
|
|
"cosmossdk.io/tools/confix"
|
|
|
|
"github.com/cosmos/cosmos-sdk/client"
|
|
)
|
|
|
|
// SetCommand returns a CLI command to interactively update an application config value.
|
|
func SetCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "set [config] [key] [value]",
|
|
Short: "Set an application config value",
|
|
Long: "Set an application config value. The [config] argument must be the path of the file when using the `confix` tool standalone, otherwise it must be the name of the config file without the .toml extension.",
|
|
Args: cobra.ExactArgs(3),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
filename, inputValue := args[0], args[2]
|
|
// parse key e.g mempool.size -> [mempool, size]
|
|
key := strings.Split(args[1], ".")
|
|
|
|
clientCtx := client.GetClientContextFromCmd(cmd)
|
|
if clientCtx.HomeDir != "" {
|
|
filename = filepath.Join(clientCtx.HomeDir, "config", filename+tomlSuffix)
|
|
}
|
|
|
|
plan := transform.Plan{
|
|
{
|
|
Desc: fmt.Sprintf("update %q=%q in %s", key, inputValue, filename),
|
|
T: transform.Func(func(_ context.Context, doc *tomledit.Document) error {
|
|
results := doc.Find(key...)
|
|
if len(results) == 0 {
|
|
return fmt.Errorf("key %q not found", key)
|
|
} else if len(results) > 1 {
|
|
return fmt.Errorf("key %q is ambiguous", key)
|
|
}
|
|
|
|
value, err := parser.ParseValue(inputValue)
|
|
if err != nil {
|
|
value = parser.MustValue(`"` + inputValue + `"`)
|
|
}
|
|
|
|
if ok := transform.InsertMapping(results[0].Section, &parser.KeyValue{
|
|
Block: results[0].Block,
|
|
Name: results[0].Name,
|
|
Value: value,
|
|
}, true); !ok {
|
|
return errors.New("failed to set value")
|
|
}
|
|
|
|
return nil
|
|
}),
|
|
},
|
|
}
|
|
|
|
outputPath := filename
|
|
if FlagStdOut {
|
|
outputPath = ""
|
|
}
|
|
|
|
ctx := cmd.Context()
|
|
if FlagVerbose {
|
|
ctx = confix.WithLogWriter(ctx, cmd.ErrOrStderr())
|
|
}
|
|
|
|
doc, err := confix.LoadConfig(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return confix.Upgrade(ctx, plan, doc, filename, outputPath, FlagSkipValidate)
|
|
},
|
|
}
|
|
|
|
cmd.Flags().BoolVar(&FlagStdOut, "stdout", false, "print the updated config to stdout")
|
|
cmd.Flags().BoolVarP(&FlagVerbose, "verbose", "v", false, "log changes to stderr")
|
|
cmd.Flags().BoolVarP(&FlagSkipValidate, "skip-validate", "s", false, "skip configuration validation (allows to mutate unknown configurations)")
|
|
|
|
return cmd
|
|
}
|
|
|
|
// GetCommand returns a CLI command to interactively get an application config value.
|
|
func GetCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "get [config] [key]",
|
|
Short: "Get an application config value",
|
|
Long: "Get an application config value. The [config] argument must be the path of the file when using the `confix` tool standalone, otherwise it must be the name of the config file without the .toml extension.",
|
|
Args: cobra.ExactArgs(2),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
filename, key := args[0], args[1]
|
|
// parse key e.g mempool.size -> [mempool, size]
|
|
keys := strings.Split(key, ".")
|
|
|
|
clientCtx := client.GetClientContextFromCmd(cmd)
|
|
if clientCtx.HomeDir != "" {
|
|
filename = filepath.Join(clientCtx.HomeDir, "config", filename+tomlSuffix)
|
|
}
|
|
|
|
doc, err := confix.LoadConfig(filename)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to load config: %w", err)
|
|
}
|
|
|
|
results := doc.Find(keys...)
|
|
if len(results) == 0 {
|
|
return fmt.Errorf("key %q not found", key)
|
|
} else if len(results) > 1 {
|
|
return fmt.Errorf("key %q is ambiguous", key)
|
|
}
|
|
|
|
return clientCtx.PrintString(fmt.Sprintf("%s\n", results[0].Value.String()))
|
|
},
|
|
}
|
|
|
|
return cmd
|
|
}
|