feat(config): add config set subcommand with type validation
This commit is contained in:
parent
c9b448d508
commit
4afc0fd8ce
2 changed files with 72 additions and 0 deletions
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
|
|
@ -107,11 +108,59 @@ var configInitCmd = &cobra.Command{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var configSetCmd = &cobra.Command{
|
||||||
|
Use: "set <key> <value>",
|
||||||
|
Short: "Set a configuration value",
|
||||||
|
Args: cobra.ExactArgs(2),
|
||||||
|
SilenceUsage: true,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
key, raw := args[0], args[1]
|
||||||
|
|
||||||
|
// Work on a copy of the current config so we can write it back.
|
||||||
|
cfg := config
|
||||||
|
defaults := defaultConfig()
|
||||||
|
fields := configFields(&cfg, &defaults)
|
||||||
|
f := findConfigField(fields, key)
|
||||||
|
if f == nil {
|
||||||
|
err := fmt.Errorf("unknown config key '%s'", key)
|
||||||
|
if suggestions := suggestConfigKey(fields, key); len(suggestions) > 0 {
|
||||||
|
return withHint(err, fmt.Sprintf("did you mean '%s'?", strings.Join(suggestions, "', '")))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch f.Kind {
|
||||||
|
case reflect.Bool:
|
||||||
|
switch raw {
|
||||||
|
case "true":
|
||||||
|
f.Field.SetBool(true)
|
||||||
|
case "false":
|
||||||
|
f.Field.SetBool(false)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("cannot set '%s': expected bool (true/false), got '%s'", key, raw)
|
||||||
|
}
|
||||||
|
case reflect.String:
|
||||||
|
f.Field.SetString(raw)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("cannot set '%s': unsupported type %s", key, f.Kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writeConfigFile(cfg); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reload so subsequent commands in the same process see the change.
|
||||||
|
config = cfg
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
configInitCmd.Flags().Bool("new", false, "overwrite existing config file")
|
configInitCmd.Flags().Bool("new", false, "overwrite existing config file")
|
||||||
configCmd.AddCommand(configGetCmd)
|
configCmd.AddCommand(configGetCmd)
|
||||||
configCmd.AddCommand(configInitCmd)
|
configCmd.AddCommand(configInitCmd)
|
||||||
configCmd.AddCommand(configListCmd)
|
configCmd.AddCommand(configListCmd)
|
||||||
configCmd.AddCommand(configPathCmd)
|
configCmd.AddCommand(configPathCmd)
|
||||||
|
configCmd.AddCommand(configSetCmd)
|
||||||
rootCmd.AddCommand(configCmd)
|
rootCmd.AddCommand(configCmd)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
testdata/config-set.ct
vendored
Normal file
23
testdata/config-set.ct
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Set a bool value and verify with get
|
||||||
|
$ pda config set git.auto_commit true
|
||||||
|
$ pda config get git.auto_commit
|
||||||
|
true
|
||||||
|
|
||||||
|
# Set a string value
|
||||||
|
$ pda config set store.default_store_name mystore
|
||||||
|
$ pda config get store.default_store_name
|
||||||
|
mystore
|
||||||
|
|
||||||
|
# Set back to original
|
||||||
|
$ pda config set git.auto_commit false
|
||||||
|
$ pda config get git.auto_commit
|
||||||
|
false
|
||||||
|
|
||||||
|
# Bad type
|
||||||
|
$ pda config set git.auto_commit yes --> FAIL
|
||||||
|
FAIL cannot set 'git.auto_commit': expected bool (true/false), got 'yes'
|
||||||
|
|
||||||
|
# Unknown key
|
||||||
|
$ pda config set git.auto_comit true --> FAIL
|
||||||
|
FAIL unknown config key 'git.auto_comit'
|
||||||
|
hint did you mean 'git.auto_commit'?
|
||||||
Loading…
Add table
Add a link
Reference in a new issue