Skip to content

Commit

Permalink
utils/cobrautil(bind): implementation based on Replace(val []string) …
Browse files Browse the repository at this point in the history
…with tests
  • Loading branch information
mmatczuk committed Sep 6, 2023
1 parent 8fe63cc commit 00fe2eb
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 8 deletions.
28 changes: 20 additions & 8 deletions utils/cobrautil/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"fmt"
"strings"

"github.com/spf13/cast"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
Expand Down Expand Up @@ -55,8 +56,8 @@ func BindAll(cmd *cobra.Command, envPrefix, configFileFlagName string) error {
ok = true
fs.VisitAll(func(f *pflag.Flag) {
if !f.Changed && v.IsSet(f.Name) {
if err := setFlagFromViper(f, fs, v.Get(f.Name)); err != nil {
fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
if err := setFlagFromViper(f, v.Get(f.Name)); err != nil {
fmt.Fprintf(cmd.ErrOrStderr(), "%s: %s\n", f.Name, err)
ok = false
}
}
Expand All @@ -75,11 +76,22 @@ func BindAll(cmd *cobra.Command, envPrefix, configFileFlagName string) error {
return nil
}

func setFlagFromViper(f *pflag.Flag, fs *pflag.FlagSet, v any) error {
s := fmt.Sprintf("%v", v)
s = strings.TrimPrefix(s, "[")
s = strings.TrimSuffix(s, "]")
s = strings.NewReplacer(", ", ",", " ", ",").Replace(s)
func setFlagFromViper(f *pflag.Flag, v any) error {
if vs, ok := v.([]interface{}); ok {
sr, ok := f.Value.(sliceReplacer)
if !ok {
return fmt.Errorf("trying to set list to %s", f.Value.Type())
}
ss, err := cast.ToStringSliceE(vs)
if err != nil {
return err
}
return sr.Replace(ss)
}

return f.Value.Set(fmt.Sprintf("%v", v))
}

return fs.Set(f.Name, s)
type sliceReplacer interface {
Replace(val []string) error
}
66 changes: 66 additions & 0 deletions utils/cobrautil/bind_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2023 Sauce Labs Inc. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

package cobrautil

import (
"net/netip"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/mmatczuk/anyflag"
"github.com/spf13/cobra"
)

type testSliceStruct struct {
Strings []string
Ints []int
Bools []bool
IPs []netip.Addr
}

func TestBindSlice(t *testing.T) {
formats := []string{
"yaml",
"json",
"toml",
}

for _, ext := range formats {
t.Run(ext, func(t *testing.T) {
cmd := &cobra.Command{}
fs := cmd.Flags()

var v testSliceStruct
fs.String("config-file", "testdata/bind-slice."+ext, "")
fs.StringSliceVar(&v.Strings, "strings", nil, "")
fs.IntSliceVar(&v.Ints, "ints", nil, "")
fs.BoolSliceVar(&v.Bools, "bools", nil, "")
fs.Var(anyflag.NewSliceValue[netip.Addr](nil, &v.IPs, netip.ParseAddr), "ips", "")

if err := BindAll(cmd, "TEST", "config-file"); err != nil {
t.Fatal(err)
}

expected := testSliceStruct{
Strings: []string{"a", "b", "c"},
Ints: []int{1, 2, 3},
Bools: []bool{true, false},
IPs: []netip.Addr{
netip.MustParseAddr("127.0.0.1"),
netip.MustParseAddr("127.0.0.2"),
},
}

ipcmp := cmp.Comparer(func(a, b netip.Addr) bool {
return a.String() == b.String()
})
if diff := cmp.Diff(expected, v, ipcmp); diff != "" {
t.Fatalf("unexpected result (-want +got):\n%s", diff)
}
})
}
}
6 changes: 6 additions & 0 deletions utils/cobrautil/testdata/bind-slice.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"strings": ["a", "b", "c"],
"ints": [1, 2, 3],
"bools": [true, false],
"ips": ["127.0.0.1", "127.0.0.2"]
}
4 changes: 4 additions & 0 deletions utils/cobrautil/testdata/bind-slice.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
strings = ["a", "b", "c"]
ints = [1, 2, 3]
bools = [true, false]
ips = ["127.0.0.1", "127.0.0.2"]
17 changes: 17 additions & 0 deletions utils/cobrautil/testdata/bind-slice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
strings:
- a
- b
- c

ints:
- 1
- 2
- 3

bools:
- true
- false

ips:
- 127.0.0.1
- 127.0.0.2

0 comments on commit 00fe2eb

Please sign in to comment.