1// Copyright 2009 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5/* 6Package pflag is a drop-in replacement for Go's flag package, implementing 7POSIX/GNU-style --flags. 8 9pflag is compatible with the GNU extensions to the POSIX recommendations 10for command-line options. See 11http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html 12 13Usage: 14 15pflag is a drop-in replacement of Go's native flag package. If you import 16pflag under the name "flag" then all code should continue to function 17with no changes. 18 19 import flag "github.com/spf13/pflag" 20 21There is one exception to this: if you directly instantiate the Flag struct 22there is one more field "Shorthand" that you will need to set. 23Most code never instantiates this struct directly, and instead uses 24functions such as String(), BoolVar(), and Var(), and is therefore 25unaffected. 26 27Define flags using flag.String(), Bool(), Int(), etc. 28 29This declares an integer flag, -flagname, stored in the pointer ip, with type *int. 30 var ip = flag.Int("flagname", 1234, "help message for flagname") 31If you like, you can bind the flag to a variable using the Var() functions. 32 var flagvar int 33 func init() { 34 flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") 35 } 36Or you can create custom flags that satisfy the Value interface (with 37pointer receivers) and couple them to flag parsing by 38 flag.Var(&flagVal, "name", "help message for flagname") 39For such flags, the default value is just the initial value of the variable. 40 41After all flags are defined, call 42 flag.Parse() 43to parse the command line into the defined flags. 44 45Flags may then be used directly. If you're using the flags themselves, 46they are all pointers; if you bind to variables, they're values. 47 fmt.Println("ip has value ", *ip) 48 fmt.Println("flagvar has value ", flagvar) 49 50After parsing, the arguments after the flag are available as the 51slice flag.Args() or individually as flag.Arg(i). 52The arguments are indexed from 0 through flag.NArg()-1. 53 54The pflag package also defines some new functions that are not in flag, 55that give one-letter shorthands for flags. You can use these by appending 56'P' to the name of any function that defines a flag. 57 var ip = flag.IntP("flagname", "f", 1234, "help message") 58 var flagvar bool 59 func init() { 60 flag.BoolVarP(&flagvar, "boolname", "b", true, "help message") 61 } 62 flag.VarP(&flagval, "varname", "v", "help message") 63Shorthand letters can be used with single dashes on the command line. 64Boolean shorthand flags can be combined with other shorthand flags. 65 66Command line flag syntax: 67 --flag // boolean flags only 68 --flag=x 69 70Unlike the flag package, a single dash before an option means something 71different than a double dash. Single dashes signify a series of shorthand 72letters for flags. All but the last shorthand letter must be boolean flags. 73 // boolean flags 74 -f 75 -abc 76 // non-boolean flags 77 -n 1234 78 -Ifile 79 // mixed 80 -abcs "hello" 81 -abcn1234 82 83Flag parsing stops after the terminator "--". Unlike the flag package, 84flags can be interspersed with arguments anywhere on the command line 85before this terminator. 86 87Integer flags accept 1234, 0664, 0x1234 and may be negative. 88Boolean flags (in their long form) accept 1, 0, t, f, true, false, 89TRUE, FALSE, True, False. 90Duration flags accept any input valid for time.ParseDuration. 91 92The default set of command-line flags is controlled by 93top-level functions. The FlagSet type allows one to define 94independent sets of flags, such as to implement subcommands 95in a command-line interface. The methods of FlagSet are 96analogous to the top-level functions for the command-line 97flag set. 98*/ 99package pflag 100 101import ( 102 "bytes" 103 "errors" 104 goflag "flag" 105 "fmt" 106 "io" 107 "os" 108 "sort" 109 "strings" 110) 111 112// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined. 113var ErrHelp = errors.New("pflag: help requested") 114 115// ErrorHandling defines how to handle flag parsing errors. 116type ErrorHandling int 117 118const ( 119 // ContinueOnError will return an err from Parse() if an error is found 120 ContinueOnError ErrorHandling = iota 121 // ExitOnError will call os.Exit(2) if an error is found when parsing 122 ExitOnError 123 // PanicOnError will panic() if an error is found when parsing flags 124 PanicOnError 125) 126 127// ParseErrorsWhitelist defines the parsing errors that can be ignored 128type ParseErrorsWhitelist struct { 129 // UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags 130 UnknownFlags bool 131} 132 133// NormalizedName is a flag name that has been normalized according to rules 134// for the FlagSet (e.g. making '-' and '_' equivalent). 135type NormalizedName string 136 137// A FlagSet represents a set of defined flags. 138type FlagSet struct { 139 // Usage is the function called when an error occurs while parsing flags. 140 // The field is a function (not a method) that may be changed to point to 141 // a custom error handler. 142 Usage func() 143 144 // SortFlags is used to indicate, if user wants to have sorted flags in 145 // help/usage messages. 146 SortFlags bool 147 148 // ParseErrorsWhitelist is used to configure a whitelist of errors 149 ParseErrorsWhitelist ParseErrorsWhitelist 150 151 name string 152 parsed bool 153 actual map[NormalizedName]*Flag 154 orderedActual []*Flag 155 sortedActual []*Flag 156 formal map[NormalizedName]*Flag 157 orderedFormal []*Flag 158 sortedFormal []*Flag 159 shorthands map[byte]*Flag 160 args []string // arguments after flags 161 argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no -- 162 errorHandling ErrorHandling 163 output io.Writer // nil means stderr; use Output() accessor 164 interspersed bool // allow interspersed option/non-option args 165 normalizeNameFunc func(f *FlagSet, name string) NormalizedName 166 167 addedGoFlagSets []*goflag.FlagSet 168} 169 170// A Flag represents the state of a flag. 171type Flag struct { 172 Name string // name as it appears on command line 173 Shorthand string // one-letter abbreviated flag 174 Usage string // help message 175 Value Value // value as set 176 DefValue string // default value (as text); for usage message 177 Changed bool // If the user set the value (or if left to default) 178 NoOptDefVal string // default value (as text); if the flag is on the command line without any options 179 Deprecated string // If this flag is deprecated, this string is the new or now thing to use 180 Hidden bool // used by cobra.Command to allow flags to be hidden from help/usage text 181 ShorthandDeprecated string // If the shorthand of this flag is deprecated, this string is the new or now thing to use 182 Annotations map[string][]string // used by cobra.Command bash autocomple code 183} 184 185// Value is the interface to the dynamic value stored in a flag. 186// (The default value is represented as a string.) 187type Value interface { 188 String() string 189 Set(string) error 190 Type() string 191} 192 193// SliceValue is a secondary interface to all flags which hold a list 194// of values. This allows full control over the value of list flags, 195// and avoids complicated marshalling and unmarshalling to csv. 196type SliceValue interface { 197 // Append adds the specified value to the end of the flag value list. 198 Append(string) error 199 // Replace will fully overwrite any data currently in the flag value list. 200 Replace([]string) error 201 // GetSlice returns the flag value list as an array of strings. 202 GetSlice() []string 203} 204 205// sortFlags returns the flags as a slice in lexicographical sorted order. 206func sortFlags(flags map[NormalizedName]*Flag) []*Flag { 207 list := make(sort.StringSlice, len(flags)) 208 i := 0 209 for k := range flags { 210 list[i] = string(k) 211 i++ 212 } 213 list.Sort() 214 result := make([]*Flag, len(list)) 215 for i, name := range list { 216 result[i] = flags[NormalizedName(name)] 217 } 218 return result 219} 220 221// SetNormalizeFunc allows you to add a function which can translate flag names. 222// Flags added to the FlagSet will be translated and then when anything tries to 223// look up the flag that will also be translated. So it would be possible to create 224// a flag named "getURL" and have it translated to "geturl". A user could then pass 225// "--getUrl" which may also be translated to "geturl" and everything will work. 226func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) { 227 f.normalizeNameFunc = n 228 f.sortedFormal = f.sortedFormal[:0] 229 for fname, flag := range f.formal { 230 nname := f.normalizeFlagName(flag.Name) 231 if fname == nname { 232 continue 233 } 234 flag.Name = string(nname) 235 delete(f.formal, fname) 236 f.formal[nname] = flag 237 if _, set := f.actual[fname]; set { 238 delete(f.actual, fname) 239 f.actual[nname] = flag 240 } 241 } 242} 243 244// GetNormalizeFunc returns the previously set NormalizeFunc of a function which 245// does no translation, if not set previously. 246func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName { 247 if f.normalizeNameFunc != nil { 248 return f.normalizeNameFunc 249 } 250 return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) } 251} 252 253func (f *FlagSet) normalizeFlagName(name string) NormalizedName { 254 n := f.GetNormalizeFunc() 255 return n(f, name) 256} 257 258// Output returns the destination for usage and error messages. os.Stderr is returned if 259// output was not set or was set to nil. 260func (f *FlagSet) Output() io.Writer { 261 if f.output == nil { 262 return os.Stderr 263 } 264 return f.output 265} 266 267// Name returns the name of the flag set. 268func (f *FlagSet) Name() string { 269 return f.name 270} 271 272// SetOutput sets the destination for usage and error messages. 273// If output is nil, os.Stderr is used. 274func (f *FlagSet) SetOutput(output io.Writer) { 275 f.output = output 276} 277 278// VisitAll visits the flags in lexicographical order or 279// in primordial order if f.SortFlags is false, calling fn for each. 280// It visits all flags, even those not set. 281func (f *FlagSet) VisitAll(fn func(*Flag)) { 282 if len(f.formal) == 0 { 283 return 284 } 285 286 var flags []*Flag 287 if f.SortFlags { 288 if len(f.formal) != len(f.sortedFormal) { 289 f.sortedFormal = sortFlags(f.formal) 290 } 291 flags = f.sortedFormal 292 } else { 293 flags = f.orderedFormal 294 } 295 296 for _, flag := range flags { 297 fn(flag) 298 } 299} 300 301// HasFlags returns a bool to indicate if the FlagSet has any flags defined. 302func (f *FlagSet) HasFlags() bool { 303 return len(f.formal) > 0 304} 305 306// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags 307// that are not hidden. 308func (f *FlagSet) HasAvailableFlags() bool { 309 for _, flag := range f.formal { 310 if !flag.Hidden { 311 return true 312 } 313 } 314 return false 315} 316 317// VisitAll visits the command-line flags in lexicographical order or 318// in primordial order if f.SortFlags is false, calling fn for each. 319// It visits all flags, even those not set. 320func VisitAll(fn func(*Flag)) { 321 CommandLine.VisitAll(fn) 322} 323 324// Visit visits the flags in lexicographical order or 325// in primordial order if f.SortFlags is false, calling fn for each. 326// It visits only those flags that have been set. 327func (f *FlagSet) Visit(fn func(*Flag)) { 328 if len(f.actual) == 0 { 329 return 330 } 331 332 var flags []*Flag 333 if f.SortFlags { 334 if len(f.actual) != len(f.sortedActual) { 335 f.sortedActual = sortFlags(f.actual) 336 } 337 flags = f.sortedActual 338 } else { 339 flags = f.orderedActual 340 } 341 342 for _, flag := range flags { 343 fn(flag) 344 } 345} 346 347// Visit visits the command-line flags in lexicographical order or 348// in primordial order if f.SortFlags is false, calling fn for each. 349// It visits only those flags that have been set. 350func Visit(fn func(*Flag)) { 351 CommandLine.Visit(fn) 352} 353 354// Lookup returns the Flag structure of the named flag, returning nil if none exists. 355func (f *FlagSet) Lookup(name string) *Flag { 356 return f.lookup(f.normalizeFlagName(name)) 357} 358 359// ShorthandLookup returns the Flag structure of the short handed flag, 360// returning nil if none exists. 361// It panics, if len(name) > 1. 362func (f *FlagSet) ShorthandLookup(name string) *Flag { 363 if name == "" { 364 return nil 365 } 366 if len(name) > 1 { 367 msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name) 368 fmt.Fprintf(f.Output(), msg) 369 panic(msg) 370 } 371 c := name[0] 372 return f.shorthands[c] 373} 374 375// lookup returns the Flag structure of the named flag, returning nil if none exists. 376func (f *FlagSet) lookup(name NormalizedName) *Flag { 377 return f.formal[name] 378} 379 380// func to return a given type for a given flag name 381func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) { 382 flag := f.Lookup(name) 383 if flag == nil { 384 err := fmt.Errorf("flag accessed but not defined: %s", name) 385 return nil, err 386 } 387 388 if flag.Value.Type() != ftype { 389 err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type()) 390 return nil, err 391 } 392 393 sval := flag.Value.String() 394 result, err := convFunc(sval) 395 if err != nil { 396 return nil, err 397 } 398 return result, nil 399} 400 401// ArgsLenAtDash will return the length of f.Args at the moment when a -- was 402// found during arg parsing. This allows your program to know which args were 403// before the -- and which came after. 404func (f *FlagSet) ArgsLenAtDash() int { 405 return f.argsLenAtDash 406} 407 408// MarkDeprecated indicated that a flag is deprecated in your program. It will 409// continue to function but will not show up in help or usage messages. Using 410// this flag will also print the given usageMessage. 411func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error { 412 flag := f.Lookup(name) 413 if flag == nil { 414 return fmt.Errorf("flag %q does not exist", name) 415 } 416 if usageMessage == "" { 417 return fmt.Errorf("deprecated message for flag %q must be set", name) 418 } 419 flag.Deprecated = usageMessage 420 flag.Hidden = true 421 return nil 422} 423 424// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your 425// program. It will continue to function but will not show up in help or usage 426// messages. Using this flag will also print the given usageMessage. 427func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error { 428 flag := f.Lookup(name) 429 if flag == nil { 430 return fmt.Errorf("flag %q does not exist", name) 431 } 432 if usageMessage == "" { 433 return fmt.Errorf("deprecated message for flag %q must be set", name) 434 } 435 flag.ShorthandDeprecated = usageMessage 436 return nil 437} 438 439// MarkHidden sets a flag to 'hidden' in your program. It will continue to 440// function but will not show up in help or usage messages. 441func (f *FlagSet) MarkHidden(name string) error { 442 flag := f.Lookup(name) 443 if flag == nil { 444 return fmt.Errorf("flag %q does not exist", name) 445 } 446 flag.Hidden = true 447 return nil 448} 449 450// Lookup returns the Flag structure of the named command-line flag, 451// returning nil if none exists. 452func Lookup(name string) *Flag { 453 return CommandLine.Lookup(name) 454} 455 456// ShorthandLookup returns the Flag structure of the short handed flag, 457// returning nil if none exists. 458func ShorthandLookup(name string) *Flag { 459 return CommandLine.ShorthandLookup(name) 460} 461 462// Set sets the value of the named flag. 463func (f *FlagSet) Set(name, value string) error { 464 normalName := f.normalizeFlagName(name) 465 flag, ok := f.formal[normalName] 466 if !ok { 467 return fmt.Errorf("no such flag -%v", name) 468 } 469 470 err := flag.Value.Set(value) 471 if err != nil { 472 var flagName string 473 if flag.Shorthand != "" && flag.ShorthandDeprecated == "" { 474 flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name) 475 } else { 476 flagName = fmt.Sprintf("--%s", flag.Name) 477 } 478 return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err) 479 } 480 481 if !flag.Changed { 482 if f.actual == nil { 483 f.actual = make(map[NormalizedName]*Flag) 484 } 485 f.actual[normalName] = flag 486 f.orderedActual = append(f.orderedActual, flag) 487 488 flag.Changed = true 489 } 490 491 if flag.Deprecated != "" { 492 fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) 493 } 494 return nil 495} 496 497// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet. 498// This is sometimes used by spf13/cobra programs which want to generate additional 499// bash completion information. 500func (f *FlagSet) SetAnnotation(name, key string, values []string) error { 501 normalName := f.normalizeFlagName(name) 502 flag, ok := f.formal[normalName] 503 if !ok { 504 return fmt.Errorf("no such flag -%v", name) 505 } 506 if flag.Annotations == nil { 507 flag.Annotations = map[string][]string{} 508 } 509 flag.Annotations[key] = values 510 return nil 511} 512 513// Changed returns true if the flag was explicitly set during Parse() and false 514// otherwise 515func (f *FlagSet) Changed(name string) bool { 516 flag := f.Lookup(name) 517 // If a flag doesn't exist, it wasn't changed.... 518 if flag == nil { 519 return false 520 } 521 return flag.Changed 522} 523 524// Set sets the value of the named command-line flag. 525func Set(name, value string) error { 526 return CommandLine.Set(name, value) 527} 528 529// PrintDefaults prints, to standard error unless configured 530// otherwise, the default values of all defined flags in the set. 531func (f *FlagSet) PrintDefaults() { 532 usages := f.FlagUsages() 533 fmt.Fprint(f.Output(), usages) 534} 535 536// defaultIsZeroValue returns true if the default value for this flag represents 537// a zero value. 538func (f *Flag) defaultIsZeroValue() bool { 539 switch f.Value.(type) { 540 case boolFlag: 541 return f.DefValue == "false" 542 case *durationValue: 543 // Beginning in Go 1.7, duration zero values are "0s" 544 return f.DefValue == "0" || f.DefValue == "0s" 545 case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value: 546 return f.DefValue == "0" 547 case *stringValue: 548 return f.DefValue == "" 549 case *ipValue, *ipMaskValue, *ipNetValue: 550 return f.DefValue == "<nil>" 551 case *intSliceValue, *stringSliceValue, *stringArrayValue: 552 return f.DefValue == "[]" 553 default: 554 switch f.Value.String() { 555 case "false": 556 return true 557 case "<nil>": 558 return true 559 case "": 560 return true 561 case "0": 562 return true 563 } 564 return false 565 } 566} 567 568// UnquoteUsage extracts a back-quoted name from the usage 569// string for a flag and returns it and the un-quoted usage. 570// Given "a `name` to show" it returns ("name", "a name to show"). 571// If there are no back quotes, the name is an educated guess of the 572// type of the flag's value, or the empty string if the flag is boolean. 573func UnquoteUsage(flag *Flag) (name string, usage string) { 574 // Look for a back-quoted name, but avoid the strings package. 575 usage = flag.Usage 576 for i := 0; i < len(usage); i++ { 577 if usage[i] == '`' { 578 for j := i + 1; j < len(usage); j++ { 579 if usage[j] == '`' { 580 name = usage[i+1 : j] 581 usage = usage[:i] + name + usage[j+1:] 582 return name, usage 583 } 584 } 585 break // Only one back quote; use type name. 586 } 587 } 588 589 name = flag.Value.Type() 590 switch name { 591 case "bool": 592 name = "" 593 case "float64": 594 name = "float" 595 case "int64": 596 name = "int" 597 case "uint64": 598 name = "uint" 599 case "stringSlice": 600 name = "strings" 601 case "intSlice": 602 name = "ints" 603 case "uintSlice": 604 name = "uints" 605 case "boolSlice": 606 name = "bools" 607 } 608 609 return 610} 611 612// Splits the string `s` on whitespace into an initial substring up to 613// `i` runes in length and the remainder. Will go `slop` over `i` if 614// that encompasses the entire string (which allows the caller to 615// avoid short orphan words on the final line). 616func wrapN(i, slop int, s string) (string, string) { 617 if i+slop > len(s) { 618 return s, "" 619 } 620 621 w := strings.LastIndexAny(s[:i], " \t\n") 622 if w <= 0 { 623 return s, "" 624 } 625 nlPos := strings.LastIndex(s[:i], "\n") 626 if nlPos > 0 && nlPos < w { 627 return s[:nlPos], s[nlPos+1:] 628 } 629 return s[:w], s[w+1:] 630} 631 632// Wraps the string `s` to a maximum width `w` with leading indent 633// `i`. The first line is not indented (this is assumed to be done by 634// caller). Pass `w` == 0 to do no wrapping 635func wrap(i, w int, s string) string { 636 if w == 0 { 637 return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1) 638 } 639 640 // space between indent i and end of line width w into which 641 // we should wrap the text. 642 wrap := w - i 643 644 var r, l string 645 646 // Not enough space for sensible wrapping. Wrap as a block on 647 // the next line instead. 648 if wrap < 24 { 649 i = 16 650 wrap = w - i 651 r += "\n" + strings.Repeat(" ", i) 652 } 653 // If still not enough space then don't even try to wrap. 654 if wrap < 24 { 655 return strings.Replace(s, "\n", r, -1) 656 } 657 658 // Try to avoid short orphan words on the final line, by 659 // allowing wrapN to go a bit over if that would fit in the 660 // remainder of the line. 661 slop := 5 662 wrap = wrap - slop 663 664 // Handle first line, which is indented by the caller (or the 665 // special case above) 666 l, s = wrapN(wrap, slop, s) 667 r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1) 668 669 // Now wrap the rest 670 for s != "" { 671 var t string 672 673 t, s = wrapN(wrap, slop, s) 674 r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1) 675 } 676 677 return r 678 679} 680 681// FlagUsagesWrapped returns a string containing the usage information 682// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no 683// wrapping) 684func (f *FlagSet) FlagUsagesWrapped(cols int) string { 685 buf := new(bytes.Buffer) 686 687 lines := make([]string, 0, len(f.formal)) 688 689 maxlen := 0 690 f.VisitAll(func(flag *Flag) { 691 if flag.Hidden { 692 return 693 } 694 695 line := "" 696 if flag.Shorthand != "" && flag.ShorthandDeprecated == "" { 697 line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name) 698 } else { 699 line = fmt.Sprintf(" --%s", flag.Name) 700 } 701 702 varname, usage := UnquoteUsage(flag) 703 if varname != "" { 704 line += " " + varname 705 } 706 if flag.NoOptDefVal != "" { 707 switch flag.Value.Type() { 708 case "string": 709 line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal) 710 case "bool": 711 if flag.NoOptDefVal != "true" { 712 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal) 713 } 714 case "count": 715 if flag.NoOptDefVal != "+1" { 716 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal) 717 } 718 default: 719 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal) 720 } 721 } 722 723 // This special character will be replaced with spacing once the 724 // correct alignment is calculated 725 line += "\x00" 726 if len(line) > maxlen { 727 maxlen = len(line) 728 } 729 730 line += usage 731 if !flag.defaultIsZeroValue() { 732 if flag.Value.Type() == "string" { 733 line += fmt.Sprintf(" (default %q)", flag.DefValue) 734 } else { 735 line += fmt.Sprintf(" (default %s)", flag.DefValue) 736 } 737 } 738 if len(flag.Deprecated) != 0 { 739 line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated) 740 } 741 742 lines = append(lines, line) 743 }) 744 745 for _, line := range lines { 746 sidx := strings.Index(line, "\x00") 747 spacing := strings.Repeat(" ", maxlen-sidx) 748 // maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx 749 fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:])) 750 } 751 752 return buf.String() 753} 754 755// FlagUsages returns a string containing the usage information for all flags in 756// the FlagSet 757func (f *FlagSet) FlagUsages() string { 758 return f.FlagUsagesWrapped(0) 759} 760 761// PrintDefaults prints to standard error the default values of all defined command-line flags. 762func PrintDefaults() { 763 CommandLine.PrintDefaults() 764} 765 766// defaultUsage is the default function to print a usage message. 767func defaultUsage(f *FlagSet) { 768 fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name) 769 f.PrintDefaults() 770} 771 772// NOTE: Usage is not just defaultUsage(CommandLine) 773// because it serves (via godoc flag Usage) as the example 774// for how to write your own usage function. 775 776// Usage prints to standard error a usage message documenting all defined command-line flags. 777// The function is a variable that may be changed to point to a custom function. 778// By default it prints a simple header and calls PrintDefaults; for details about the 779// format of the output and how to control it, see the documentation for PrintDefaults. 780var Usage = func() { 781 fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) 782 PrintDefaults() 783} 784 785// NFlag returns the number of flags that have been set. 786func (f *FlagSet) NFlag() int { return len(f.actual) } 787 788// NFlag returns the number of command-line flags that have been set. 789func NFlag() int { return len(CommandLine.actual) } 790 791// Arg returns the i'th argument. Arg(0) is the first remaining argument 792// after flags have been processed. 793func (f *FlagSet) Arg(i int) string { 794 if i < 0 || i >= len(f.args) { 795 return "" 796 } 797 return f.args[i] 798} 799 800// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument 801// after flags have been processed. 802func Arg(i int) string { 803 return CommandLine.Arg(i) 804} 805 806// NArg is the number of arguments remaining after flags have been processed. 807func (f *FlagSet) NArg() int { return len(f.args) } 808 809// NArg is the number of arguments remaining after flags have been processed. 810func NArg() int { return len(CommandLine.args) } 811 812// Args returns the non-flag arguments. 813func (f *FlagSet) Args() []string { return f.args } 814 815// Args returns the non-flag command-line arguments. 816func Args() []string { return CommandLine.args } 817 818// Var defines a flag with the specified name and usage string. The type and 819// value of the flag are represented by the first argument, of type Value, which 820// typically holds a user-defined implementation of Value. For instance, the 821// caller could create a flag that turns a comma-separated string into a slice 822// of strings by giving the slice the methods of Value; in particular, Set would 823// decompose the comma-separated string into the slice. 824func (f *FlagSet) Var(value Value, name string, usage string) { 825 f.VarP(value, name, "", usage) 826} 827 828// VarPF is like VarP, but returns the flag created 829func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag { 830 // Remember the default value as a string; it won't change. 831 flag := &Flag{ 832 Name: name, 833 Shorthand: shorthand, 834 Usage: usage, 835 Value: value, 836 DefValue: value.String(), 837 } 838 f.AddFlag(flag) 839 return flag 840} 841 842// VarP is like Var, but accepts a shorthand letter that can be used after a single dash. 843func (f *FlagSet) VarP(value Value, name, shorthand, usage string) { 844 f.VarPF(value, name, shorthand, usage) 845} 846 847// AddFlag will add the flag to the FlagSet 848func (f *FlagSet) AddFlag(flag *Flag) { 849 normalizedFlagName := f.normalizeFlagName(flag.Name) 850 851 _, alreadyThere := f.formal[normalizedFlagName] 852 if alreadyThere { 853 msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name) 854 fmt.Fprintln(f.Output(), msg) 855 panic(msg) // Happens only if flags are declared with identical names 856 } 857 if f.formal == nil { 858 f.formal = make(map[NormalizedName]*Flag) 859 } 860 861 flag.Name = string(normalizedFlagName) 862 f.formal[normalizedFlagName] = flag 863 f.orderedFormal = append(f.orderedFormal, flag) 864 865 if flag.Shorthand == "" { 866 return 867 } 868 if len(flag.Shorthand) > 1 { 869 msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand) 870 fmt.Fprintf(f.Output(), msg) 871 panic(msg) 872 } 873 if f.shorthands == nil { 874 f.shorthands = make(map[byte]*Flag) 875 } 876 c := flag.Shorthand[0] 877 used, alreadyThere := f.shorthands[c] 878 if alreadyThere { 879 msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name) 880 fmt.Fprintf(f.Output(), msg) 881 panic(msg) 882 } 883 f.shorthands[c] = flag 884} 885 886// AddFlagSet adds one FlagSet to another. If a flag is already present in f 887// the flag from newSet will be ignored. 888func (f *FlagSet) AddFlagSet(newSet *FlagSet) { 889 if newSet == nil { 890 return 891 } 892 newSet.VisitAll(func(flag *Flag) { 893 if f.Lookup(flag.Name) == nil { 894 f.AddFlag(flag) 895 } 896 }) 897} 898 899// Var defines a flag with the specified name and usage string. The type and 900// value of the flag are represented by the first argument, of type Value, which 901// typically holds a user-defined implementation of Value. For instance, the 902// caller could create a flag that turns a comma-separated string into a slice 903// of strings by giving the slice the methods of Value; in particular, Set would 904// decompose the comma-separated string into the slice. 905func Var(value Value, name string, usage string) { 906 CommandLine.VarP(value, name, "", usage) 907} 908 909// VarP is like Var, but accepts a shorthand letter that can be used after a single dash. 910func VarP(value Value, name, shorthand, usage string) { 911 CommandLine.VarP(value, name, shorthand, usage) 912} 913 914// failf prints to standard error a formatted error and usage message and 915// returns the error. 916func (f *FlagSet) failf(format string, a ...interface{}) error { 917 err := fmt.Errorf(format, a...) 918 if f.errorHandling != ContinueOnError { 919 fmt.Fprintln(f.Output(), err) 920 f.usage() 921 } 922 return err 923} 924 925// usage calls the Usage method for the flag set, or the usage function if 926// the flag set is CommandLine. 927func (f *FlagSet) usage() { 928 if f == CommandLine { 929 Usage() 930 } else if f.Usage == nil { 931 defaultUsage(f) 932 } else { 933 f.Usage() 934 } 935} 936 937//--unknown (args will be empty) 938//--unknown --next-flag ... (args will be --next-flag ...) 939//--unknown arg ... (args will be arg ...) 940func stripUnknownFlagValue(args []string) []string { 941 if len(args) == 0 { 942 //--unknown 943 return args 944 } 945 946 first := args[0] 947 if len(first) > 0 && first[0] == '-' { 948 //--unknown --next-flag ... 949 return args 950 } 951 952 //--unknown arg ... (args will be arg ...) 953 if len(args) > 1 { 954 return args[1:] 955 } 956 return nil 957} 958 959func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) { 960 a = args 961 name := s[2:] 962 if len(name) == 0 || name[0] == '-' || name[0] == '=' { 963 err = f.failf("bad flag syntax: %s", s) 964 return 965 } 966 967 split := strings.SplitN(name, "=", 2) 968 name = split[0] 969 flag, exists := f.formal[f.normalizeFlagName(name)] 970 971 if !exists { 972 switch { 973 case name == "help": 974 f.usage() 975 return a, ErrHelp 976 case f.ParseErrorsWhitelist.UnknownFlags: 977 // --unknown=unknownval arg ... 978 // we do not want to lose arg in this case 979 if len(split) >= 2 { 980 return a, nil 981 } 982 983 return stripUnknownFlagValue(a), nil 984 default: 985 err = f.failf("unknown flag: --%s", name) 986 return 987 } 988 } 989 990 var value string 991 if len(split) == 2 { 992 // '--flag=arg' 993 value = split[1] 994 } else if flag.NoOptDefVal != "" { 995 // '--flag' (arg was optional) 996 value = flag.NoOptDefVal 997 } else if len(a) > 0 { 998 // '--flag arg' 999 value = a[0] 1000 a = a[1:] 1001 } else { 1002 // '--flag' (arg was required) 1003 err = f.failf("flag needs an argument: %s", s) 1004 return 1005 } 1006 1007 err = fn(flag, value) 1008 if err != nil { 1009 f.failf(err.Error()) 1010 } 1011 return 1012} 1013 1014func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) { 1015 outArgs = args 1016 1017 if strings.HasPrefix(shorthands, "test.") { 1018 return 1019 } 1020 1021 outShorts = shorthands[1:] 1022 c := shorthands[0] 1023 1024 flag, exists := f.shorthands[c] 1025 if !exists { 1026 switch { 1027 case c == 'h': 1028 f.usage() 1029 err = ErrHelp 1030 return 1031 case f.ParseErrorsWhitelist.UnknownFlags: 1032 // '-f=arg arg ...' 1033 // we do not want to lose arg in this case 1034 if len(shorthands) > 2 && shorthands[1] == '=' { 1035 outShorts = "" 1036 return 1037 } 1038 1039 outArgs = stripUnknownFlagValue(outArgs) 1040 return 1041 default: 1042 err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands) 1043 return 1044 } 1045 } 1046 1047 var value string 1048 if len(shorthands) > 2 && shorthands[1] == '=' { 1049 // '-f=arg' 1050 value = shorthands[2:] 1051 outShorts = "" 1052 } else if flag.NoOptDefVal != "" { 1053 // '-f' (arg was optional) 1054 value = flag.NoOptDefVal 1055 } else if len(shorthands) > 1 { 1056 // '-farg' 1057 value = shorthands[1:] 1058 outShorts = "" 1059 } else if len(args) > 0 { 1060 // '-f arg' 1061 value = args[0] 1062 outArgs = args[1:] 1063 } else { 1064 // '-f' (arg was required) 1065 err = f.failf("flag needs an argument: %q in -%s", c, shorthands) 1066 return 1067 } 1068 1069 if flag.ShorthandDeprecated != "" { 1070 fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) 1071 } 1072 1073 err = fn(flag, value) 1074 if err != nil { 1075 f.failf(err.Error()) 1076 } 1077 return 1078} 1079 1080func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) { 1081 a = args 1082 shorthands := s[1:] 1083 1084 // "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv"). 1085 for len(shorthands) > 0 { 1086 shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn) 1087 if err != nil { 1088 return 1089 } 1090 } 1091 1092 return 1093} 1094 1095func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) { 1096 for len(args) > 0 { 1097 s := args[0] 1098 args = args[1:] 1099 if len(s) == 0 || s[0] != '-' || len(s) == 1 { 1100 if !f.interspersed { 1101 f.args = append(f.args, s) 1102 f.args = append(f.args, args...) 1103 return nil 1104 } 1105 f.args = append(f.args, s) 1106 continue 1107 } 1108 1109 if s[1] == '-' { 1110 if len(s) == 2 { // "--" terminates the flags 1111 f.argsLenAtDash = len(f.args) 1112 f.args = append(f.args, args...) 1113 break 1114 } 1115 args, err = f.parseLongArg(s, args, fn) 1116 } else { 1117 args, err = f.parseShortArg(s, args, fn) 1118 } 1119 if err != nil { 1120 return 1121 } 1122 } 1123 return 1124} 1125 1126// Parse parses flag definitions from the argument list, which should not 1127// include the command name. Must be called after all flags in the FlagSet 1128// are defined and before flags are accessed by the program. 1129// The return value will be ErrHelp if -help was set but not defined. 1130func (f *FlagSet) Parse(arguments []string) error { 1131 if f.addedGoFlagSets != nil { 1132 for _, goFlagSet := range f.addedGoFlagSets { 1133 goFlagSet.Parse(nil) 1134 } 1135 } 1136 f.parsed = true 1137 1138 if len(arguments) < 0 { 1139 return nil 1140 } 1141 1142 f.args = make([]string, 0, len(arguments)) 1143 1144 set := func(flag *Flag, value string) error { 1145 return f.Set(flag.Name, value) 1146 } 1147 1148 err := f.parseArgs(arguments, set) 1149 if err != nil { 1150 switch f.errorHandling { 1151 case ContinueOnError: 1152 return err 1153 case ExitOnError: 1154 fmt.Println(err) 1155 os.Exit(2) 1156 case PanicOnError: 1157 panic(err) 1158 } 1159 } 1160 return nil 1161} 1162 1163type parseFunc func(flag *Flag, value string) error 1164 1165// ParseAll parses flag definitions from the argument list, which should not 1166// include the command name. The arguments for fn are flag and value. Must be 1167// called after all flags in the FlagSet are defined and before flags are 1168// accessed by the program. The return value will be ErrHelp if -help was set 1169// but not defined. 1170func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error { 1171 f.parsed = true 1172 f.args = make([]string, 0, len(arguments)) 1173 1174 err := f.parseArgs(arguments, fn) 1175 if err != nil { 1176 switch f.errorHandling { 1177 case ContinueOnError: 1178 return err 1179 case ExitOnError: 1180 os.Exit(2) 1181 case PanicOnError: 1182 panic(err) 1183 } 1184 } 1185 return nil 1186} 1187 1188// Parsed reports whether f.Parse has been called. 1189func (f *FlagSet) Parsed() bool { 1190 return f.parsed 1191} 1192 1193// Parse parses the command-line flags from os.Args[1:]. Must be called 1194// after all flags are defined and before flags are accessed by the program. 1195func Parse() { 1196 // Ignore errors; CommandLine is set for ExitOnError. 1197 CommandLine.Parse(os.Args[1:]) 1198} 1199 1200// ParseAll parses the command-line flags from os.Args[1:] and called fn for each. 1201// The arguments for fn are flag and value. Must be called after all flags are 1202// defined and before flags are accessed by the program. 1203func ParseAll(fn func(flag *Flag, value string) error) { 1204 // Ignore errors; CommandLine is set for ExitOnError. 1205 CommandLine.ParseAll(os.Args[1:], fn) 1206} 1207 1208// SetInterspersed sets whether to support interspersed option/non-option arguments. 1209func SetInterspersed(interspersed bool) { 1210 CommandLine.SetInterspersed(interspersed) 1211} 1212 1213// Parsed returns true if the command-line flags have been parsed. 1214func Parsed() bool { 1215 return CommandLine.Parsed() 1216} 1217 1218// CommandLine is the default set of command-line flags, parsed from os.Args. 1219var CommandLine = NewFlagSet(os.Args[0], ExitOnError) 1220 1221// NewFlagSet returns a new, empty flag set with the specified name, 1222// error handling property and SortFlags set to true. 1223func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { 1224 f := &FlagSet{ 1225 name: name, 1226 errorHandling: errorHandling, 1227 argsLenAtDash: -1, 1228 interspersed: true, 1229 SortFlags: true, 1230 } 1231 return f 1232} 1233 1234// SetInterspersed sets whether to support interspersed option/non-option arguments. 1235func (f *FlagSet) SetInterspersed(interspersed bool) { 1236 f.interspersed = interspersed 1237} 1238 1239// Init sets the name and error handling property for a flag set. 1240// By default, the zero FlagSet uses an empty name and the 1241// ContinueOnError error handling policy. 1242func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { 1243 f.name = name 1244 f.errorHandling = errorHandling 1245 f.argsLenAtDash = -1 1246} 1247