11package cluster
22
33import (
4+ "fmt"
45 "strconv"
56 "strings"
7+
8+ "github.com/alessio/shellescape"
9+ "github.com/k0sproject/k0sctl/internal/shell"
610)
711
812// Flags is a slice of strings with added functions to ease manipulating lists of command-line flags
913type Flags []string
1014
1115// Add adds a flag regardless if it exists already or not
1216func (f * Flags ) Add (s string ) {
17+ if ns , err := shell .Unquote (s ); err == nil {
18+ s = ns
19+ }
1320 * f = append (* f , s )
1421}
1522
1623// Add a flag with a value
1724func (f * Flags ) AddWithValue (key , value string ) {
18- * f = append (* f , key + " " + value )
25+ if nv , err := shell .Unquote (value ); err == nil {
26+ value = nv
27+ }
28+ * f = append (* f , key + "=" + value )
1929}
2030
2131// AddUnlessExist adds a flag unless one with the same prefix exists
2232func (f * Flags ) AddUnlessExist (s string ) {
33+ if ns , err := shell .Unquote (s ); err == nil {
34+ s = ns
35+ }
2336 if f .Include (s ) {
2437 return
2538 }
26- * f = append ( * f , s )
39+ f . Add ( s )
2740}
2841
2942// AddOrReplace replaces a flag with the same prefix or adds a new one if one does not exist
3043func (f * Flags ) AddOrReplace (s string ) {
44+ if ns , err := shell .Unquote (s ); err == nil {
45+ s = ns
46+ }
3147 idx := f .Index (s )
3248 if idx > - 1 {
3349 (* f )[idx ] = s
3450 return
3551 }
36- * f = append ( * f , s )
52+ f . Add ( s )
3753}
3854
3955// Include returns true if a flag with a matching prefix can be found
@@ -43,6 +59,9 @@ func (f Flags) Include(s string) bool {
4359
4460// Index returns an index to a flag with a matching prefix
4561func (f Flags ) Index (s string ) int {
62+ if ns , err := shell .Unquote (s ); err == nil {
63+ s = ns
64+ }
4665 var flag string
4766 sepidx := strings .IndexAny (s , "= " )
4867 if sepidx < 0 {
@@ -73,17 +92,16 @@ func (f Flags) GetValue(s string) string {
7392 if fl == "" {
7493 return ""
7594 }
95+ if nfl , err := shell .Unquote (fl ); err == nil {
96+ fl = nfl
97+ }
7698
7799 idx := strings .IndexAny (fl , "= " )
78100 if idx < 0 {
79101 return ""
80102 }
81103
82104 val := fl [idx + 1 :]
83- s , err := strconv .Unquote (val )
84- if err == nil {
85- return s
86- }
87105
88106 return val
89107}
@@ -137,5 +155,59 @@ func (f *Flags) MergeAdd(b Flags) {
137155
138156// Join creates a string separated by spaces
139157func (f * Flags ) Join () string {
140- return strings .Join (* f , " " )
158+ var parts []string
159+ f .Each (func (k , v string ) {
160+ if v == "" && k != "" {
161+ parts = append (parts , shellescape .Quote (k ))
162+ } else {
163+ parts = append (parts , fmt .Sprintf ("%s=%s" , k , shellescape .Quote (v )))
164+ }
165+ })
166+ return strings .Join (parts , " " )
167+ }
168+
169+ // Each iterates over each flag and calls the function with the flag key and value as arguments
170+ func (f Flags ) Each (fn func (string , string )) {
171+ for _ , flag := range f {
172+ sepidx := strings .IndexAny (flag , "= " )
173+ if sepidx < 0 {
174+ if flag == "" {
175+ continue
176+ }
177+ fn (flag , "" )
178+ } else {
179+ key , value := flag [:sepidx ], flag [sepidx + 1 :]
180+ if unq , err := shell .Unquote (value ); err == nil {
181+ value = unq
182+ }
183+ fn (key , value )
184+ }
185+ }
186+ }
187+
188+ // Map returns a map[string]string of the flags where the key is the flag and the value is the value
189+ func (f Flags ) Map () map [string ]string {
190+ res := make (map [string ]string )
191+ f .Each (func (k , v string ) {
192+ res [k ] = v
193+ })
194+ return res
195+ }
196+
197+ // Equals compares the flags with another Flags and returns true if they have the same flags and values, ignoring order
198+ func (f Flags ) Equals (b Flags ) bool {
199+ if len (f ) != len (b ) {
200+ return false
201+ }
202+ for _ , flag := range f {
203+ if ! b .Include (flag ) {
204+ return false
205+ }
206+ ourValue := f .GetValue (flag )
207+ theirValue := b .GetValue (flag )
208+ if ourValue != theirValue {
209+ return false
210+ }
211+ }
212+ return true
141213}
0 commit comments