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 first[0] == '-' { 929 //--unknown --next-flag ... 930 return args 931 } 932 933 //--unknown arg ... (args will be arg ...) 934 return args[1:] 935} 936 937func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) { 938 a = args 939 name := s[2:] 940 if len(name) == 0 || name[0] == '-' || name[0] == '=' { 941 err = f.failf("bad flag syntax: %s", s) 942 return 943 } 944 945 split := strings.SplitN(name, "=", 2) 946 name = split[0] 947 flag, exists := f.formal[f.normalizeFlagName(name)] 948 949 if !exists { 950 switch { 951 case name == "help": 952 f.usage() 953 return a, ErrHelp 954 case f.ParseErrorsWhitelist.UnknownFlags: 955 // --unknown=unknownval arg ... 956 // we do not want to lose arg in this case 957 if len(split) >= 2 { 958 return a, nil 959 } 960 961 return stripUnknownFlagValue(a), nil 962 default: 963 err = f.failf("unknown flag: --%s", name) 964 return 965 } 966 } 967 968 var value string 969 if len(split) == 2 { 970 // '--flag=arg' 971 value = split[1] 972 } else if flag.NoOptDefVal != "" { 973 // '--flag' (arg was optional) 974 value = flag.NoOptDefVal 975 } else if len(a) > 0 { 976 // '--flag arg' 977 value = a[0] 978 a = a[1:] 979 } else { 980 // '--flag' (arg was required) 981 err = f.failf("flag needs an argument: %s", s) 982 return 983 } 984 985 err = fn(flag, value) 986 if err != nil { 987 f.failf(err.Error()) 988 } 989 return 990} 991 992func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) { 993 if strings.HasPrefix(shorthands, "test.") { 994 return 995 } 996 997 outArgs = args 998 outShorts = shorthands[1:] 999 c := shorthands[0] 1000 1001 flag, exists := f.shorthands[c] 1002 if !exists { 1003 switch { 1004 case c == 'h': 1005 f.usage() 1006 err = ErrHelp 1007 return 1008 case f.ParseErrorsWhitelist.UnknownFlags: 1009 // '-f=arg arg ...' 1010 // we do not want to lose arg in this case 1011 if len(shorthands) > 2 && shorthands[1] == '=' { 1012 outShorts = "" 1013 return 1014 } 1015 1016 outArgs = stripUnknownFlagValue(outArgs) 1017 return 1018 default: 1019 err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands) 1020 return 1021 } 1022 } 1023 1024 var value string 1025 if len(shorthands) > 2 && shorthands[1] == '=' { 1026 // '-f=arg' 1027 value = shorthands[2:] 1028 outShorts = "" 1029 } else if flag.NoOptDefVal != "" { 1030 // '-f' (arg was optional) 1031 value = flag.NoOptDefVal 1032 } else if len(shorthands) > 1 { 1033 // '-farg' 1034 value = shorthands[1:] 1035 outShorts = "" 1036 } else if len(args) > 0 { 1037 // '-f arg' 1038 value = args[0] 1039 outArgs = args[1:] 1040 } else { 1041 // '-f' (arg was required) 1042 err = f.failf("flag needs an argument: %q in -%s", c, shorthands) 1043 return 1044 } 1045 1046 if flag.ShorthandDeprecated != "" { 1047 fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) 1048 } 1049 1050 err = fn(flag, value) 1051 if err != nil { 1052 f.failf(err.Error()) 1053 } 1054 return 1055} 1056 1057func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) { 1058 a = args 1059 shorthands := s[1:] 1060 1061 // "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv"). 1062 for len(shorthands) > 0 { 1063 shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn) 1064 if err != nil { 1065 return 1066 } 1067 } 1068 1069 return 1070} 1071 1072func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) { 1073 for len(args) > 0 { 1074 s := args[0] 1075 args = args[1:] 1076 if len(s) == 0 || s[0] != '-' || len(s) == 1 { 1077 if !f.interspersed { 1078 f.args = append(f.args, s) 1079 f.args = append(f.args, args...) 1080 return nil 1081 } 1082 f.args = append(f.args, s) 1083 continue 1084 } 1085 1086 if s[1] == '-' { 1087 if len(s) == 2 { // "--" terminates the flags 1088 f.argsLenAtDash = len(f.args) 1089 f.args = append(f.args, args...) 1090 break 1091 } 1092 args, err = f.parseLongArg(s, args, fn) 1093 } else { 1094 args, err = f.parseShortArg(s, args, fn) 1095 } 1096 if err != nil { 1097 return 1098 } 1099 } 1100 return 1101} 1102 1103// Parse parses flag definitions from the argument list, which should not 1104// include the command name. Must be called after all flags in the FlagSet 1105// are defined and before flags are accessed by the program. 1106// The return value will be ErrHelp if -help was set but not defined. 1107func (f *FlagSet) Parse(arguments []string) error { 1108 if f.addedGoFlagSets != nil { 1109 for _, goFlagSet := range f.addedGoFlagSets { 1110 goFlagSet.Parse(nil) 1111 } 1112 } 1113 f.parsed = true 1114 1115 if len(arguments) < 0 { 1116 return nil 1117 } 1118 1119 f.args = make([]string, 0, len(arguments)) 1120 1121 set := func(flag *Flag, value string) error { 1122 return f.Set(flag.Name, value) 1123 } 1124 1125 err := f.parseArgs(arguments, set) 1126 if err != nil { 1127 switch f.errorHandling { 1128 case ContinueOnError: 1129 return err 1130 case ExitOnError: 1131 fmt.Println(err) 1132 os.Exit(2) 1133 case PanicOnError: 1134 panic(err) 1135 } 1136 } 1137 return nil 1138} 1139 1140type parseFunc func(flag *Flag, value string) error 1141 1142// ParseAll parses flag definitions from the argument list, which should not 1143// include the command name. The arguments for fn are flag and value. Must be 1144// called after all flags in the FlagSet are defined and before flags are 1145// accessed by the program. The return value will be ErrHelp if -help was set 1146// but not defined. 1147func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error { 1148 f.parsed = true 1149 f.args = make([]string, 0, len(arguments)) 1150 1151 err := f.parseArgs(arguments, fn) 1152 if err != nil { 1153 switch f.errorHandling { 1154 case ContinueOnError: 1155 return err 1156 case ExitOnError: 1157 os.Exit(2) 1158 case PanicOnError: 1159 panic(err) 1160 } 1161 } 1162 return nil 1163} 1164 1165// Parsed reports whether f.Parse has been called. 1166func (f *FlagSet) Parsed() bool { 1167 return f.parsed 1168} 1169 1170// Parse parses the command-line flags from os.Args[1:]. Must be called 1171// after all flags are defined and before flags are accessed by the program. 1172func Parse() { 1173 // Ignore errors; CommandLine is set for ExitOnError. 1174 CommandLine.Parse(os.Args[1:]) 1175} 1176 1177// ParseAll parses the command-line flags from os.Args[1:] and called fn for each. 1178// The arguments for fn are flag and value. Must be called after all flags are 1179// defined and before flags are accessed by the program. 1180func ParseAll(fn func(flag *Flag, value string) error) { 1181 // Ignore errors; CommandLine is set for ExitOnError. 1182 CommandLine.ParseAll(os.Args[1:], fn) 1183} 1184 1185// SetInterspersed sets whether to support interspersed option/non-option arguments. 1186func SetInterspersed(interspersed bool) { 1187 CommandLine.SetInterspersed(interspersed) 1188} 1189 1190// Parsed returns true if the command-line flags have been parsed. 1191func Parsed() bool { 1192 return CommandLine.Parsed() 1193} 1194 1195// CommandLine is the default set of command-line flags, parsed from os.Args. 1196var CommandLine = NewFlagSet(os.Args[0], ExitOnError) 1197 1198// NewFlagSet returns a new, empty flag set with the specified name, 1199// error handling property and SortFlags set to true. 1200func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { 1201 f := &FlagSet{ 1202 name: name, 1203 errorHandling: errorHandling, 1204 argsLenAtDash: -1, 1205 interspersed: true, 1206 SortFlags: true, 1207 } 1208 return f 1209} 1210 1211// SetInterspersed sets whether to support interspersed option/non-option arguments. 1212func (f *FlagSet) SetInterspersed(interspersed bool) { 1213 f.interspersed = interspersed 1214} 1215 1216// Init sets the name and error handling property for a flag set. 1217// By default, the zero FlagSet uses an empty name and the 1218// ContinueOnError error handling policy. 1219func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { 1220 f.name = name 1221 f.errorHandling = errorHandling 1222 f.argsLenAtDash = -1 1223} 1224