Browse code

vendor: github.com/spf13/pflag v1.0.6

- Add exported functions to preserve pkg/flag compatibility
- Add IPNetSlice and unit tests

full diff: https://github.com/spf13/pflag/compare/v1.0.5...v1.0.6

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2025/02/11 23:45:03
Showing 8 changed files
... ...
@@ -91,7 +91,7 @@ require (
91 91
 	github.com/rootless-containers/rootlesskit/v2 v2.3.2
92 92
 	github.com/sirupsen/logrus v1.9.3
93 93
 	github.com/spf13/cobra v1.8.1
94
-	github.com/spf13/pflag v1.0.5
94
+	github.com/spf13/pflag v1.0.6
95 95
 	github.com/tonistiigi/go-archvariant v1.0.0
96 96
 	github.com/vbatts/tar-split v0.11.6
97 97
 	github.com/vishvananda/netlink v1.3.1-0.20240922070040-084abd93d350
... ...
@@ -503,8 +503,9 @@ github.com/spdx/tools-golang v0.5.3 h1:ialnHeEYUC4+hkm5vJm4qz2x+oEJbS0mAMFrNXdQr
503 503
 github.com/spdx/tools-golang v0.5.3/go.mod h1:/ETOahiAo96Ob0/RAIBmFZw6XN0yTnyr/uFZm2NTMhI=
504 504
 github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
505 505
 github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
506
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
507 506
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
507
+github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
508
+github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
508 509
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
509 510
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
510 511
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
511 512
new file mode 100644
... ...
@@ -0,0 +1,4 @@
0
+linters:
1
+    disable-all: true
2
+    enable:
3
+        - nolintlint
... ...
@@ -160,7 +160,7 @@ type FlagSet struct {
160 160
 	args              []string // arguments after flags
161 161
 	argsLenAtDash     int      // len(args) when a '--' was located when parsing, or -1 if no --
162 162
 	errorHandling     ErrorHandling
163
-	output            io.Writer // nil means stderr; use out() accessor
163
+	output            io.Writer // nil means stderr; use Output() accessor
164 164
 	interspersed      bool      // allow interspersed option/non-option args
165 165
 	normalizeNameFunc func(f *FlagSet, name string) NormalizedName
166 166
 
... ...
@@ -255,13 +255,20 @@ func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
255 255
 	return n(f, name)
256 256
 }
257 257
 
258
-func (f *FlagSet) out() io.Writer {
258
+// Output returns the destination for usage and error messages. os.Stderr is returned if
259
+// output was not set or was set to nil.
260
+func (f *FlagSet) Output() io.Writer {
259 261
 	if f.output == nil {
260 262
 		return os.Stderr
261 263
 	}
262 264
 	return f.output
263 265
 }
264 266
 
267
+// Name returns the name of the flag set.
268
+func (f *FlagSet) Name() string {
269
+	return f.name
270
+}
271
+
265 272
 // SetOutput sets the destination for usage and error messages.
266 273
 // If output is nil, os.Stderr is used.
267 274
 func (f *FlagSet) SetOutput(output io.Writer) {
... ...
@@ -358,7 +365,7 @@ func (f *FlagSet) ShorthandLookup(name string) *Flag {
358 358
 	}
359 359
 	if len(name) > 1 {
360 360
 		msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
361
-		fmt.Fprintf(f.out(), msg)
361
+		fmt.Fprintf(f.Output(), msg)
362 362
 		panic(msg)
363 363
 	}
364 364
 	c := name[0]
... ...
@@ -482,7 +489,7 @@ func (f *FlagSet) Set(name, value string) error {
482 482
 	}
483 483
 
484 484
 	if flag.Deprecated != "" {
485
-		fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
485
+		fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
486 486
 	}
487 487
 	return nil
488 488
 }
... ...
@@ -523,7 +530,7 @@ func Set(name, value string) error {
523 523
 // otherwise, the default values of all defined flags in the set.
524 524
 func (f *FlagSet) PrintDefaults() {
525 525
 	usages := f.FlagUsages()
526
-	fmt.Fprint(f.out(), usages)
526
+	fmt.Fprint(f.Output(), usages)
527 527
 }
528 528
 
529 529
 // defaultIsZeroValue returns true if the default value for this flag represents
... ...
@@ -758,7 +765,7 @@ func PrintDefaults() {
758 758
 
759 759
 // defaultUsage is the default function to print a usage message.
760 760
 func defaultUsage(f *FlagSet) {
761
-	fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
761
+	fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
762 762
 	f.PrintDefaults()
763 763
 }
764 764
 
... ...
@@ -844,7 +851,7 @@ func (f *FlagSet) AddFlag(flag *Flag) {
844 844
 	_, alreadyThere := f.formal[normalizedFlagName]
845 845
 	if alreadyThere {
846 846
 		msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
847
-		fmt.Fprintln(f.out(), msg)
847
+		fmt.Fprintln(f.Output(), msg)
848 848
 		panic(msg) // Happens only if flags are declared with identical names
849 849
 	}
850 850
 	if f.formal == nil {
... ...
@@ -860,7 +867,7 @@ func (f *FlagSet) AddFlag(flag *Flag) {
860 860
 	}
861 861
 	if len(flag.Shorthand) > 1 {
862 862
 		msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
863
-		fmt.Fprintf(f.out(), msg)
863
+		fmt.Fprintf(f.Output(), msg)
864 864
 		panic(msg)
865 865
 	}
866 866
 	if f.shorthands == nil {
... ...
@@ -870,7 +877,7 @@ func (f *FlagSet) AddFlag(flag *Flag) {
870 870
 	used, alreadyThere := f.shorthands[c]
871 871
 	if alreadyThere {
872 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)
873
+		fmt.Fprintf(f.Output(), msg)
874 874
 		panic(msg)
875 875
 	}
876 876
 	f.shorthands[c] = flag
... ...
@@ -909,7 +916,7 @@ func VarP(value Value, name, shorthand, usage string) {
909 909
 func (f *FlagSet) failf(format string, a ...interface{}) error {
910 910
 	err := fmt.Errorf(format, a...)
911 911
 	if f.errorHandling != ContinueOnError {
912
-		fmt.Fprintln(f.out(), err)
912
+		fmt.Fprintln(f.Output(), err)
913 913
 		f.usage()
914 914
 	}
915 915
 	return err
... ...
@@ -1060,7 +1067,7 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse
1060 1060
 	}
1061 1061
 
1062 1062
 	if flag.ShorthandDeprecated != "" {
1063
-		fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
1063
+		fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
1064 1064
 	}
1065 1065
 
1066 1066
 	err = fn(flag, value)
... ...
@@ -16,6 +16,9 @@ func newIPValue(val net.IP, p *net.IP) *ipValue {
16 16
 
17 17
 func (i *ipValue) String() string { return net.IP(*i).String() }
18 18
 func (i *ipValue) Set(s string) error {
19
+	if s == "" {
20
+		return nil
21
+	}
19 22
 	ip := net.ParseIP(strings.TrimSpace(s))
20 23
 	if ip == nil {
21 24
 		return fmt.Errorf("failed to parse IP: %q", s)
22 25
new file mode 100644
... ...
@@ -0,0 +1,147 @@
0
+package pflag
1
+
2
+import (
3
+	"fmt"
4
+	"io"
5
+	"net"
6
+	"strings"
7
+)
8
+
9
+// -- ipNetSlice Value
10
+type ipNetSliceValue struct {
11
+	value   *[]net.IPNet
12
+	changed bool
13
+}
14
+
15
+func newIPNetSliceValue(val []net.IPNet, p *[]net.IPNet) *ipNetSliceValue {
16
+	ipnsv := new(ipNetSliceValue)
17
+	ipnsv.value = p
18
+	*ipnsv.value = val
19
+	return ipnsv
20
+}
21
+
22
+// Set converts, and assigns, the comma-separated IPNet argument string representation as the []net.IPNet value of this flag.
23
+// If Set is called on a flag that already has a []net.IPNet assigned, the newly converted values will be appended.
24
+func (s *ipNetSliceValue) Set(val string) error {
25
+
26
+	// remove all quote characters
27
+	rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
28
+
29
+	// read flag arguments with CSV parser
30
+	ipNetStrSlice, err := readAsCSV(rmQuote.Replace(val))
31
+	if err != nil && err != io.EOF {
32
+		return err
33
+	}
34
+
35
+	// parse ip values into slice
36
+	out := make([]net.IPNet, 0, len(ipNetStrSlice))
37
+	for _, ipNetStr := range ipNetStrSlice {
38
+		_, n, err := net.ParseCIDR(strings.TrimSpace(ipNetStr))
39
+		if err != nil {
40
+			return fmt.Errorf("invalid string being converted to CIDR: %s", ipNetStr)
41
+		}
42
+		out = append(out, *n)
43
+	}
44
+
45
+	if !s.changed {
46
+		*s.value = out
47
+	} else {
48
+		*s.value = append(*s.value, out...)
49
+	}
50
+
51
+	s.changed = true
52
+
53
+	return nil
54
+}
55
+
56
+// Type returns a string that uniquely represents this flag's type.
57
+func (s *ipNetSliceValue) Type() string {
58
+	return "ipNetSlice"
59
+}
60
+
61
+// String defines a "native" format for this net.IPNet slice flag value.
62
+func (s *ipNetSliceValue) String() string {
63
+
64
+	ipNetStrSlice := make([]string, len(*s.value))
65
+	for i, n := range *s.value {
66
+		ipNetStrSlice[i] = n.String()
67
+	}
68
+
69
+	out, _ := writeAsCSV(ipNetStrSlice)
70
+	return "[" + out + "]"
71
+}
72
+
73
+func ipNetSliceConv(val string) (interface{}, error) {
74
+	val = strings.Trim(val, "[]")
75
+	// Emtpy string would cause a slice with one (empty) entry
76
+	if len(val) == 0 {
77
+		return []net.IPNet{}, nil
78
+	}
79
+	ss := strings.Split(val, ",")
80
+	out := make([]net.IPNet, len(ss))
81
+	for i, sval := range ss {
82
+		_, n, err := net.ParseCIDR(strings.TrimSpace(sval))
83
+		if err != nil {
84
+			return nil, fmt.Errorf("invalid string being converted to CIDR: %s", sval)
85
+		}
86
+		out[i] = *n
87
+	}
88
+	return out, nil
89
+}
90
+
91
+// GetIPNetSlice returns the []net.IPNet value of a flag with the given name
92
+func (f *FlagSet) GetIPNetSlice(name string) ([]net.IPNet, error) {
93
+	val, err := f.getFlagType(name, "ipNetSlice", ipNetSliceConv)
94
+	if err != nil {
95
+		return []net.IPNet{}, err
96
+	}
97
+	return val.([]net.IPNet), nil
98
+}
99
+
100
+// IPNetSliceVar defines a ipNetSlice flag with specified name, default value, and usage string.
101
+// The argument p points to a []net.IPNet variable in which to store the value of the flag.
102
+func (f *FlagSet) IPNetSliceVar(p *[]net.IPNet, name string, value []net.IPNet, usage string) {
103
+	f.VarP(newIPNetSliceValue(value, p), name, "", usage)
104
+}
105
+
106
+// IPNetSliceVarP is like IPNetSliceVar, but accepts a shorthand letter that can be used after a single dash.
107
+func (f *FlagSet) IPNetSliceVarP(p *[]net.IPNet, name, shorthand string, value []net.IPNet, usage string) {
108
+	f.VarP(newIPNetSliceValue(value, p), name, shorthand, usage)
109
+}
110
+
111
+// IPNetSliceVar defines a []net.IPNet flag with specified name, default value, and usage string.
112
+// The argument p points to a []net.IPNet variable in which to store the value of the flag.
113
+func IPNetSliceVar(p *[]net.IPNet, name string, value []net.IPNet, usage string) {
114
+	CommandLine.VarP(newIPNetSliceValue(value, p), name, "", usage)
115
+}
116
+
117
+// IPNetSliceVarP is like IPNetSliceVar, but accepts a shorthand letter that can be used after a single dash.
118
+func IPNetSliceVarP(p *[]net.IPNet, name, shorthand string, value []net.IPNet, usage string) {
119
+	CommandLine.VarP(newIPNetSliceValue(value, p), name, shorthand, usage)
120
+}
121
+
122
+// IPNetSlice defines a []net.IPNet flag with specified name, default value, and usage string.
123
+// The return value is the address of a []net.IPNet variable that stores the value of that flag.
124
+func (f *FlagSet) IPNetSlice(name string, value []net.IPNet, usage string) *[]net.IPNet {
125
+	p := []net.IPNet{}
126
+	f.IPNetSliceVarP(&p, name, "", value, usage)
127
+	return &p
128
+}
129
+
130
+// IPNetSliceP is like IPNetSlice, but accepts a shorthand letter that can be used after a single dash.
131
+func (f *FlagSet) IPNetSliceP(name, shorthand string, value []net.IPNet, usage string) *[]net.IPNet {
132
+	p := []net.IPNet{}
133
+	f.IPNetSliceVarP(&p, name, shorthand, value, usage)
134
+	return &p
135
+}
136
+
137
+// IPNetSlice defines a []net.IPNet flag with specified name, default value, and usage string.
138
+// The return value is the address of a []net.IP variable that stores the value of the flag.
139
+func IPNetSlice(name string, value []net.IPNet, usage string) *[]net.IPNet {
140
+	return CommandLine.IPNetSliceP(name, "", value, usage)
141
+}
142
+
143
+// IPNetSliceP is like IPNetSlice, but accepts a shorthand letter that can be used after a single dash.
144
+func IPNetSliceP(name, shorthand string, value []net.IPNet, usage string) *[]net.IPNet {
145
+	return CommandLine.IPNetSliceP(name, shorthand, value, usage)
146
+}
... ...
@@ -31,11 +31,7 @@ func (s *stringArrayValue) Append(val string) error {
31 31
 func (s *stringArrayValue) Replace(val []string) error {
32 32
 	out := make([]string, len(val))
33 33
 	for i, d := range val {
34
-		var err error
35 34
 		out[i] = d
36
-		if err != nil {
37
-			return err
38
-		}
39 35
 	}
40 36
 	*s.value = out
41 37
 	return nil
... ...
@@ -1107,7 +1107,7 @@ github.com/spdx/tools-golang/spdx/v2/v2_3
1107 1107
 # github.com/spf13/cobra v1.8.1
1108 1108
 ## explicit; go 1.15
1109 1109
 github.com/spf13/cobra
1110
-# github.com/spf13/pflag v1.0.5
1110
+# github.com/spf13/pflag v1.0.6
1111 1111
 ## explicit; go 1.12
1112 1112
 github.com/spf13/pflag
1113 1113
 # github.com/stretchr/testify v1.10.0