cobra-prompt icon indicating copy to clipboard operation
cobra-prompt copied to clipboard

Incorrect behavior when restoring default value of slice type flags.

Open sagan opened this issue 1 month ago • 0 comments

If PersistFlagValues is false, cobra-prompt restore all flags to default value after every command execution.

cobra-prompt.go

func findSuggestions(co *CobraPrompt, d *prompt.Document) []prompt.Suggest {
	//...
	addFlags := func(flag *pflag.Flag) {
		if flag.Changed && !persistFlagValues {
			flag.Value.Set(flag.DefValue)
		}
		//...
	}
	//...
}

However, if the flag is a SliceValue (e.g. []string), the flag.DefValue is the result of value.String(), which basically is a csv enclaved in "[]", e.g. [foo,bar]. Also, the Set(value string) method of SliceValue will only append the value to existing array. To set the whole flag values to new array, Replace method should be used instead.

To handle slice flags correctly, I suggest make the following changes:

import "encoding/csv"

func findSuggestions(co *CobraPrompt, d *prompt.Document) []prompt.Suggest {
	//...
	addFlags := func(flag *pflag.Flag) {
		if flag.Changed && !persistFlagValues {
			if sv, ok := flag.Value.(pflag.SliceValue); ok {
				// flag.DefValue is  "[" + writeAsCSV(values) + "]"
				stringReader := strings.NewReader(flag.DefValue[1 : len(flag.DefValue)-1])
				csvReader := csv.NewReader(stringReader)
				values, err := csvReader.Read()
				if err == nil {
					sv.Replace(values)
				}
			} else {
				flag.Value.Set(flag.DefValue)
			}
		}
		//...
	}
	//...
}

sagan avatar May 15 '24 07:05 sagan