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