The behavior is different for StringSlice if an argument is on the command line flag compared to an environment variable. The flag is parsed correctly, but the environment variable is not.
Here is an example to see the behavior:
package main
import (
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var RootCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
h := viper.GetStringSlice("hosts")
fmt.Printf("hosts: %+v (type: %T, length: %d)\n", h, h, len(h))
},
}
func init() {
viper.SetEnvPrefix("test")
viper.AutomaticEnv()
RootCmd.PersistentFlags().StringSlice("hosts", []string{}, "list of hosts")
viper.BindPFlag("hosts", RootCmd.PersistentFlags().Lookup("hosts"))
viper.SetDefault("hosts", []string{})
}
func Execute() {
RootCmd.Execute()
}
func main() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
Here is the output:
# Incorrect length of 1
$ TEST_HOSTS=1.2.3.4:9000,5.6.7.8:9000 go run main.go
hosts: [1.2.3.4:9000,5.6.7.8:9000] (type: []string, length: 1)
# Correctly set length of 2
$ go run main.go --hosts=1.2.3.4:9000,5.6.7.8:9000
hosts: [1.2.3.4:9000 5.6.7.8:9000] (type: []string, length: 2)
The behavior is different for
StringSliceif an argument is on the command line flag compared to an environment variable. The flag is parsed correctly, but the environment variable is not.Here is an example to see the behavior:
Here is the output: