diff --git a/internal/cmd/variable/create/create.go b/internal/cmd/variable/create/create.go index b62fe4a..449418e 100644 --- a/internal/cmd/variable/create/create.go +++ b/internal/cmd/variable/create/create.go @@ -16,6 +16,7 @@ type Options struct { id string name string environmentID string + rawKeys []string keys map[string]string skipConfirm bool inputDone bool @@ -36,12 +37,16 @@ func NewCmdCreateVariable(f *cmdutil.Factory) *cobra.Command { util.AddServiceParam(cmd, &opts.id, &opts.name) util.AddEnvOfServiceParam(cmd, &opts.environmentID) cmd.Flags().BoolVarP(&opts.skipConfirm, "yes", "y", false, "Skip confirmation") - cmd.Flags().StringToStringVarP(&opts.keys, "key", "k", nil, "Key value pair of the variable") + cmd.Flags().StringArrayVarP(&opts.rawKeys, "key", "k", nil, "Key value pair of the variable (KEY=VALUE)") return cmd } func runCreateVariable(f *cmdutil.Factory, opts *Options) error { + if err := parseRawKeys(opts); err != nil { + return err + } + if f.Interactive { return runCreateVariableInteractive(f, opts) } else { @@ -49,6 +54,29 @@ func runCreateVariable(f *cmdutil.Factory, opts *Options) error { } } +// parseRawKeys converts the raw "KEY=VALUE" strings from --key flags +// into the keys map. It splits on the first "=" only, so values +// containing "=", "${}", commas, and other special characters are preserved. +func parseRawKeys(opts *Options) error { + if len(opts.rawKeys) == 0 { + return nil + } + + if opts.keys == nil { + opts.keys = make(map[string]string, len(opts.rawKeys)) + } + + for _, kv := range opts.rawKeys { + parts := strings.SplitN(kv, "=", 2) + if len(parts) != 2 || parts[0] == "" { + return fmt.Errorf("invalid key-value pair %q: expected KEY=VALUE format", kv) + } + opts.keys[parts[0]] = parts[1] + } + + return nil +} + func runCreateVariableInteractive(f *cmdutil.Factory, opts *Options) error { zctx := f.Config.GetContext() diff --git a/internal/cmd/variable/update/update.go b/internal/cmd/variable/update/update.go index bb8ad1b..e1946f4 100644 --- a/internal/cmd/variable/update/update.go +++ b/internal/cmd/variable/update/update.go @@ -3,6 +3,7 @@ package update import ( "context" "fmt" + "strings" "github.com/briandowns/spinner" "github.com/spf13/cobra" @@ -15,6 +16,7 @@ type Options struct { id string name string environmentID string + rawKeys []string keys map[string]string skipConfirm bool inputDone bool @@ -35,12 +37,16 @@ func NewCmdUpdateVariable(f *cmdutil.Factory) *cobra.Command { util.AddServiceParam(cmd, &opts.id, &opts.name) util.AddEnvOfServiceParam(cmd, &opts.environmentID) cmd.Flags().BoolVarP(&opts.skipConfirm, "yes", "y", false, "Skip confirmation") - cmd.Flags().StringToStringVarP(&opts.keys, "key", "k", nil, "Key value pair of the variable") + cmd.Flags().StringArrayVarP(&opts.rawKeys, "key", "k", nil, "Key value pair of the variable (KEY=VALUE)") return cmd } func runUpdateVariable(f *cmdutil.Factory, opts *Options) error { + if err := parseRawKeys(opts); err != nil { + return err + } + if f.Interactive { opts.keys = make(map[string]string) return runUpdateVariableInteractive(f, opts) @@ -48,6 +54,29 @@ func runUpdateVariable(f *cmdutil.Factory, opts *Options) error { return runUpdateVariableNonInteractive(f, opts) } +// parseRawKeys converts the raw "KEY=VALUE" strings from --key flags +// into the keys map. It splits on the first "=" only, so values +// containing "=", "${}", commas, and other special characters are preserved. +func parseRawKeys(opts *Options) error { + if len(opts.rawKeys) == 0 { + return nil + } + + if opts.keys == nil { + opts.keys = make(map[string]string, len(opts.rawKeys)) + } + + for _, kv := range opts.rawKeys { + parts := strings.SplitN(kv, "=", 2) + if len(parts) != 2 || parts[0] == "" { + return fmt.Errorf("invalid key-value pair %q: expected KEY=VALUE format", kv) + } + opts.keys[parts[0]] = parts[1] + } + + return nil +} + func runUpdateVariableInteractive(f *cmdutil.Factory, opts *Options) error { zctx := f.Config.GetContext()