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