github.com/mheon/docker@v0.11.2-0.20150922122814-44f47903a831/pkg/mflag/flag.go (about) 1 // Copyright 2014-2015 The Docker & 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 // Package mflag implements command-line flag parsing. 6 // 7 // Usage: 8 // 9 // Define flags using flag.String(), Bool(), Int(), etc. 10 // 11 // This declares an integer flag, -f or --flagname, stored in the pointer ip, with type *int. 12 // import "flag /github.com/docker/docker/pkg/mflag" 13 // var ip = flag.Int([]string{"f", "-flagname"}, 1234, "help message for flagname") 14 // If you like, you can bind the flag to a variable using the Var() functions. 15 // var flagvar int 16 // func init() { 17 // // -flaghidden will work, but will be hidden from the usage 18 // flag.IntVar(&flagvar, []string{"f", "#flaghidden", "-flagname"}, 1234, "help message for flagname") 19 // } 20 // Or you can create custom flags that satisfy the Value interface (with 21 // pointer receivers) and couple them to flag parsing by 22 // flag.Var(&flagVal, []string{"name"}, "help message for flagname") 23 // For such flags, the default value is just the initial value of the variable. 24 // 25 // You can also add "deprecated" flags, they are still usable, but are not shown 26 // in the usage and will display a warning when you try to use them. `#` before 27 // an option means this option is deprecated, if there is an following option 28 // without `#` ahead, then that's the replacement, if not, it will just be removed: 29 // var ip = flag.Int([]string{"#f", "#flagname", "-flagname"}, 1234, "help message for flagname") 30 // this will display: `Warning: '-f' is deprecated, it will be replaced by '--flagname' soon. See usage.` or 31 // this will display: `Warning: '-flagname' is deprecated, it will be replaced by '--flagname' soon. See usage.` 32 // var ip = flag.Int([]string{"f", "#flagname"}, 1234, "help message for flagname") 33 // will display: `Warning: '-flagname' is deprecated, it will be removed soon. See usage.` 34 // so you can only use `-f`. 35 // 36 // You can also group one letter flags, bif you declare 37 // var v = flag.Bool([]string{"v", "-verbose"}, false, "help message for verbose") 38 // var s = flag.Bool([]string{"s", "-slow"}, false, "help message for slow") 39 // you will be able to use the -vs or -sv 40 // 41 // After all flags are defined, call 42 // flag.Parse() 43 // to parse the command line into the defined flags. 44 // 45 // Flags may then be used directly. If you're using the flags themselves, 46 // they 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 // 50 // After parsing, the arguments after the flag are available as the 51 // slice flag.Args() or individually as flag.Arg(i). 52 // The arguments are indexed from 0 through flag.NArg()-1. 53 // 54 // Command line flag syntax: 55 // -flag 56 // -flag=x 57 // -flag="x" 58 // -flag='x' 59 // -flag x // non-boolean flags only 60 // One or two minus signs may be used; they are equivalent. 61 // The last form is not permitted for boolean flags because the 62 // meaning of the command 63 // cmd -x * 64 // will change if there is a file called 0, false, etc. You must 65 // use the -flag=false form to turn off a boolean flag. 66 // 67 // Flag parsing stops just before the first non-flag argument 68 // ("-" is a non-flag argument) or after the terminator "--". 69 // 70 // Integer flags accept 1234, 0664, 0x1234 and may be negative. 71 // Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False. 72 // Duration flags accept any input valid for time.ParseDuration. 73 // 74 // The default set of command-line flags is controlled by 75 // top-level functions. The FlagSet type allows one to define 76 // independent sets of flags, such as to implement subcommands 77 // in a command-line interface. The methods of FlagSet are 78 // analogous to the top-level functions for the command-line 79 // flag set. 80 81 package mflag 82 83 import ( 84 "errors" 85 "fmt" 86 "io" 87 "os" 88 "runtime" 89 "sort" 90 "strconv" 91 "strings" 92 "text/tabwriter" 93 "time" 94 95 "github.com/docker/docker/pkg/homedir" 96 ) 97 98 // ErrHelp is the error returned if the flag -help is invoked but no such flag is defined. 99 var ErrHelp = errors.New("flag: help requested") 100 101 // ErrRetry is the error returned if you need to try letter by letter 102 var ErrRetry = errors.New("flag: retry") 103 104 // -- bool Value 105 type boolValue bool 106 107 func newBoolValue(val bool, p *bool) *boolValue { 108 *p = val 109 return (*boolValue)(p) 110 } 111 112 func (b *boolValue) Set(s string) error { 113 v, err := strconv.ParseBool(s) 114 *b = boolValue(v) 115 return err 116 } 117 118 func (b *boolValue) Get() interface{} { return bool(*b) } 119 120 func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) } 121 122 func (b *boolValue) IsBoolFlag() bool { return true } 123 124 // optional interface to indicate boolean flags that can be 125 // supplied without "=value" text 126 type boolFlag interface { 127 Value 128 IsBoolFlag() bool 129 } 130 131 // -- int Value 132 type intValue int 133 134 func newIntValue(val int, p *int) *intValue { 135 *p = val 136 return (*intValue)(p) 137 } 138 139 func (i *intValue) Set(s string) error { 140 v, err := strconv.ParseInt(s, 0, 64) 141 *i = intValue(v) 142 return err 143 } 144 145 func (i *intValue) Get() interface{} { return int(*i) } 146 147 func (i *intValue) String() string { return fmt.Sprintf("%v", *i) } 148 149 // -- int64 Value 150 type int64Value int64 151 152 func newInt64Value(val int64, p *int64) *int64Value { 153 *p = val 154 return (*int64Value)(p) 155 } 156 157 func (i *int64Value) Set(s string) error { 158 v, err := strconv.ParseInt(s, 0, 64) 159 *i = int64Value(v) 160 return err 161 } 162 163 func (i *int64Value) Get() interface{} { return int64(*i) } 164 165 func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) } 166 167 // -- uint Value 168 type uintValue uint 169 170 func newUintValue(val uint, p *uint) *uintValue { 171 *p = val 172 return (*uintValue)(p) 173 } 174 175 func (i *uintValue) Set(s string) error { 176 v, err := strconv.ParseUint(s, 0, 64) 177 *i = uintValue(v) 178 return err 179 } 180 181 func (i *uintValue) Get() interface{} { return uint(*i) } 182 183 func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) } 184 185 // -- uint64 Value 186 type uint64Value uint64 187 188 func newUint64Value(val uint64, p *uint64) *uint64Value { 189 *p = val 190 return (*uint64Value)(p) 191 } 192 193 func (i *uint64Value) Set(s string) error { 194 v, err := strconv.ParseUint(s, 0, 64) 195 *i = uint64Value(v) 196 return err 197 } 198 199 func (i *uint64Value) Get() interface{} { return uint64(*i) } 200 201 func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) } 202 203 // -- string Value 204 type stringValue string 205 206 func newStringValue(val string, p *string) *stringValue { 207 *p = val 208 return (*stringValue)(p) 209 } 210 211 func (s *stringValue) Set(val string) error { 212 *s = stringValue(val) 213 return nil 214 } 215 216 func (s *stringValue) Get() interface{} { return string(*s) } 217 218 func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) } 219 220 // -- float64 Value 221 type float64Value float64 222 223 func newFloat64Value(val float64, p *float64) *float64Value { 224 *p = val 225 return (*float64Value)(p) 226 } 227 228 func (f *float64Value) Set(s string) error { 229 v, err := strconv.ParseFloat(s, 64) 230 *f = float64Value(v) 231 return err 232 } 233 234 func (f *float64Value) Get() interface{} { return float64(*f) } 235 236 func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) } 237 238 // -- time.Duration Value 239 type durationValue time.Duration 240 241 func newDurationValue(val time.Duration, p *time.Duration) *durationValue { 242 *p = val 243 return (*durationValue)(p) 244 } 245 246 func (d *durationValue) Set(s string) error { 247 v, err := time.ParseDuration(s) 248 *d = durationValue(v) 249 return err 250 } 251 252 func (d *durationValue) Get() interface{} { return time.Duration(*d) } 253 254 func (d *durationValue) String() string { return (*time.Duration)(d).String() } 255 256 // Value is the interface to the dynamic value stored in a flag. 257 // (The default value is represented as a string.) 258 // 259 // If a Value has an IsBoolFlag() bool method returning true, 260 // the command-line parser makes -name equivalent to -name=true 261 // rather than using the next command-line argument. 262 type Value interface { 263 String() string 264 Set(string) error 265 } 266 267 // Getter is an interface that allows the contents of a Value to be retrieved. 268 // It wraps the Value interface, rather than being part of it, because it 269 // appeared after Go 1 and its compatibility rules. All Value types provided 270 // by this package satisfy the Getter interface. 271 type Getter interface { 272 Value 273 Get() interface{} 274 } 275 276 // ErrorHandling defines how to handle flag parsing errors. 277 type ErrorHandling int 278 279 // ErrorHandling strategies available when a flag parsing error occurs 280 const ( 281 ContinueOnError ErrorHandling = iota 282 ExitOnError 283 PanicOnError 284 ) 285 286 // A FlagSet represents a set of defined flags. The zero value of a FlagSet 287 // has no name and has ContinueOnError error handling. 288 type FlagSet struct { 289 // Usage is the function called when an error occurs while parsing flags. 290 // The field is a function (not a method) that may be changed to point to 291 // a custom error handler. 292 Usage func() 293 ShortUsage func() 294 295 name string 296 parsed bool 297 actual map[string]*Flag 298 formal map[string]*Flag 299 args []string // arguments after flags 300 errorHandling ErrorHandling 301 output io.Writer // nil means stderr; use Out() accessor 302 nArgRequirements []nArgRequirement 303 } 304 305 // A Flag represents the state of a flag. 306 type Flag struct { 307 Names []string // name as it appears on command line 308 Usage string // help message 309 Value Value // value as set 310 DefValue string // default value (as text); for usage message 311 } 312 313 type flagSlice []string 314 315 func (p flagSlice) Len() int { return len(p) } 316 func (p flagSlice) Less(i, j int) bool { 317 pi, pj := strings.TrimPrefix(p[i], "-"), strings.TrimPrefix(p[j], "-") 318 lpi, lpj := strings.ToLower(pi), strings.ToLower(pj) 319 if lpi != lpj { 320 return lpi < lpj 321 } 322 return pi < pj 323 } 324 func (p flagSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 325 326 // sortFlags returns the flags as a slice in lexicographical sorted order. 327 func sortFlags(flags map[string]*Flag) []*Flag { 328 var list flagSlice 329 330 // The sorted list is based on the first name, when flag map might use the other names. 331 nameMap := make(map[string]string) 332 333 for n, f := range flags { 334 fName := strings.TrimPrefix(f.Names[0], "#") 335 nameMap[fName] = n 336 if len(f.Names) == 1 { 337 list = append(list, fName) 338 continue 339 } 340 341 found := false 342 for _, name := range list { 343 if name == fName { 344 found = true 345 break 346 } 347 } 348 if !found { 349 list = append(list, fName) 350 } 351 } 352 sort.Sort(list) 353 result := make([]*Flag, len(list)) 354 for i, name := range list { 355 result[i] = flags[nameMap[name]] 356 } 357 return result 358 } 359 360 // Name returns the name of the FlagSet. 361 func (fs *FlagSet) Name() string { 362 return fs.name 363 } 364 365 // Out returns the destination for usage and error messages. 366 func (fs *FlagSet) Out() io.Writer { 367 if fs.output == nil { 368 return os.Stderr 369 } 370 return fs.output 371 } 372 373 // SetOutput sets the destination for usage and error messages. 374 // If output is nil, os.Stderr is used. 375 func (fs *FlagSet) SetOutput(output io.Writer) { 376 fs.output = output 377 } 378 379 // VisitAll visits the flags in lexicographical order, calling fn for each. 380 // It visits all flags, even those not set. 381 func (fs *FlagSet) VisitAll(fn func(*Flag)) { 382 for _, flag := range sortFlags(fs.formal) { 383 fn(flag) 384 } 385 } 386 387 // VisitAll visits the command-line flags in lexicographical order, calling 388 // fn for each. It visits all flags, even those not set. 389 func VisitAll(fn func(*Flag)) { 390 CommandLine.VisitAll(fn) 391 } 392 393 // Visit visits the flags in lexicographical order, calling fn for each. 394 // It visits only those flags that have been set. 395 func (fs *FlagSet) Visit(fn func(*Flag)) { 396 for _, flag := range sortFlags(fs.actual) { 397 fn(flag) 398 } 399 } 400 401 // Visit visits the command-line flags in lexicographical order, calling fn 402 // for each. It visits only those flags that have been set. 403 func Visit(fn func(*Flag)) { 404 CommandLine.Visit(fn) 405 } 406 407 // Lookup returns the Flag structure of the named flag, returning nil if none exists. 408 func (fs *FlagSet) Lookup(name string) *Flag { 409 return fs.formal[name] 410 } 411 412 // IsSet indicates whether the specified flag is set in the given FlagSet 413 func (fs *FlagSet) IsSet(name string) bool { 414 return fs.actual[name] != nil 415 } 416 417 // Lookup returns the Flag structure of the named command-line flag, 418 // returning nil if none exists. 419 func Lookup(name string) *Flag { 420 return CommandLine.formal[name] 421 } 422 423 // IsSet indicates whether the specified flag was specified at all on the cmd line. 424 func IsSet(name string) bool { 425 return CommandLine.IsSet(name) 426 } 427 428 type nArgRequirementType int 429 430 // Indicator used to pass to BadArgs function 431 const ( 432 Exact nArgRequirementType = iota 433 Max 434 Min 435 ) 436 437 type nArgRequirement struct { 438 Type nArgRequirementType 439 N int 440 } 441 442 // Require adds a requirement about the number of arguments for the FlagSet. 443 // The first parameter can be Exact, Max, or Min to respectively specify the exact, 444 // the maximum, or the minimal number of arguments required. 445 // The actual check is done in FlagSet.CheckArgs(). 446 func (fs *FlagSet) Require(nArgRequirementType nArgRequirementType, nArg int) { 447 fs.nArgRequirements = append(fs.nArgRequirements, nArgRequirement{nArgRequirementType, nArg}) 448 } 449 450 // CheckArgs uses the requirements set by FlagSet.Require() to validate 451 // the number of arguments. If the requirements are not met, 452 // an error message string is returned. 453 func (fs *FlagSet) CheckArgs() (message string) { 454 for _, req := range fs.nArgRequirements { 455 var arguments string 456 if req.N == 1 { 457 arguments = "1 argument" 458 } else { 459 arguments = fmt.Sprintf("%d arguments", req.N) 460 } 461 462 str := func(kind string) string { 463 return fmt.Sprintf("%q requires %s%s", fs.name, kind, arguments) 464 } 465 466 switch req.Type { 467 case Exact: 468 if fs.NArg() != req.N { 469 return str("") 470 } 471 case Max: 472 if fs.NArg() > req.N { 473 return str("a maximum of ") 474 } 475 case Min: 476 if fs.NArg() < req.N { 477 return str("a minimum of ") 478 } 479 } 480 } 481 return "" 482 } 483 484 // Set sets the value of the named flag. 485 func (fs *FlagSet) Set(name, value string) error { 486 flag, ok := fs.formal[name] 487 if !ok { 488 return fmt.Errorf("no such flag -%v", name) 489 } 490 if err := flag.Value.Set(value); err != nil { 491 return err 492 } 493 if fs.actual == nil { 494 fs.actual = make(map[string]*Flag) 495 } 496 fs.actual[name] = flag 497 return nil 498 } 499 500 // Set sets the value of the named command-line flag. 501 func Set(name, value string) error { 502 return CommandLine.Set(name, value) 503 } 504 505 // PrintDefaults prints, to standard error unless configured 506 // otherwise, the default values of all defined flags in the set. 507 func (fs *FlagSet) PrintDefaults() { 508 writer := tabwriter.NewWriter(fs.Out(), 20, 1, 3, ' ', 0) 509 home := homedir.Get() 510 511 // Don't substitute when HOME is / 512 if runtime.GOOS != "windows" && home == "/" { 513 home = "" 514 } 515 516 // Add a blank line between cmd description and list of options 517 if fs.FlagCount() > 0 { 518 fmt.Fprintln(writer, "") 519 } 520 521 fs.VisitAll(func(flag *Flag) { 522 format := " -%s=%s" 523 names := []string{} 524 for _, name := range flag.Names { 525 if name[0] != '#' { 526 names = append(names, name) 527 } 528 } 529 if len(names) > 0 && len(flag.Usage) > 0 { 530 val := flag.DefValue 531 532 if home != "" && strings.HasPrefix(val, home) { 533 val = homedir.GetShortcutString() + val[len(home):] 534 } 535 536 fmt.Fprintf(writer, format, strings.Join(names, ", -"), val) 537 for i, line := range strings.Split(flag.Usage, "\n") { 538 if i != 0 { 539 line = " " + line 540 } 541 fmt.Fprintln(writer, "\t", line) 542 } 543 } 544 }) 545 writer.Flush() 546 } 547 548 // PrintDefaults prints to standard error the default values of all defined command-line flags. 549 func PrintDefaults() { 550 CommandLine.PrintDefaults() 551 } 552 553 // defaultUsage is the default function to print a usage message. 554 func defaultUsage(fs *FlagSet) { 555 if fs.name == "" { 556 fmt.Fprintf(fs.Out(), "Usage:\n") 557 } else { 558 fmt.Fprintf(fs.Out(), "Usage of %s:\n", fs.name) 559 } 560 fs.PrintDefaults() 561 } 562 563 // NOTE: Usage is not just defaultUsage(CommandLine) 564 // because it serves (via godoc flag Usage) as the example 565 // for how to write your own usage function. 566 567 // Usage prints to standard error a usage message documenting all defined command-line flags. 568 // The function is a variable that may be changed to point to a custom function. 569 var Usage = func() { 570 fmt.Fprintf(CommandLine.Out(), "Usage of %s:\n", os.Args[0]) 571 PrintDefaults() 572 } 573 574 // Usage prints to standard error a usage message documenting the standard command layout 575 // The function is a variable that may be changed to point to a custom function. 576 var ShortUsage = func() { 577 fmt.Fprintf(CommandLine.output, "Usage of %s:\n", os.Args[0]) 578 } 579 580 // FlagCount returns the number of flags that have been defined. 581 func (fs *FlagSet) FlagCount() int { return len(sortFlags(fs.formal)) } 582 583 // FlagCountUndeprecated returns the number of undeprecated flags that have been defined. 584 func (fs *FlagSet) FlagCountUndeprecated() int { 585 count := 0 586 for _, flag := range sortFlags(fs.formal) { 587 for _, name := range flag.Names { 588 if name[0] != '#' { 589 count++ 590 break 591 } 592 } 593 } 594 return count 595 } 596 597 // NFlag returns the number of flags that have been set. 598 func (fs *FlagSet) NFlag() int { return len(fs.actual) } 599 600 // NFlag returns the number of command-line flags that have been set. 601 func NFlag() int { return len(CommandLine.actual) } 602 603 // Arg returns the i'th argument. Arg(0) is the first remaining argument 604 // after flags have been processed. 605 func (fs *FlagSet) Arg(i int) string { 606 if i < 0 || i >= len(fs.args) { 607 return "" 608 } 609 return fs.args[i] 610 } 611 612 // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument 613 // after flags have been processed. 614 func Arg(i int) string { 615 return CommandLine.Arg(i) 616 } 617 618 // NArg is the number of arguments remaining after flags have been processed. 619 func (fs *FlagSet) NArg() int { return len(fs.args) } 620 621 // NArg is the number of arguments remaining after flags have been processed. 622 func NArg() int { return len(CommandLine.args) } 623 624 // Args returns the non-flag arguments. 625 func (fs *FlagSet) Args() []string { return fs.args } 626 627 // Args returns the non-flag command-line arguments. 628 func Args() []string { return CommandLine.args } 629 630 // BoolVar defines a bool flag with specified name, default value, and usage string. 631 // The argument p points to a bool variable in which to store the value of the flag. 632 func (fs *FlagSet) BoolVar(p *bool, names []string, value bool, usage string) { 633 fs.Var(newBoolValue(value, p), names, usage) 634 } 635 636 // BoolVar defines a bool flag with specified name, default value, and usage string. 637 // The argument p points to a bool variable in which to store the value of the flag. 638 func BoolVar(p *bool, names []string, value bool, usage string) { 639 CommandLine.Var(newBoolValue(value, p), names, usage) 640 } 641 642 // Bool defines a bool flag with specified name, default value, and usage string. 643 // The return value is the address of a bool variable that stores the value of the flag. 644 func (fs *FlagSet) Bool(names []string, value bool, usage string) *bool { 645 p := new(bool) 646 fs.BoolVar(p, names, value, usage) 647 return p 648 } 649 650 // Bool defines a bool flag with specified name, default value, and usage string. 651 // The return value is the address of a bool variable that stores the value of the flag. 652 func Bool(names []string, value bool, usage string) *bool { 653 return CommandLine.Bool(names, value, usage) 654 } 655 656 // IntVar defines an int flag with specified name, default value, and usage string. 657 // The argument p points to an int variable in which to store the value of the flag. 658 func (fs *FlagSet) IntVar(p *int, names []string, value int, usage string) { 659 fs.Var(newIntValue(value, p), names, usage) 660 } 661 662 // IntVar defines an int flag with specified name, default value, and usage string. 663 // The argument p points to an int variable in which to store the value of the flag. 664 func IntVar(p *int, names []string, value int, usage string) { 665 CommandLine.Var(newIntValue(value, p), names, usage) 666 } 667 668 // Int defines an int flag with specified name, default value, and usage string. 669 // The return value is the address of an int variable that stores the value of the flag. 670 func (fs *FlagSet) Int(names []string, value int, usage string) *int { 671 p := new(int) 672 fs.IntVar(p, names, value, usage) 673 return p 674 } 675 676 // Int defines an int flag with specified name, default value, and usage string. 677 // The return value is the address of an int variable that stores the value of the flag. 678 func Int(names []string, value int, usage string) *int { 679 return CommandLine.Int(names, value, usage) 680 } 681 682 // Int64Var defines an int64 flag with specified name, default value, and usage string. 683 // The argument p points to an int64 variable in which to store the value of the flag. 684 func (fs *FlagSet) Int64Var(p *int64, names []string, value int64, usage string) { 685 fs.Var(newInt64Value(value, p), names, usage) 686 } 687 688 // Int64Var defines an int64 flag with specified name, default value, and usage string. 689 // The argument p points to an int64 variable in which to store the value of the flag. 690 func Int64Var(p *int64, names []string, value int64, usage string) { 691 CommandLine.Var(newInt64Value(value, p), names, usage) 692 } 693 694 // Int64 defines an int64 flag with specified name, default value, and usage string. 695 // The return value is the address of an int64 variable that stores the value of the flag. 696 func (fs *FlagSet) Int64(names []string, value int64, usage string) *int64 { 697 p := new(int64) 698 fs.Int64Var(p, names, value, usage) 699 return p 700 } 701 702 // Int64 defines an int64 flag with specified name, default value, and usage string. 703 // The return value is the address of an int64 variable that stores the value of the flag. 704 func Int64(names []string, value int64, usage string) *int64 { 705 return CommandLine.Int64(names, value, usage) 706 } 707 708 // UintVar defines a uint flag with specified name, default value, and usage string. 709 // The argument p points to a uint variable in which to store the value of the flag. 710 func (fs *FlagSet) UintVar(p *uint, names []string, value uint, usage string) { 711 fs.Var(newUintValue(value, p), names, usage) 712 } 713 714 // UintVar defines a uint flag with specified name, default value, and usage string. 715 // The argument p points to a uint variable in which to store the value of the flag. 716 func UintVar(p *uint, names []string, value uint, usage string) { 717 CommandLine.Var(newUintValue(value, p), names, usage) 718 } 719 720 // Uint defines a uint flag with specified name, default value, and usage string. 721 // The return value is the address of a uint variable that stores the value of the flag. 722 func (fs *FlagSet) Uint(names []string, value uint, usage string) *uint { 723 p := new(uint) 724 fs.UintVar(p, names, value, usage) 725 return p 726 } 727 728 // Uint defines a uint flag with specified name, default value, and usage string. 729 // The return value is the address of a uint variable that stores the value of the flag. 730 func Uint(names []string, value uint, usage string) *uint { 731 return CommandLine.Uint(names, value, usage) 732 } 733 734 // Uint64Var defines a uint64 flag with specified name, default value, and usage string. 735 // The argument p points to a uint64 variable in which to store the value of the flag. 736 func (fs *FlagSet) Uint64Var(p *uint64, names []string, value uint64, usage string) { 737 fs.Var(newUint64Value(value, p), names, usage) 738 } 739 740 // Uint64Var defines a uint64 flag with specified name, default value, and usage string. 741 // The argument p points to a uint64 variable in which to store the value of the flag. 742 func Uint64Var(p *uint64, names []string, value uint64, usage string) { 743 CommandLine.Var(newUint64Value(value, p), names, usage) 744 } 745 746 // Uint64 defines a uint64 flag with specified name, default value, and usage string. 747 // The return value is the address of a uint64 variable that stores the value of the flag. 748 func (fs *FlagSet) Uint64(names []string, value uint64, usage string) *uint64 { 749 p := new(uint64) 750 fs.Uint64Var(p, names, value, usage) 751 return p 752 } 753 754 // Uint64 defines a uint64 flag with specified name, default value, and usage string. 755 // The return value is the address of a uint64 variable that stores the value of the flag. 756 func Uint64(names []string, value uint64, usage string) *uint64 { 757 return CommandLine.Uint64(names, value, usage) 758 } 759 760 // StringVar defines a string flag with specified name, default value, and usage string. 761 // The argument p points to a string variable in which to store the value of the flag. 762 func (fs *FlagSet) StringVar(p *string, names []string, value string, usage string) { 763 fs.Var(newStringValue(value, p), names, usage) 764 } 765 766 // StringVar defines a string flag with specified name, default value, and usage string. 767 // The argument p points to a string variable in which to store the value of the flag. 768 func StringVar(p *string, names []string, value string, usage string) { 769 CommandLine.Var(newStringValue(value, p), names, usage) 770 } 771 772 // String defines a string flag with specified name, default value, and usage string. 773 // The return value is the address of a string variable that stores the value of the flag. 774 func (fs *FlagSet) String(names []string, value string, usage string) *string { 775 p := new(string) 776 fs.StringVar(p, names, value, usage) 777 return p 778 } 779 780 // String defines a string flag with specified name, default value, and usage string. 781 // The return value is the address of a string variable that stores the value of the flag. 782 func String(names []string, value string, usage string) *string { 783 return CommandLine.String(names, value, usage) 784 } 785 786 // Float64Var defines a float64 flag with specified name, default value, and usage string. 787 // The argument p points to a float64 variable in which to store the value of the flag. 788 func (fs *FlagSet) Float64Var(p *float64, names []string, value float64, usage string) { 789 fs.Var(newFloat64Value(value, p), names, usage) 790 } 791 792 // Float64Var defines a float64 flag with specified name, default value, and usage string. 793 // The argument p points to a float64 variable in which to store the value of the flag. 794 func Float64Var(p *float64, names []string, value float64, usage string) { 795 CommandLine.Var(newFloat64Value(value, p), names, usage) 796 } 797 798 // Float64 defines a float64 flag with specified name, default value, and usage string. 799 // The return value is the address of a float64 variable that stores the value of the flag. 800 func (fs *FlagSet) Float64(names []string, value float64, usage string) *float64 { 801 p := new(float64) 802 fs.Float64Var(p, names, value, usage) 803 return p 804 } 805 806 // Float64 defines a float64 flag with specified name, default value, and usage string. 807 // The return value is the address of a float64 variable that stores the value of the flag. 808 func Float64(names []string, value float64, usage string) *float64 { 809 return CommandLine.Float64(names, value, usage) 810 } 811 812 // DurationVar defines a time.Duration flag with specified name, default value, and usage string. 813 // The argument p points to a time.Duration variable in which to store the value of the flag. 814 func (fs *FlagSet) DurationVar(p *time.Duration, names []string, value time.Duration, usage string) { 815 fs.Var(newDurationValue(value, p), names, usage) 816 } 817 818 // DurationVar defines a time.Duration flag with specified name, default value, and usage string. 819 // The argument p points to a time.Duration variable in which to store the value of the flag. 820 func DurationVar(p *time.Duration, names []string, value time.Duration, usage string) { 821 CommandLine.Var(newDurationValue(value, p), names, usage) 822 } 823 824 // Duration defines a time.Duration flag with specified name, default value, and usage string. 825 // The return value is the address of a time.Duration variable that stores the value of the flag. 826 func (fs *FlagSet) Duration(names []string, value time.Duration, usage string) *time.Duration { 827 p := new(time.Duration) 828 fs.DurationVar(p, names, value, usage) 829 return p 830 } 831 832 // Duration defines a time.Duration flag with specified name, default value, and usage string. 833 // The return value is the address of a time.Duration variable that stores the value of the flag. 834 func Duration(names []string, value time.Duration, usage string) *time.Duration { 835 return CommandLine.Duration(names, value, usage) 836 } 837 838 // Var defines a flag with the specified name and usage string. The type and 839 // value of the flag are represented by the first argument, of type Value, which 840 // typically holds a user-defined implementation of Value. For instance, the 841 // caller could create a flag that turns a comma-separated string into a slice 842 // of strings by giving the slice the methods of Value; in particular, Set would 843 // decompose the comma-separated string into the slice. 844 func (fs *FlagSet) Var(value Value, names []string, usage string) { 845 // Remember the default value as a string; it won't change. 846 flag := &Flag{names, usage, value, value.String()} 847 for _, name := range names { 848 name = strings.TrimPrefix(name, "#") 849 _, alreadythere := fs.formal[name] 850 if alreadythere { 851 var msg string 852 if fs.name == "" { 853 msg = fmt.Sprintf("flag redefined: %s", name) 854 } else { 855 msg = fmt.Sprintf("%s flag redefined: %s", fs.name, name) 856 } 857 fmt.Fprintln(fs.Out(), msg) 858 panic(msg) // Happens only if flags are declared with identical names 859 } 860 if fs.formal == nil { 861 fs.formal = make(map[string]*Flag) 862 } 863 fs.formal[name] = flag 864 } 865 } 866 867 // Var defines a flag with the specified name and usage string. The type and 868 // value of the flag are represented by the first argument, of type Value, which 869 // typically holds a user-defined implementation of Value. For instance, the 870 // caller could create a flag that turns a comma-separated string into a slice 871 // of strings by giving the slice the methods of Value; in particular, Set would 872 // decompose the comma-separated string into the slice. 873 func Var(value Value, names []string, usage string) { 874 CommandLine.Var(value, names, usage) 875 } 876 877 // failf prints to standard error a formatted error and usage message and 878 // returns the error. 879 func (fs *FlagSet) failf(format string, a ...interface{}) error { 880 err := fmt.Errorf(format, a...) 881 fmt.Fprintln(fs.Out(), err) 882 if os.Args[0] == fs.name { 883 fmt.Fprintf(fs.Out(), "See '%s --help'.\n", os.Args[0]) 884 } else { 885 fmt.Fprintf(fs.Out(), "See '%s %s --help'.\n", os.Args[0], fs.name) 886 } 887 return err 888 } 889 890 // usage calls the Usage method for the flag set, or the usage function if 891 // the flag set is CommandLine. 892 func (fs *FlagSet) usage() { 893 if fs == CommandLine { 894 Usage() 895 } else if fs.Usage == nil { 896 defaultUsage(fs) 897 } else { 898 fs.Usage() 899 } 900 } 901 902 func trimQuotes(str string) string { 903 if len(str) == 0 { 904 return str 905 } 906 type quote struct { 907 start, end byte 908 } 909 910 // All valid quote types. 911 quotes := []quote{ 912 // Double quotes 913 { 914 start: '"', 915 end: '"', 916 }, 917 918 // Single quotes 919 { 920 start: '\'', 921 end: '\'', 922 }, 923 } 924 925 for _, quote := range quotes { 926 // Only strip if outermost match. 927 if str[0] == quote.start && str[len(str)-1] == quote.end { 928 str = str[1 : len(str)-1] 929 break 930 } 931 } 932 933 return str 934 } 935 936 // parseOne parses one flag. It reports whether a flag was seen. 937 func (fs *FlagSet) parseOne() (bool, string, error) { 938 if len(fs.args) == 0 { 939 return false, "", nil 940 } 941 s := fs.args[0] 942 if len(s) == 0 || s[0] != '-' || len(s) == 1 { 943 return false, "", nil 944 } 945 if s[1] == '-' && len(s) == 2 { // "--" terminates the flags 946 fs.args = fs.args[1:] 947 return false, "", nil 948 } 949 name := s[1:] 950 if len(name) == 0 || name[0] == '=' { 951 return false, "", fs.failf("bad flag syntax: %s", s) 952 } 953 954 // it's a flag. does it have an argument? 955 fs.args = fs.args[1:] 956 hasValue := false 957 value := "" 958 if i := strings.Index(name, "="); i != -1 { 959 value = trimQuotes(name[i+1:]) 960 hasValue = true 961 name = name[:i] 962 } 963 964 m := fs.formal 965 flag, alreadythere := m[name] // BUG 966 if !alreadythere { 967 if name == "-help" || name == "help" || name == "h" { // special case for nice help message. 968 fs.usage() 969 return false, "", ErrHelp 970 } 971 if len(name) > 0 && name[0] == '-' { 972 return false, "", fs.failf("flag provided but not defined: -%s", name) 973 } 974 return false, name, ErrRetry 975 } 976 if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg 977 if hasValue { 978 if err := fv.Set(value); err != nil { 979 return false, "", fs.failf("invalid boolean value %q for -%s: %v", value, name, err) 980 } 981 } else { 982 fv.Set("true") 983 } 984 } else { 985 // It must have a value, which might be the next argument. 986 if !hasValue && len(fs.args) > 0 { 987 // value is the next arg 988 hasValue = true 989 value, fs.args = fs.args[0], fs.args[1:] 990 } 991 if !hasValue { 992 return false, "", fs.failf("flag needs an argument: -%s", name) 993 } 994 if err := flag.Value.Set(value); err != nil { 995 return false, "", fs.failf("invalid value %q for flag -%s: %v", value, name, err) 996 } 997 } 998 if fs.actual == nil { 999 fs.actual = make(map[string]*Flag) 1000 } 1001 fs.actual[name] = flag 1002 for i, n := range flag.Names { 1003 if n == fmt.Sprintf("#%s", name) { 1004 replacement := "" 1005 for j := i; j < len(flag.Names); j++ { 1006 if flag.Names[j][0] != '#' { 1007 replacement = flag.Names[j] 1008 break 1009 } 1010 } 1011 if replacement != "" { 1012 fmt.Fprintf(fs.Out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement) 1013 } else { 1014 fmt.Fprintf(fs.Out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name) 1015 } 1016 } 1017 } 1018 return true, "", nil 1019 } 1020 1021 // Parse parses flag definitions from the argument list, which should not 1022 // include the command name. Must be called after all flags in the FlagSet 1023 // are defined and before flags are accessed by the program. 1024 // The return value will be ErrHelp if -help was set but not defined. 1025 func (fs *FlagSet) Parse(arguments []string) error { 1026 fs.parsed = true 1027 fs.args = arguments 1028 for { 1029 seen, name, err := fs.parseOne() 1030 if seen { 1031 continue 1032 } 1033 if err == nil { 1034 break 1035 } 1036 if err == ErrRetry { 1037 if len(name) > 1 { 1038 err = nil 1039 for _, letter := range strings.Split(name, "") { 1040 fs.args = append([]string{"-" + letter}, fs.args...) 1041 seen2, _, err2 := fs.parseOne() 1042 if seen2 { 1043 continue 1044 } 1045 if err2 != nil { 1046 err = fs.failf("flag provided but not defined: -%s", name) 1047 break 1048 } 1049 } 1050 if err == nil { 1051 continue 1052 } 1053 } else { 1054 err = fs.failf("flag provided but not defined: -%s", name) 1055 } 1056 } 1057 switch fs.errorHandling { 1058 case ContinueOnError: 1059 return err 1060 case ExitOnError: 1061 os.Exit(2) 1062 case PanicOnError: 1063 panic(err) 1064 } 1065 } 1066 return nil 1067 } 1068 1069 // ParseFlags is a utility function that adds a help flag if withHelp is true, 1070 // calls fs.Parse(args) and prints a relevant error message if there are 1071 // incorrect number of arguments. It returns error only if error handling is 1072 // set to ContinueOnError and parsing fails. If error handling is set to 1073 // ExitOnError, it's safe to ignore the return value. 1074 func (fs *FlagSet) ParseFlags(args []string, withHelp bool) error { 1075 var help *bool 1076 if withHelp { 1077 help = fs.Bool([]string{"#help", "-help"}, false, "Print usage") 1078 } 1079 if err := fs.Parse(args); err != nil { 1080 return err 1081 } 1082 if help != nil && *help { 1083 fs.SetOutput(os.Stdout) 1084 fs.Usage() 1085 os.Exit(0) 1086 } 1087 if str := fs.CheckArgs(); str != "" { 1088 fs.SetOutput(os.Stderr) 1089 fs.ReportError(str, withHelp) 1090 fs.ShortUsage() 1091 os.Exit(1) 1092 } 1093 return nil 1094 } 1095 1096 // ReportError is a utility method that prints a user-friendly message 1097 // containing the error that occurred during parsing and a suggestion to get help 1098 func (fs *FlagSet) ReportError(str string, withHelp bool) { 1099 if withHelp { 1100 if os.Args[0] == fs.Name() { 1101 str += ".\nSee '" + os.Args[0] + " --help'" 1102 } else { 1103 str += ".\nSee '" + os.Args[0] + " " + fs.Name() + " --help'" 1104 } 1105 } 1106 fmt.Fprintf(fs.Out(), "docker: %s.\n", str) 1107 } 1108 1109 // Parsed reports whether fs.Parse has been called. 1110 func (fs *FlagSet) Parsed() bool { 1111 return fs.parsed 1112 } 1113 1114 // Parse parses the command-line flags from os.Args[1:]. Must be called 1115 // after all flags are defined and before flags are accessed by the program. 1116 func Parse() { 1117 // Ignore errors; CommandLine is set for ExitOnError. 1118 CommandLine.Parse(os.Args[1:]) 1119 } 1120 1121 // Parsed returns true if the command-line flags have been parsed. 1122 func Parsed() bool { 1123 return CommandLine.Parsed() 1124 } 1125 1126 // CommandLine is the default set of command-line flags, parsed from os.Args. 1127 // The top-level functions such as BoolVar, Arg, and on are wrappers for the 1128 // methods of CommandLine. 1129 var CommandLine = NewFlagSet(os.Args[0], ExitOnError) 1130 1131 // NewFlagSet returns a new, empty flag set with the specified name and 1132 // error handling property. 1133 func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { 1134 f := &FlagSet{ 1135 name: name, 1136 errorHandling: errorHandling, 1137 } 1138 return f 1139 } 1140 1141 // Init sets the name and error handling property for a flag set. 1142 // By default, the zero FlagSet uses an empty name and the 1143 // ContinueOnError error handling policy. 1144 func (fs *FlagSet) Init(name string, errorHandling ErrorHandling) { 1145 fs.name = name 1146 fs.errorHandling = errorHandling 1147 } 1148 1149 type mergeVal struct { 1150 Value 1151 key string 1152 fset *FlagSet 1153 } 1154 1155 func (v mergeVal) Set(s string) error { 1156 return v.fset.Set(v.key, s) 1157 } 1158 1159 func (v mergeVal) IsBoolFlag() bool { 1160 if b, ok := v.Value.(boolFlag); ok { 1161 return b.IsBoolFlag() 1162 } 1163 return false 1164 } 1165 1166 // Merge is an helper function that merges n FlagSets into a single dest FlagSet 1167 // In case of name collision between the flagsets it will apply 1168 // the destination FlagSet's errorHandling behaviour. 1169 func Merge(dest *FlagSet, flagsets ...*FlagSet) error { 1170 for _, fset := range flagsets { 1171 for k, f := range fset.formal { 1172 if _, ok := dest.formal[k]; ok { 1173 var err error 1174 if fset.name == "" { 1175 err = fmt.Errorf("flag redefined: %s", k) 1176 } else { 1177 err = fmt.Errorf("%s flag redefined: %s", fset.name, k) 1178 } 1179 fmt.Fprintln(fset.Out(), err.Error()) 1180 // Happens only if flags are declared with identical names 1181 switch dest.errorHandling { 1182 case ContinueOnError: 1183 return err 1184 case ExitOnError: 1185 os.Exit(2) 1186 case PanicOnError: 1187 panic(err) 1188 } 1189 } 1190 newF := *f 1191 newF.Value = mergeVal{f.Value, k, fset} 1192 dest.formal[k] = &newF 1193 } 1194 } 1195 return nil 1196 } 1197 1198 // IsEmpty reports if the FlagSet is actually empty. 1199 func (fs *FlagSet) IsEmpty() bool { 1200 return len(fs.actual) == 0 1201 }