OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / spf13 / pflag / golangflag.go
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 package pflag
6
7 import (
8         goflag "flag"
9         "reflect"
10         "strings"
11 )
12
13 // flagValueWrapper implements pflag.Value around a flag.Value.  The main
14 // difference here is the addition of the Type method that returns a string
15 // name of the type.  As this is generally unknown, we approximate that with
16 // reflection.
17 type flagValueWrapper struct {
18         inner    goflag.Value
19         flagType string
20 }
21
22 // We are just copying the boolFlag interface out of goflag as that is what
23 // they use to decide if a flag should get "true" when no arg is given.
24 type goBoolFlag interface {
25         goflag.Value
26         IsBoolFlag() bool
27 }
28
29 func wrapFlagValue(v goflag.Value) Value {
30         // If the flag.Value happens to also be a pflag.Value, just use it directly.
31         if pv, ok := v.(Value); ok {
32                 return pv
33         }
34
35         pv := &flagValueWrapper{
36                 inner: v,
37         }
38
39         t := reflect.TypeOf(v)
40         if t.Kind() == reflect.Interface || t.Kind() == reflect.Ptr {
41                 t = t.Elem()
42         }
43
44         pv.flagType = strings.TrimSuffix(t.Name(), "Value")
45         return pv
46 }
47
48 func (v *flagValueWrapper) String() string {
49         return v.inner.String()
50 }
51
52 func (v *flagValueWrapper) Set(s string) error {
53         return v.inner.Set(s)
54 }
55
56 func (v *flagValueWrapper) Type() string {
57         return v.flagType
58 }
59
60 // PFlagFromGoFlag will return a *pflag.Flag given a *flag.Flag
61 // If the *flag.Flag.Name was a single character (ex: `v`) it will be accessiblei
62 // with both `-v` and `--v` in flags. If the golang flag was more than a single
63 // character (ex: `verbose`) it will only be accessible via `--verbose`
64 func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
65         // Remember the default value as a string; it won't change.
66         flag := &Flag{
67                 Name:  goflag.Name,
68                 Usage: goflag.Usage,
69                 Value: wrapFlagValue(goflag.Value),
70                 // Looks like golang flags don't set DefValue correctly  :-(
71                 //DefValue: goflag.DefValue,
72                 DefValue: goflag.Value.String(),
73         }
74         // Ex: if the golang flag was -v, allow both -v and --v to work
75         if len(flag.Name) == 1 {
76                 flag.Shorthand = flag.Name
77         }
78         if fv, ok := goflag.Value.(goBoolFlag); ok && fv.IsBoolFlag() {
79                 flag.NoOptDefVal = "true"
80         }
81         return flag
82 }
83
84 // AddGoFlag will add the given *flag.Flag to the pflag.FlagSet
85 func (f *FlagSet) AddGoFlag(goflag *goflag.Flag) {
86         if f.Lookup(goflag.Name) != nil {
87                 return
88         }
89         newflag := PFlagFromGoFlag(goflag)
90         f.AddFlag(newflag)
91 }
92
93 // AddGoFlagSet will add the given *flag.FlagSet to the pflag.FlagSet
94 func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
95         if newSet == nil {
96                 return
97         }
98         newSet.VisitAll(func(goflag *goflag.Flag) {
99                 f.AddGoFlag(goflag)
100         })
101 }