podman

Форк
0
1239 строк · 35.5 Кб
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
/*
6
Package pflag is a drop-in replacement for Go's flag package, implementing
7
POSIX/GNU-style --flags.
8

9
pflag is compatible with the GNU extensions to the POSIX recommendations
10
for command-line options. See
11
http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
12

13
Usage:
14

15
pflag is a drop-in replacement of Go's native flag package. If you import
16
pflag under the name "flag" then all code should continue to function
17
with no changes.
18

19
	import flag "github.com/spf13/pflag"
20

21
There is one exception to this: if you directly instantiate the Flag struct
22
there is one more field "Shorthand" that you will need to set.
23
Most code never instantiates this struct directly, and instead uses
24
functions such as String(), BoolVar(), and Var(), and is therefore
25
unaffected.
26

27
Define flags using flag.String(), Bool(), Int(), etc.
28

29
This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
30
	var ip = flag.Int("flagname", 1234, "help message for flagname")
31
If 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
	}
36
Or you can create custom flags that satisfy the Value interface (with
37
pointer receivers) and couple them to flag parsing by
38
	flag.Var(&flagVal, "name", "help message for flagname")
39
For such flags, the default value is just the initial value of the variable.
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
The pflag package also defines some new functions that are not in flag,
55
that give one-letter shorthands for flags. You can use these by appending
56
'P' to the name of any function that defines a flag.
57
	var ip = flag.IntP("flagname", "f", 1234, "help message")
58
	var flagvar bool
59
	func init() {
60
		flag.BoolVarP(&flagvar, "boolname", "b", true, "help message")
61
	}
62
	flag.VarP(&flagval, "varname", "v", "help message")
63
Shorthand letters can be used with single dashes on the command line.
64
Boolean shorthand flags can be combined with other shorthand flags.
65

66
Command line flag syntax:
67
	--flag    // boolean flags only
68
	--flag=x
69

70
Unlike the flag package, a single dash before an option means something
71
different than a double dash. Single dashes signify a series of shorthand
72
letters 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

83
Flag parsing stops after the terminator "--". Unlike the flag package,
84
flags can be interspersed with arguments anywhere on the command line
85
before this terminator.
86

87
Integer flags accept 1234, 0664, 0x1234 and may be negative.
88
Boolean flags (in their long form) accept 1, 0, t, f, true, false,
89
TRUE, FALSE, True, False.
90
Duration flags accept any input valid for time.ParseDuration.
91

92
The default set of command-line flags is controlled by
93
top-level functions.  The FlagSet type allows one to define
94
independent sets of flags, such as to implement subcommands
95
in a command-line interface. The methods of FlagSet are
96
analogous to the top-level functions for the command-line
97
flag set.
98
*/
99
package pflag
100

101
import (
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.
113
var ErrHelp = errors.New("pflag: help requested")
114

115
// ErrorHandling defines how to handle flag parsing errors.
116
type ErrorHandling int
117

118
const (
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
128
type 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).
135
type NormalizedName string
136

137
// A FlagSet represents a set of defined flags.
138
type 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.
171
type 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.)
187
type Value interface {
188
	String() string
189
	Set(string) error
190
	Type() string
191
}
192

193
// SliceValue is a secondary interface to all flags which hold a list
194
// of values.  This allows full control over the value of list flags,
195
// and avoids complicated marshalling and unmarshalling to csv.
196
type SliceValue interface {
197
	// Append adds the specified value to the end of the flag value list.
198
	Append(string) error
199
	// Replace will fully overwrite any data currently in the flag value list.
200
	Replace([]string) error
201
	// GetSlice returns the flag value list as an array of strings.
202
	GetSlice() []string
203
}
204

205
// sortFlags returns the flags as a slice in lexicographical sorted order.
206
func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
207
	list := make(sort.StringSlice, len(flags))
208
	i := 0
209
	for k := range flags {
210
		list[i] = string(k)
211
		i++
212
	}
213
	list.Sort()
214
	result := make([]*Flag, len(list))
215
	for i, name := range list {
216
		result[i] = flags[NormalizedName(name)]
217
	}
218
	return result
219
}
220

221
// SetNormalizeFunc allows you to add a function which can translate flag names.
222
// Flags added to the FlagSet will be translated and then when anything tries to
223
// look up the flag that will also be translated. So it would be possible to create
224
// a flag named "getURL" and have it translated to "geturl".  A user could then pass
225
// "--getUrl" which may also be translated to "geturl" and everything will work.
226
func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
227
	f.normalizeNameFunc = n
228
	f.sortedFormal = f.sortedFormal[:0]
229
	for fname, flag := range f.formal {
230
		nname := f.normalizeFlagName(flag.Name)
231
		if fname == nname {
232
			continue
233
		}
234
		flag.Name = string(nname)
235
		delete(f.formal, fname)
236
		f.formal[nname] = flag
237
		if _, set := f.actual[fname]; set {
238
			delete(f.actual, fname)
239
			f.actual[nname] = flag
240
		}
241
	}
242
}
243

244
// GetNormalizeFunc returns the previously set NormalizeFunc of a function which
245
// does no translation, if not set previously.
246
func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
247
	if f.normalizeNameFunc != nil {
248
		return f.normalizeNameFunc
249
	}
250
	return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
251
}
252

253
func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
254
	n := f.GetNormalizeFunc()
255
	return n(f, name)
256
}
257

258
func (f *FlagSet) out() io.Writer {
259
	if f.output == nil {
260
		return os.Stderr
261
	}
262
	return f.output
263
}
264

265
// SetOutput sets the destination for usage and error messages.
266
// If output is nil, os.Stderr is used.
267
func (f *FlagSet) SetOutput(output io.Writer) {
268
	f.output = output
269
}
270

271
// VisitAll visits the flags in lexicographical order or
272
// in primordial order if f.SortFlags is false, calling fn for each.
273
// It visits all flags, even those not set.
274
func (f *FlagSet) VisitAll(fn func(*Flag)) {
275
	if len(f.formal) == 0 {
276
		return
277
	}
278

279
	var flags []*Flag
280
	if f.SortFlags {
281
		if len(f.formal) != len(f.sortedFormal) {
282
			f.sortedFormal = sortFlags(f.formal)
283
		}
284
		flags = f.sortedFormal
285
	} else {
286
		flags = f.orderedFormal
287
	}
288

289
	for _, flag := range flags {
290
		fn(flag)
291
	}
292
}
293

294
// HasFlags returns a bool to indicate if the FlagSet has any flags defined.
295
func (f *FlagSet) HasFlags() bool {
296
	return len(f.formal) > 0
297
}
298

299
// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
300
// that are not hidden.
301
func (f *FlagSet) HasAvailableFlags() bool {
302
	for _, flag := range f.formal {
303
		if !flag.Hidden {
304
			return true
305
		}
306
	}
307
	return false
308
}
309

310
// VisitAll visits the command-line flags in lexicographical order or
311
// in primordial order if f.SortFlags is false, calling fn for each.
312
// It visits all flags, even those not set.
313
func VisitAll(fn func(*Flag)) {
314
	CommandLine.VisitAll(fn)
315
}
316

317
// Visit visits the flags in lexicographical order or
318
// in primordial order if f.SortFlags is false, calling fn for each.
319
// It visits only those flags that have been set.
320
func (f *FlagSet) Visit(fn func(*Flag)) {
321
	if len(f.actual) == 0 {
322
		return
323
	}
324

325
	var flags []*Flag
326
	if f.SortFlags {
327
		if len(f.actual) != len(f.sortedActual) {
328
			f.sortedActual = sortFlags(f.actual)
329
		}
330
		flags = f.sortedActual
331
	} else {
332
		flags = f.orderedActual
333
	}
334

335
	for _, flag := range flags {
336
		fn(flag)
337
	}
338
}
339

340
// Visit visits the command-line flags in lexicographical order or
341
// in primordial order if f.SortFlags is false, calling fn for each.
342
// It visits only those flags that have been set.
343
func Visit(fn func(*Flag)) {
344
	CommandLine.Visit(fn)
345
}
346

347
// Lookup returns the Flag structure of the named flag, returning nil if none exists.
348
func (f *FlagSet) Lookup(name string) *Flag {
349
	return f.lookup(f.normalizeFlagName(name))
350
}
351

352
// ShorthandLookup returns the Flag structure of the short handed flag,
353
// returning nil if none exists.
354
// It panics, if len(name) > 1.
355
func (f *FlagSet) ShorthandLookup(name string) *Flag {
356
	if name == "" {
357
		return nil
358
	}
359
	if len(name) > 1 {
360
		msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
361
		fmt.Fprintf(f.out(), msg)
362
		panic(msg)
363
	}
364
	c := name[0]
365
	return f.shorthands[c]
366
}
367

368
// lookup returns the Flag structure of the named flag, returning nil if none exists.
369
func (f *FlagSet) lookup(name NormalizedName) *Flag {
370
	return f.formal[name]
371
}
372

373
// func to return a given type for a given flag name
374
func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
375
	flag := f.Lookup(name)
376
	if flag == nil {
377
		err := fmt.Errorf("flag accessed but not defined: %s", name)
378
		return nil, err
379
	}
380

381
	if flag.Value.Type() != ftype {
382
		err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
383
		return nil, err
384
	}
385

386
	sval := flag.Value.String()
387
	result, err := convFunc(sval)
388
	if err != nil {
389
		return nil, err
390
	}
391
	return result, nil
392
}
393

394
// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
395
// found during arg parsing. This allows your program to know which args were
396
// before the -- and which came after.
397
func (f *FlagSet) ArgsLenAtDash() int {
398
	return f.argsLenAtDash
399
}
400

401
// MarkDeprecated indicated that a flag is deprecated in your program. It will
402
// continue to function but will not show up in help or usage messages. Using
403
// this flag will also print the given usageMessage.
404
func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
405
	flag := f.Lookup(name)
406
	if flag == nil {
407
		return fmt.Errorf("flag %q does not exist", name)
408
	}
409
	if usageMessage == "" {
410
		return fmt.Errorf("deprecated message for flag %q must be set", name)
411
	}
412
	flag.Deprecated = usageMessage
413
	flag.Hidden = true
414
	return nil
415
}
416

417
// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
418
// program. It will continue to function but will not show up in help or usage
419
// messages. Using this flag will also print the given usageMessage.
420
func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
421
	flag := f.Lookup(name)
422
	if flag == nil {
423
		return fmt.Errorf("flag %q does not exist", name)
424
	}
425
	if usageMessage == "" {
426
		return fmt.Errorf("deprecated message for flag %q must be set", name)
427
	}
428
	flag.ShorthandDeprecated = usageMessage
429
	return nil
430
}
431

432
// MarkHidden sets a flag to 'hidden' in your program. It will continue to
433
// function but will not show up in help or usage messages.
434
func (f *FlagSet) MarkHidden(name string) error {
435
	flag := f.Lookup(name)
436
	if flag == nil {
437
		return fmt.Errorf("flag %q does not exist", name)
438
	}
439
	flag.Hidden = true
440
	return nil
441
}
442

443
// Lookup returns the Flag structure of the named command-line flag,
444
// returning nil if none exists.
445
func Lookup(name string) *Flag {
446
	return CommandLine.Lookup(name)
447
}
448

449
// ShorthandLookup returns the Flag structure of the short handed flag,
450
// returning nil if none exists.
451
func ShorthandLookup(name string) *Flag {
452
	return CommandLine.ShorthandLookup(name)
453
}
454

455
// Set sets the value of the named flag.
456
func (f *FlagSet) Set(name, value string) error {
457
	normalName := f.normalizeFlagName(name)
458
	flag, ok := f.formal[normalName]
459
	if !ok {
460
		return fmt.Errorf("no such flag -%v", name)
461
	}
462

463
	err := flag.Value.Set(value)
464
	if err != nil {
465
		var flagName string
466
		if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
467
			flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
468
		} else {
469
			flagName = fmt.Sprintf("--%s", flag.Name)
470
		}
471
		return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
472
	}
473

474
	if !flag.Changed {
475
		if f.actual == nil {
476
			f.actual = make(map[NormalizedName]*Flag)
477
		}
478
		f.actual[normalName] = flag
479
		f.orderedActual = append(f.orderedActual, flag)
480

481
		flag.Changed = true
482
	}
483

484
	if flag.Deprecated != "" {
485
		fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
486
	}
487
	return nil
488
}
489

490
// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
491
// This is sometimes used by spf13/cobra programs which want to generate additional
492
// bash completion information.
493
func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
494
	normalName := f.normalizeFlagName(name)
495
	flag, ok := f.formal[normalName]
496
	if !ok {
497
		return fmt.Errorf("no such flag -%v", name)
498
	}
499
	if flag.Annotations == nil {
500
		flag.Annotations = map[string][]string{}
501
	}
502
	flag.Annotations[key] = values
503
	return nil
504
}
505

506
// Changed returns true if the flag was explicitly set during Parse() and false
507
// otherwise
508
func (f *FlagSet) Changed(name string) bool {
509
	flag := f.Lookup(name)
510
	// If a flag doesn't exist, it wasn't changed....
511
	if flag == nil {
512
		return false
513
	}
514
	return flag.Changed
515
}
516

517
// Set sets the value of the named command-line flag.
518
func Set(name, value string) error {
519
	return CommandLine.Set(name, value)
520
}
521

522
// PrintDefaults prints, to standard error unless configured
523
// otherwise, the default values of all defined flags in the set.
524
func (f *FlagSet) PrintDefaults() {
525
	usages := f.FlagUsages()
526
	fmt.Fprint(f.out(), usages)
527
}
528

529
// defaultIsZeroValue returns true if the default value for this flag represents
530
// a zero value.
531
func (f *Flag) defaultIsZeroValue() bool {
532
	switch f.Value.(type) {
533
	case boolFlag:
534
		return f.DefValue == "false"
535
	case *durationValue:
536
		// Beginning in Go 1.7, duration zero values are "0s"
537
		return f.DefValue == "0" || f.DefValue == "0s"
538
	case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
539
		return f.DefValue == "0"
540
	case *stringValue:
541
		return f.DefValue == ""
542
	case *ipValue, *ipMaskValue, *ipNetValue:
543
		return f.DefValue == "<nil>"
544
	case *intSliceValue, *stringSliceValue, *stringArrayValue:
545
		return f.DefValue == "[]"
546
	default:
547
		switch f.Value.String() {
548
		case "false":
549
			return true
550
		case "<nil>":
551
			return true
552
		case "":
553
			return true
554
		case "0":
555
			return true
556
		}
557
		return false
558
	}
559
}
560

561
// UnquoteUsage extracts a back-quoted name from the usage
562
// string for a flag and returns it and the un-quoted usage.
563
// Given "a `name` to show" it returns ("name", "a name to show").
564
// If there are no back quotes, the name is an educated guess of the
565
// type of the flag's value, or the empty string if the flag is boolean.
566
func UnquoteUsage(flag *Flag) (name string, usage string) {
567
	// Look for a back-quoted name, but avoid the strings package.
568
	usage = flag.Usage
569
	for i := 0; i < len(usage); i++ {
570
		if usage[i] == '`' {
571
			for j := i + 1; j < len(usage); j++ {
572
				if usage[j] == '`' {
573
					name = usage[i+1 : j]
574
					usage = usage[:i] + name + usage[j+1:]
575
					return name, usage
576
				}
577
			}
578
			break // Only one back quote; use type name.
579
		}
580
	}
581

582
	name = flag.Value.Type()
583
	switch name {
584
	case "bool":
585
		name = ""
586
	case "float64":
587
		name = "float"
588
	case "int64":
589
		name = "int"
590
	case "uint64":
591
		name = "uint"
592
	case "stringSlice":
593
		name = "strings"
594
	case "intSlice":
595
		name = "ints"
596
	case "uintSlice":
597
		name = "uints"
598
	case "boolSlice":
599
		name = "bools"
600
	}
601

602
	return
603
}
604

605
// Splits the string `s` on whitespace into an initial substring up to
606
// `i` runes in length and the remainder. Will go `slop` over `i` if
607
// that encompasses the entire string (which allows the caller to
608
// avoid short orphan words on the final line).
609
func wrapN(i, slop int, s string) (string, string) {
610
	if i+slop > len(s) {
611
		return s, ""
612
	}
613

614
	w := strings.LastIndexAny(s[:i], " \t\n")
615
	if w <= 0 {
616
		return s, ""
617
	}
618
	nlPos := strings.LastIndex(s[:i], "\n")
619
	if nlPos > 0 && nlPos < w {
620
		return s[:nlPos], s[nlPos+1:]
621
	}
622
	return s[:w], s[w+1:]
623
}
624

625
// Wraps the string `s` to a maximum width `w` with leading indent
626
// `i`. The first line is not indented (this is assumed to be done by
627
// caller). Pass `w` == 0 to do no wrapping
628
func wrap(i, w int, s string) string {
629
	if w == 0 {
630
		return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
631
	}
632

633
	// space between indent i and end of line width w into which
634
	// we should wrap the text.
635
	wrap := w - i
636

637
	var r, l string
638

639
	// Not enough space for sensible wrapping. Wrap as a block on
640
	// the next line instead.
641
	if wrap < 24 {
642
		i = 16
643
		wrap = w - i
644
		r += "\n" + strings.Repeat(" ", i)
645
	}
646
	// If still not enough space then don't even try to wrap.
647
	if wrap < 24 {
648
		return strings.Replace(s, "\n", r, -1)
649
	}
650

651
	// Try to avoid short orphan words on the final line, by
652
	// allowing wrapN to go a bit over if that would fit in the
653
	// remainder of the line.
654
	slop := 5
655
	wrap = wrap - slop
656

657
	// Handle first line, which is indented by the caller (or the
658
	// special case above)
659
	l, s = wrapN(wrap, slop, s)
660
	r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1)
661

662
	// Now wrap the rest
663
	for s != "" {
664
		var t string
665

666
		t, s = wrapN(wrap, slop, s)
667
		r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
668
	}
669

670
	return r
671

672
}
673

674
// FlagUsagesWrapped returns a string containing the usage information
675
// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
676
// wrapping)
677
func (f *FlagSet) FlagUsagesWrapped(cols int) string {
678
	buf := new(bytes.Buffer)
679

680
	lines := make([]string, 0, len(f.formal))
681

682
	maxlen := 0
683
	f.VisitAll(func(flag *Flag) {
684
		if flag.Hidden {
685
			return
686
		}
687

688
		line := ""
689
		if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
690
			line = fmt.Sprintf("  -%s, --%s", flag.Shorthand, flag.Name)
691
		} else {
692
			line = fmt.Sprintf("      --%s", flag.Name)
693
		}
694

695
		varname, usage := UnquoteUsage(flag)
696
		if varname != "" {
697
			line += " " + varname
698
		}
699
		if flag.NoOptDefVal != "" {
700
			switch flag.Value.Type() {
701
			case "string":
702
				line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
703
			case "bool":
704
				if flag.NoOptDefVal != "true" {
705
					line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
706
				}
707
			case "count":
708
				if flag.NoOptDefVal != "+1" {
709
					line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
710
				}
711
			default:
712
				line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
713
			}
714
		}
715

716
		// This special character will be replaced with spacing once the
717
		// correct alignment is calculated
718
		line += "\x00"
719
		if len(line) > maxlen {
720
			maxlen = len(line)
721
		}
722

723
		line += usage
724
		if !flag.defaultIsZeroValue() {
725
			if flag.Value.Type() == "string" {
726
				line += fmt.Sprintf(" (default %q)", flag.DefValue)
727
			} else {
728
				line += fmt.Sprintf(" (default %s)", flag.DefValue)
729
			}
730
		}
731
		if len(flag.Deprecated) != 0 {
732
			line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
733
		}
734

735
		lines = append(lines, line)
736
	})
737

738
	for _, line := range lines {
739
		sidx := strings.Index(line, "\x00")
740
		spacing := strings.Repeat(" ", maxlen-sidx)
741
		// maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
742
		fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
743
	}
744

745
	return buf.String()
746
}
747

748
// FlagUsages returns a string containing the usage information for all flags in
749
// the FlagSet
750
func (f *FlagSet) FlagUsages() string {
751
	return f.FlagUsagesWrapped(0)
752
}
753

754
// PrintDefaults prints to standard error the default values of all defined command-line flags.
755
func PrintDefaults() {
756
	CommandLine.PrintDefaults()
757
}
758

759
// defaultUsage is the default function to print a usage message.
760
func defaultUsage(f *FlagSet) {
761
	fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
762
	f.PrintDefaults()
763
}
764

765
// NOTE: Usage is not just defaultUsage(CommandLine)
766
// because it serves (via godoc flag Usage) as the example
767
// for how to write your own usage function.
768

769
// Usage prints to standard error a usage message documenting all defined command-line flags.
770
// The function is a variable that may be changed to point to a custom function.
771
// By default it prints a simple header and calls PrintDefaults; for details about the
772
// format of the output and how to control it, see the documentation for PrintDefaults.
773
var Usage = func() {
774
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
775
	PrintDefaults()
776
}
777

778
// NFlag returns the number of flags that have been set.
779
func (f *FlagSet) NFlag() int { return len(f.actual) }
780

781
// NFlag returns the number of command-line flags that have been set.
782
func NFlag() int { return len(CommandLine.actual) }
783

784
// Arg returns the i'th argument.  Arg(0) is the first remaining argument
785
// after flags have been processed.
786
func (f *FlagSet) Arg(i int) string {
787
	if i < 0 || i >= len(f.args) {
788
		return ""
789
	}
790
	return f.args[i]
791
}
792

793
// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
794
// after flags have been processed.
795
func Arg(i int) string {
796
	return CommandLine.Arg(i)
797
}
798

799
// NArg is the number of arguments remaining after flags have been processed.
800
func (f *FlagSet) NArg() int { return len(f.args) }
801

802
// NArg is the number of arguments remaining after flags have been processed.
803
func NArg() int { return len(CommandLine.args) }
804

805
// Args returns the non-flag arguments.
806
func (f *FlagSet) Args() []string { return f.args }
807

808
// Args returns the non-flag command-line arguments.
809
func Args() []string { return CommandLine.args }
810

811
// Var defines a flag with the specified name and usage string. The type and
812
// value of the flag are represented by the first argument, of type Value, which
813
// typically holds a user-defined implementation of Value. For instance, the
814
// caller could create a flag that turns a comma-separated string into a slice
815
// of strings by giving the slice the methods of Value; in particular, Set would
816
// decompose the comma-separated string into the slice.
817
func (f *FlagSet) Var(value Value, name string, usage string) {
818
	f.VarP(value, name, "", usage)
819
}
820

821
// VarPF is like VarP, but returns the flag created
822
func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
823
	// Remember the default value as a string; it won't change.
824
	flag := &Flag{
825
		Name:      name,
826
		Shorthand: shorthand,
827
		Usage:     usage,
828
		Value:     value,
829
		DefValue:  value.String(),
830
	}
831
	f.AddFlag(flag)
832
	return flag
833
}
834

835
// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
836
func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
837
	f.VarPF(value, name, shorthand, usage)
838
}
839

840
// AddFlag will add the flag to the FlagSet
841
func (f *FlagSet) AddFlag(flag *Flag) {
842
	normalizedFlagName := f.normalizeFlagName(flag.Name)
843

844
	_, alreadyThere := f.formal[normalizedFlagName]
845
	if alreadyThere {
846
		msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
847
		fmt.Fprintln(f.out(), msg)
848
		panic(msg) // Happens only if flags are declared with identical names
849
	}
850
	if f.formal == nil {
851
		f.formal = make(map[NormalizedName]*Flag)
852
	}
853

854
	flag.Name = string(normalizedFlagName)
855
	f.formal[normalizedFlagName] = flag
856
	f.orderedFormal = append(f.orderedFormal, flag)
857

858
	if flag.Shorthand == "" {
859
		return
860
	}
861
	if len(flag.Shorthand) > 1 {
862
		msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
863
		fmt.Fprintf(f.out(), msg)
864
		panic(msg)
865
	}
866
	if f.shorthands == nil {
867
		f.shorthands = make(map[byte]*Flag)
868
	}
869
	c := flag.Shorthand[0]
870
	used, alreadyThere := f.shorthands[c]
871
	if alreadyThere {
872
		msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
873
		fmt.Fprintf(f.out(), msg)
874
		panic(msg)
875
	}
876
	f.shorthands[c] = flag
877
}
878

879
// AddFlagSet adds one FlagSet to another. If a flag is already present in f
880
// the flag from newSet will be ignored.
881
func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
882
	if newSet == nil {
883
		return
884
	}
885
	newSet.VisitAll(func(flag *Flag) {
886
		if f.Lookup(flag.Name) == nil {
887
			f.AddFlag(flag)
888
		}
889
	})
890
}
891

892
// Var defines a flag with the specified name and usage string. The type and
893
// value of the flag are represented by the first argument, of type Value, which
894
// typically holds a user-defined implementation of Value. For instance, the
895
// caller could create a flag that turns a comma-separated string into a slice
896
// of strings by giving the slice the methods of Value; in particular, Set would
897
// decompose the comma-separated string into the slice.
898
func Var(value Value, name string, usage string) {
899
	CommandLine.VarP(value, name, "", usage)
900
}
901

902
// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
903
func VarP(value Value, name, shorthand, usage string) {
904
	CommandLine.VarP(value, name, shorthand, usage)
905
}
906

907
// failf prints to standard error a formatted error and usage message and
908
// returns the error.
909
func (f *FlagSet) failf(format string, a ...interface{}) error {
910
	err := fmt.Errorf(format, a...)
911
	if f.errorHandling != ContinueOnError {
912
		fmt.Fprintln(f.out(), err)
913
		f.usage()
914
	}
915
	return err
916
}
917

918
// usage calls the Usage method for the flag set, or the usage function if
919
// the flag set is CommandLine.
920
func (f *FlagSet) usage() {
921
	if f == CommandLine {
922
		Usage()
923
	} else if f.Usage == nil {
924
		defaultUsage(f)
925
	} else {
926
		f.Usage()
927
	}
928
}
929

930
//--unknown (args will be empty)
931
//--unknown --next-flag ... (args will be --next-flag ...)
932
//--unknown arg ... (args will be arg ...)
933
func stripUnknownFlagValue(args []string) []string {
934
	if len(args) == 0 {
935
		//--unknown
936
		return args
937
	}
938

939
	first := args[0]
940
	if len(first) > 0 && first[0] == '-' {
941
		//--unknown --next-flag ...
942
		return args
943
	}
944

945
	//--unknown arg ... (args will be arg ...)
946
	if len(args) > 1 {
947
		return args[1:]
948
	}
949
	return nil
950
}
951

952
func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
953
	a = args
954
	name := s[2:]
955
	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
956
		err = f.failf("bad flag syntax: %s", s)
957
		return
958
	}
959

960
	split := strings.SplitN(name, "=", 2)
961
	name = split[0]
962
	flag, exists := f.formal[f.normalizeFlagName(name)]
963

964
	if !exists {
965
		switch {
966
		case name == "help":
967
			f.usage()
968
			return a, ErrHelp
969
		case f.ParseErrorsWhitelist.UnknownFlags:
970
			// --unknown=unknownval arg ...
971
			// we do not want to lose arg in this case
972
			if len(split) >= 2 {
973
				return a, nil
974
			}
975

976
			return stripUnknownFlagValue(a), nil
977
		default:
978
			err = f.failf("unknown flag: --%s", name)
979
			return
980
		}
981
	}
982

983
	var value string
984
	if len(split) == 2 {
985
		// '--flag=arg'
986
		value = split[1]
987
	} else if flag.NoOptDefVal != "" {
988
		// '--flag' (arg was optional)
989
		value = flag.NoOptDefVal
990
	} else if len(a) > 0 {
991
		// '--flag arg'
992
		value = a[0]
993
		a = a[1:]
994
	} else {
995
		// '--flag' (arg was required)
996
		err = f.failf("flag needs an argument: %s", s)
997
		return
998
	}
999

1000
	err = fn(flag, value)
1001
	if err != nil {
1002
		f.failf(err.Error())
1003
	}
1004
	return
1005
}
1006

1007
func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
1008
	outArgs = args
1009

1010
	if strings.HasPrefix(shorthands, "test.") {
1011
		return
1012
	}
1013

1014
	outShorts = shorthands[1:]
1015
	c := shorthands[0]
1016

1017
	flag, exists := f.shorthands[c]
1018
	if !exists {
1019
		switch {
1020
		case c == 'h':
1021
			f.usage()
1022
			err = ErrHelp
1023
			return
1024
		case f.ParseErrorsWhitelist.UnknownFlags:
1025
			// '-f=arg arg ...'
1026
			// we do not want to lose arg in this case
1027
			if len(shorthands) > 2 && shorthands[1] == '=' {
1028
				outShorts = ""
1029
				return
1030
			}
1031

1032
			outArgs = stripUnknownFlagValue(outArgs)
1033
			return
1034
		default:
1035
			err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
1036
			return
1037
		}
1038
	}
1039

1040
	var value string
1041
	if len(shorthands) > 2 && shorthands[1] == '=' {
1042
		// '-f=arg'
1043
		value = shorthands[2:]
1044
		outShorts = ""
1045
	} else if flag.NoOptDefVal != "" {
1046
		// '-f' (arg was optional)
1047
		value = flag.NoOptDefVal
1048
	} else if len(shorthands) > 1 {
1049
		// '-farg'
1050
		value = shorthands[1:]
1051
		outShorts = ""
1052
	} else if len(args) > 0 {
1053
		// '-f arg'
1054
		value = args[0]
1055
		outArgs = args[1:]
1056
	} else {
1057
		// '-f' (arg was required)
1058
		err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
1059
		return
1060
	}
1061

1062
	if flag.ShorthandDeprecated != "" {
1063
		fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
1064
	}
1065

1066
	err = fn(flag, value)
1067
	if err != nil {
1068
		f.failf(err.Error())
1069
	}
1070
	return
1071
}
1072

1073
func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
1074
	a = args
1075
	shorthands := s[1:]
1076

1077
	// "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
1078
	for len(shorthands) > 0 {
1079
		shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
1080
		if err != nil {
1081
			return
1082
		}
1083
	}
1084

1085
	return
1086
}
1087

1088
func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
1089
	for len(args) > 0 {
1090
		s := args[0]
1091
		args = args[1:]
1092
		if len(s) == 0 || s[0] != '-' || len(s) == 1 {
1093
			if !f.interspersed {
1094
				f.args = append(f.args, s)
1095
				f.args = append(f.args, args...)
1096
				return nil
1097
			}
1098
			f.args = append(f.args, s)
1099
			continue
1100
		}
1101

1102
		if s[1] == '-' {
1103
			if len(s) == 2 { // "--" terminates the flags
1104
				f.argsLenAtDash = len(f.args)
1105
				f.args = append(f.args, args...)
1106
				break
1107
			}
1108
			args, err = f.parseLongArg(s, args, fn)
1109
		} else {
1110
			args, err = f.parseShortArg(s, args, fn)
1111
		}
1112
		if err != nil {
1113
			return
1114
		}
1115
	}
1116
	return
1117
}
1118

1119
// Parse parses flag definitions from the argument list, which should not
1120
// include the command name.  Must be called after all flags in the FlagSet
1121
// are defined and before flags are accessed by the program.
1122
// The return value will be ErrHelp if -help was set but not defined.
1123
func (f *FlagSet) Parse(arguments []string) error {
1124
	if f.addedGoFlagSets != nil {
1125
		for _, goFlagSet := range f.addedGoFlagSets {
1126
			goFlagSet.Parse(nil)
1127
		}
1128
	}
1129
	f.parsed = true
1130

1131
	if len(arguments) < 0 {
1132
		return nil
1133
	}
1134

1135
	f.args = make([]string, 0, len(arguments))
1136

1137
	set := func(flag *Flag, value string) error {
1138
		return f.Set(flag.Name, value)
1139
	}
1140

1141
	err := f.parseArgs(arguments, set)
1142
	if err != nil {
1143
		switch f.errorHandling {
1144
		case ContinueOnError:
1145
			return err
1146
		case ExitOnError:
1147
			fmt.Println(err)
1148
			os.Exit(2)
1149
		case PanicOnError:
1150
			panic(err)
1151
		}
1152
	}
1153
	return nil
1154
}
1155

1156
type parseFunc func(flag *Flag, value string) error
1157

1158
// ParseAll parses flag definitions from the argument list, which should not
1159
// include the command name. The arguments for fn are flag and value. Must be
1160
// called after all flags in the FlagSet are defined and before flags are
1161
// accessed by the program. The return value will be ErrHelp if -help was set
1162
// but not defined.
1163
func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
1164
	f.parsed = true
1165
	f.args = make([]string, 0, len(arguments))
1166

1167
	err := f.parseArgs(arguments, fn)
1168
	if err != nil {
1169
		switch f.errorHandling {
1170
		case ContinueOnError:
1171
			return err
1172
		case ExitOnError:
1173
			os.Exit(2)
1174
		case PanicOnError:
1175
			panic(err)
1176
		}
1177
	}
1178
	return nil
1179
}
1180

1181
// Parsed reports whether f.Parse has been called.
1182
func (f *FlagSet) Parsed() bool {
1183
	return f.parsed
1184
}
1185

1186
// Parse parses the command-line flags from os.Args[1:].  Must be called
1187
// after all flags are defined and before flags are accessed by the program.
1188
func Parse() {
1189
	// Ignore errors; CommandLine is set for ExitOnError.
1190
	CommandLine.Parse(os.Args[1:])
1191
}
1192

1193
// ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
1194
// The arguments for fn are flag and value. Must be called after all flags are
1195
// defined and before flags are accessed by the program.
1196
func ParseAll(fn func(flag *Flag, value string) error) {
1197
	// Ignore errors; CommandLine is set for ExitOnError.
1198
	CommandLine.ParseAll(os.Args[1:], fn)
1199
}
1200

1201
// SetInterspersed sets whether to support interspersed option/non-option arguments.
1202
func SetInterspersed(interspersed bool) {
1203
	CommandLine.SetInterspersed(interspersed)
1204
}
1205

1206
// Parsed returns true if the command-line flags have been parsed.
1207
func Parsed() bool {
1208
	return CommandLine.Parsed()
1209
}
1210

1211
// CommandLine is the default set of command-line flags, parsed from os.Args.
1212
var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
1213

1214
// NewFlagSet returns a new, empty flag set with the specified name,
1215
// error handling property and SortFlags set to true.
1216
func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
1217
	f := &FlagSet{
1218
		name:          name,
1219
		errorHandling: errorHandling,
1220
		argsLenAtDash: -1,
1221
		interspersed:  true,
1222
		SortFlags:     true,
1223
	}
1224
	return f
1225
}
1226

1227
// SetInterspersed sets whether to support interspersed option/non-option arguments.
1228
func (f *FlagSet) SetInterspersed(interspersed bool) {
1229
	f.interspersed = interspersed
1230
}
1231

1232
// Init sets the name and error handling property for a flag set.
1233
// By default, the zero FlagSet uses an empty name and the
1234
// ContinueOnError error handling policy.
1235
func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
1236
	f.name = name
1237
	f.errorHandling = errorHandling
1238
	f.argsLenAtDash = -1
1239
}
1240

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.