Skip to content

StringSlice behavior different for command line flag and environment variable #380

@jgoodall

Description

@jgoodall

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)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions