1[![Build Status](https://travis-ci.org/spf13/pflag.svg?branch=master)](https://travis-ci.org/spf13/pflag) 2[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/pflag)](https://goreportcard.com/report/github.com/spf13/pflag) 3[![GoDoc](https://godoc.org/github.com/spf13/pflag?status.svg)](https://godoc.org/github.com/spf13/pflag) 4 5## Description 6 7pflag is a drop-in replacement for Go's flag package, implementing 8POSIX/GNU-style --flags. 9 10pflag is compatible with the [GNU extensions to the POSIX recommendations 11for command-line options][1]. For a more precise description, see the 12"Command-line flag syntax" section below. 13 14[1]: http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html 15 16pflag is available under the same style of BSD license as the Go language, 17which can be found in the LICENSE file. 18 19## Installation 20 21pflag is available using the standard `go get` command. 22 23Install by running: 24 25 go get github.com/spf13/pflag 26 27Run tests by running: 28 29 go test github.com/spf13/pflag 30 31## Usage 32 33pflag is a drop-in replacement of Go's native flag package. If you import 34pflag under the name "flag" then all code should continue to function 35with no changes. 36 37``` go 38import flag "github.com/spf13/pflag" 39``` 40 41There is one exception to this: if you directly instantiate the Flag struct 42there is one more field "Shorthand" that you will need to set. 43Most code never instantiates this struct directly, and instead uses 44functions such as String(), BoolVar(), and Var(), and is therefore 45unaffected. 46 47Define flags using flag.String(), Bool(), Int(), etc. 48 49This declares an integer flag, -flagname, stored in the pointer ip, with type *int. 50 51``` go 52var ip *int = flag.Int("flagname", 1234, "help message for flagname") 53``` 54 55If you like, you can bind the flag to a variable using the Var() functions. 56 57``` go 58var flagvar int 59func init() { 60 flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") 61} 62``` 63 64Or you can create custom flags that satisfy the Value interface (with 65pointer receivers) and couple them to flag parsing by 66 67``` go 68flag.Var(&flagVal, "name", "help message for flagname") 69``` 70 71For such flags, the default value is just the initial value of the variable. 72 73After all flags are defined, call 74 75``` go 76flag.Parse() 77``` 78 79to parse the command line into the defined flags. 80 81Flags may then be used directly. If you're using the flags themselves, 82they are all pointers; if you bind to variables, they're values. 83 84``` go 85fmt.Println("ip has value ", *ip) 86fmt.Println("flagvar has value ", flagvar) 87``` 88 89There are helper functions available to get the value stored in a Flag if you have a FlagSet but find 90it difficult to keep up with all of the pointers in your code. 91If you have a pflag.FlagSet with a flag called 'flagname' of type int you 92can use GetInt() to get the int value. But notice that 'flagname' must exist 93and it must be an int. GetString("flagname") will fail. 94 95``` go 96i, err := flagset.GetInt("flagname") 97``` 98 99After parsing, the arguments after the flag are available as the 100slice flag.Args() or individually as flag.Arg(i). 101The arguments are indexed from 0 through flag.NArg()-1. 102 103The pflag package also defines some new functions that are not in flag, 104that give one-letter shorthands for flags. You can use these by appending 105'P' to the name of any function that defines a flag. 106 107``` go 108var ip = flag.IntP("flagname", "f", 1234, "help message") 109var flagvar bool 110func init() { 111 flag.BoolVarP(&flagvar, "boolname", "b", true, "help message") 112} 113flag.VarP(&flagVal, "varname", "v", "help message") 114``` 115 116Shorthand letters can be used with single dashes on the command line. 117Boolean shorthand flags can be combined with other shorthand flags. 118 119The default set of command-line flags is controlled by 120top-level functions. The FlagSet type allows one to define 121independent sets of flags, such as to implement subcommands 122in a command-line interface. The methods of FlagSet are 123analogous to the top-level functions for the command-line 124flag set. 125 126## Setting no option default values for flags 127 128After you create a flag it is possible to set the pflag.NoOptDefVal for 129the given flag. Doing this changes the meaning of the flag slightly. If 130a flag has a NoOptDefVal and the flag is set on the command line without 131an option the flag will be set to the NoOptDefVal. For example given: 132 133``` go 134var ip = flag.IntP("flagname", "f", 1234, "help message") 135flag.Lookup("flagname").NoOptDefVal = "4321" 136``` 137 138Would result in something like 139 140| Parsed Arguments | Resulting Value | 141| ------------- | ------------- | 142| --flagname=1357 | ip=1357 | 143| --flagname | ip=4321 | 144| [nothing] | ip=1234 | 145 146## Command line flag syntax 147 148``` 149--flag // boolean flags, or flags with no option default values 150--flag x // only on flags without a default value 151--flag=x 152``` 153 154Unlike the flag package, a single dash before an option means something 155different than a double dash. Single dashes signify a series of shorthand 156letters for flags. All but the last shorthand letter must be boolean flags 157or a flag with a default value 158 159``` 160// boolean or flags where the 'no option default value' is set 161-f 162-f=true 163-abc 164but 165-b true is INVALID 166 167// non-boolean and flags without a 'no option default value' 168-n 1234 169-n=1234 170-n1234 171 172// mixed 173-abcs "hello" 174-absd="hello" 175-abcs1234 176``` 177 178Flag parsing stops after the terminator "--". Unlike the flag package, 179flags can be interspersed with arguments anywhere on the command line 180before this terminator. 181 182Integer flags accept 1234, 0664, 0x1234 and may be negative. 183Boolean flags (in their long form) accept 1, 0, t, f, true, false, 184TRUE, FALSE, True, False. 185Duration flags accept any input valid for time.ParseDuration. 186 187## Mutating or "Normalizing" Flag names 188 189It is possible to set a custom flag name 'normalization function.' It allows flag names to be mutated both when created in the code and when used on the command line to some 'normalized' form. The 'normalized' form is used for comparison. Two examples of using the custom normalization func follow. 190 191**Example #1**: You want -, _, and . in flags to compare the same. aka --my-flag == --my_flag == --my.flag 192 193``` go 194func wordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName { 195 from := []string{"-", "_"} 196 to := "." 197 for _, sep := range from { 198 name = strings.Replace(name, sep, to, -1) 199 } 200 return pflag.NormalizedName(name) 201} 202 203myFlagSet.SetNormalizeFunc(wordSepNormalizeFunc) 204``` 205 206**Example #2**: You want to alias two flags. aka --old-flag-name == --new-flag-name 207 208``` go 209func aliasNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName { 210 switch name { 211 case "old-flag-name": 212 name = "new-flag-name" 213 break 214 } 215 return pflag.NormalizedName(name) 216} 217 218myFlagSet.SetNormalizeFunc(aliasNormalizeFunc) 219``` 220 221## Deprecating a flag or its shorthand 222It is possible to deprecate a flag, or just its shorthand. Deprecating a flag/shorthand hides it from help text and prints a usage message when the deprecated flag/shorthand is used. 223 224**Example #1**: You want to deprecate a flag named "badflag" as well as inform the users what flag they should use instead. 225```go 226// deprecate a flag by specifying its name and a usage message 227flags.MarkDeprecated("badflag", "please use --good-flag instead") 228``` 229This hides "badflag" from help text, and prints `Flag --badflag has been deprecated, please use --good-flag instead` when "badflag" is used. 230 231**Example #2**: You want to keep a flag name "noshorthandflag" but deprecate its shortname "n". 232```go 233// deprecate a flag shorthand by specifying its flag name and a usage message 234flags.MarkShorthandDeprecated("noshorthandflag", "please use --noshorthandflag only") 235``` 236This hides the shortname "n" from help text, and prints `Flag shorthand -n has been deprecated, please use --noshorthandflag only` when the shorthand "n" is used. 237 238Note that usage message is essential here, and it should not be empty. 239 240## Hidden flags 241It is possible to mark a flag as hidden, meaning it will still function as normal, however will not show up in usage/help text. 242 243**Example**: You have a flag named "secretFlag" that you need for internal use only and don't want it showing up in help text, or for its usage text to be available. 244```go 245// hide a flag by specifying its name 246flags.MarkHidden("secretFlag") 247``` 248 249## Disable sorting of flags 250`pflag` allows you to disable sorting of flags for help and usage message. 251 252**Example**: 253```go 254flags.BoolP("verbose", "v", false, "verbose output") 255flags.String("coolflag", "yeaah", "it's really cool flag") 256flags.Int("usefulflag", 777, "sometimes it's very useful") 257flags.SortFlags = false 258flags.PrintDefaults() 259``` 260**Output**: 261``` 262 -v, --verbose verbose output 263 --coolflag string it's really cool flag (default "yeaah") 264 --usefulflag int sometimes it's very useful (default 777) 265``` 266 267 268## Supporting Go flags when using pflag 269In order to support flags defined using Go's `flag` package, they must be added to the `pflag` flagset. This is usually necessary 270to support flags defined by third-party dependencies (e.g. `golang/glog`). 271 272**Example**: You want to add the Go flags to the `CommandLine` flagset 273```go 274import ( 275 goflag "flag" 276 flag "github.com/spf13/pflag" 277) 278 279var ip *int = flag.Int("flagname", 1234, "help message for flagname") 280 281func main() { 282 flag.CommandLine.AddGoFlagSet(goflag.CommandLine) 283 flag.Parse() 284} 285``` 286 287## More info 288 289You can see the full reference documentation of the pflag package 290[at godoc.org][3], or through go's standard documentation system by 291running `godoc -http=:6060` and browsing to 292[http://localhost:6060/pkg/github.com/spf13/pflag][2] after 293installation. 294 295[2]: http://localhost:6060/pkg/github.com/spf13/pflag 296[3]: http://godoc.org/github.com/spf13/pflag 297