golangflag.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. package pflag
  5. import (
  6. goflag "flag"
  7. "fmt"
  8. "reflect"
  9. "strings"
  10. )
  11. var _ = fmt.Print
  12. // flagValueWrapper implements pflag.Value around a flag.Value. The main
  13. // difference here is the addition of the Type method that returns a string
  14. // name of the type. As this is generally unknown, we approximate that with
  15. // reflection.
  16. type flagValueWrapper struct {
  17. inner goflag.Value
  18. flagType string
  19. }
  20. // We are just copying the boolFlag interface out of goflag as that is what
  21. // they use to decide if a flag should get "true" when no arg is given.
  22. type goBoolFlag interface {
  23. goflag.Value
  24. IsBoolFlag() bool
  25. }
  26. func wrapFlagValue(v goflag.Value) Value {
  27. // If the flag.Value happens to also be a pflag.Value, just use it directly.
  28. if pv, ok := v.(Value); ok {
  29. return pv
  30. }
  31. pv := &flagValueWrapper{
  32. inner: v,
  33. }
  34. t := reflect.TypeOf(v)
  35. if t.Kind() == reflect.Interface || t.Kind() == reflect.Ptr {
  36. t = t.Elem()
  37. }
  38. pv.flagType = strings.TrimSuffix(t.Name(), "Value")
  39. return pv
  40. }
  41. func (v *flagValueWrapper) String() string {
  42. return v.inner.String()
  43. }
  44. func (v *flagValueWrapper) Set(s string) error {
  45. return v.inner.Set(s)
  46. }
  47. func (v *flagValueWrapper) Type() string {
  48. return v.flagType
  49. }
  50. // PFlagFromGoFlag will return a *pflag.Flag given a *flag.Flag
  51. func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
  52. // Remember the default value as a string; it won't change.
  53. flag := &Flag{
  54. Name: goflag.Name,
  55. Usage: goflag.Usage,
  56. Value: wrapFlagValue(goflag.Value),
  57. // Looks like golang flags don't set DefValue correctly :-(
  58. //DefValue: goflag.DefValue,
  59. DefValue: goflag.Value.String(),
  60. }
  61. if fv, ok := goflag.Value.(goBoolFlag); ok && fv.IsBoolFlag() {
  62. flag.NoOptDefVal = "true"
  63. }
  64. return flag
  65. }
  66. // AddGoFlag will add the given *flag.Flag to the pflag.FlagSet
  67. func (f *FlagSet) AddGoFlag(goflag *goflag.Flag) {
  68. if f.Lookup(goflag.Name) != nil {
  69. return
  70. }
  71. newflag := PFlagFromGoFlag(goflag)
  72. f.AddFlag(newflag)
  73. }
  74. // AddGoFlagSet will add the given *flag.FlagSet to the pflag.FlagSet
  75. func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
  76. if newSet == nil {
  77. return
  78. }
  79. newSet.VisitAll(func(goflag *goflag.Flag) {
  80. f.AddGoFlag(goflag)
  81. })
  82. }