pflag is a drop-in replacement of Go's native flag package. If you import pflag under the name "flag" then all code should continue to function with no changes.
import flag "github.com/spf13/pflag"
There is one exception to this: if you directly instantiate the Flag struct there is one more field "Shorthand" that you will need to set. Most code never instantiates this struct directly, and instead uses functions such as String(), BoolVar(), and Var(), and is therefore unaffected.
package main import ( "fmt" "github.com/spf13/pflag" "github.com/spf13/viper" ) func aliasNormalizeFunc(f *pflag.FlagSet, n string) pflag.NormalizedName { switch n { case "pass", "ps": n = "password" } return pflag.NormalizedName(n) } func main() { pflag.StringP("name", "n", "Frank", "Name parameter") pflag.StringP("password", "p", "hardToGuess", "Password") pflag.CommandLine.SetNormalizeFunc(aliasNormalizeFunc) pflag.Parse() viper.BindPFlags(pflag.CommandLine) name := viper.GetString("name") password := viper.GetString("password") fmt.Println(name, password) // Reading an environment variable viper.BindEnv("GOMAXPROCS") val := viper.Get("GOMAXPROCS") if val != nil { fmt.Println("GOMAXPROCS:", val) } else { // Setting an environment variable viper.Set("GOMAXPROCS", 8) val = viper.Get("GOMAXPROCS") fmt.Println("GOMAXPROCS:", val) } }
zzh@ZZHPC:/zdata/Github/ztest$ go run main.go --help Usage of /tmp/go-build3847677257/b001/exe/main: -n, --name string Name parameter (default "Frank") -p, --password string Password (default "hardToGuess") pflag: help requested exit status 2 zzh@ZZHPC:/zdata/Github/ztest$ go run main.go -n ZhangZhihui -p ZZZ ZhangZhihui ZZZ GOMAXPROCS: 8 zzh@ZZHPC:/zdata/Github/ztest$ go run main.go Frank hardToGuess GOMAXPROCS: 8
package main import ( "fmt" "os" "github.com/spf13/viper" ) type Config struct { MacPass string `mapstructure:"macos"` LinuxPass string `mapstructure:"linux"` WindowsPass string `mapstructure:"windows"` PostHost string `mapstructure:"postgres"` MySQLHost string `mapstructure:"mysql"` MongoHost string `mapstructure:"mongodb"` } func main() { var configFile = ".config.json" if len(os.Args) == 1 { fmt.Println("Using default config file", configFile) } else { configFile = os.Args[1] } viper.SetConfigType("json") viper.SetConfigFile(configFile) fmt.Printf("Using config file %s\n", viper.ConfigFileUsed()) viper.ReadInConfig() if viper.IsSet("macos") { fmt.Println("macos:", viper.Get("macos")) } else { fmt.Println("macos not set!") } if viper.IsSet("active") { value := viper.GetBool("active") if value { postgres := viper.Get("postgres") mysql := viper.Get("mysql") mongo := viper.Get("mongodb") fmt.Println("P:", postgres, "My:", mysql, "Mo:", mongo) } } else { fmt.Println("active is not set!") } if !viper.IsSet("DoesNotExist") { fmt.Println("DoesNotExist is not set!") } var config Config err := viper.Unmarshal(&config) if err != nil { fmt.Println(err) os.Exit(1) } fmt.Printf("%#v\n", config) }
zzh@ZZHPC:/zdata/Github/ztest$ go run main.go Using default config file .config.json Using config file .config.json macos not set! active is not set! DoesNotExist is not set! main.Config{MacPass:"", LinuxPass:"", WindowsPass:"", PostHost:"", MySQLHost:"", MongoHost:""}