-
Notifications
You must be signed in to change notification settings - Fork 2.1k
String Slices from pflags are not handled correctly by viper. #200
Copy link
Copy link
Closed
Description
The slice of strings just contains one element that is the stringified version of the string
ie: []string{"[firstarg,secondarg]"}
or in the case of nil/empty: []string{"[]"}
It appears that this is coming from the Pflag libraries ValueString() function. I've included a patch that "helps" the issue but I suspect it's a little bit more deep-seated as the cast package also doesn't seem to handle this case well at all hence I'm not making trying to make a PR for this.
For others hitting this issue the workaround is to simply use pflags directly for string slices until this is fixed.
diff --git a/viper.go b/viper.go
index a2633b0..d1cce44 100644
--- a/viper.go
+++ b/viper.go
@@ -479,6 +479,8 @@ func (v *Viper) Get(key string) interface{} {
val = cast.ToInt(flag.ValueString())
case "bool":
val = cast.ToBool(flag.ValueString())
+ case "stringSlice":
+ val = []string{}
default:
val = flag.ValueString()
}
@@ -742,6 +744,8 @@ func (v *Viper) find(key string) interface{} {
return cast.ToInt(flag.ValueString())
case "bool":
return cast.ToBool(flag.ValueString())
+ case "stringSlice":
+ return strings.Split(strings.Trim(flag.ValueString(), "[]"), ",")
default:
return flag.ValueString()
}Example program that shows the the failure:
package main
import (
"fmt"
"os"
"github.com/davecgh/go-spew/spew"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func main() {
var rootCmd = &cobra.Command{
Run: run,
}
rootCmd.PersistentFlags().StringSliceP("thing", "t", nil, "")
viper.BindPFlags(rootCmd.PersistentFlags())
if err := rootCmd.Execute(); err != nil {
fmt.Printf("\n%+v\n", err)
os.Exit(1)
}
}
func run(cmd *cobra.Command, args []string) {
str := viper.Get("thing")
slice := viper.GetStringSlice("thing")
slicePFlag, _ := cmd.PersistentFlags().GetStringSlice("thing")
spew.Dump(str, slice, slicePFlag)
}Output (annotated for clarity) of go run main.go
str = (string) (len=2) "[]"
slice = ([]string) (len=1 cap=1) {
(string) (len=2) "[]"
}
slicePFlag = ([]string) {}
Output (annotated for clarity) of go run main.go -t thing1 -t thing2
str = (string) (len=15) "[thing1,thing2]"
slice = ([]string) (len=1 cap=1) {
(string) (len=15) "[thing1,thing2]"
}
slicePFlag = ([]string) (len=2 cap=2) {
(string) (len=6) "thing1",
(string) (len=6) "thing2"
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels