From 4afc0fd8ce5585b89c0bf3d00cd3828b1508db4d Mon Sep 17 00:00:00 2001 From: lew Date: Wed, 11 Feb 2026 23:49:44 +0000 Subject: [PATCH] feat(config): add config set subcommand with type validation --- cmd/config_cmd.go | 49 ++++++++++++++++++++++++++++++++++++++++++ testdata/config-set.ct | 23 ++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 testdata/config-set.ct diff --git a/cmd/config_cmd.go b/cmd/config_cmd.go index 21361cc..cbee910 100644 --- a/cmd/config_cmd.go +++ b/cmd/config_cmd.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "reflect" "strings" "github.com/BurntSushi/toml" @@ -107,11 +108,59 @@ var configInitCmd = &cobra.Command{ }, } +var configSetCmd = &cobra.Command{ + Use: "set ", + 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() { configInitCmd.Flags().Bool("new", false, "overwrite existing config file") configCmd.AddCommand(configGetCmd) configCmd.AddCommand(configInitCmd) configCmd.AddCommand(configListCmd) configCmd.AddCommand(configPathCmd) + configCmd.AddCommand(configSetCmd) rootCmd.AddCommand(configCmd) } diff --git a/testdata/config-set.ct b/testdata/config-set.ct new file mode 100644 index 0000000..38cb572 --- /dev/null +++ b/testdata/config-set.ct @@ -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'?