...

Source file src/github.com/spf13/pflag/golangflag.go

Documentation: github.com/spf13/pflag

     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  	if f.addedGoFlagSets == nil {
   102  		f.addedGoFlagSets = make([]*goflag.FlagSet, 0)
   103  	}
   104  	f.addedGoFlagSets = append(f.addedGoFlagSets, newSet)
   105  }
   106  

View as plain text