Skip to content

Commit 91e63de

Browse files
jbdoumenjoutraefiker
authored andcommitted
Apply the case of the CLI flags for the configuration
1 parent cd164de commit 91e63de

File tree

5 files changed

+171
-40
lines changed

5 files changed

+171
-40
lines changed

pkg/cli/commands_test.go

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -625,46 +625,62 @@ func Test_execute_configuration(t *testing.T) {
625625
}
626626

627627
func Test_execute_configuration_file(t *testing.T) {
628-
rootCmd := &Command{
629-
Name: "root",
630-
Description: "This is a test",
631-
Configuration: nil,
632-
Run: func(_ []string) error {
633-
return nil
628+
testCases := []struct {
629+
desc string
630+
args []string
631+
}{
632+
{
633+
desc: "configFile arg in camel case",
634+
args: []string{"", "sub1", "--configFile=./fixtures/config.toml"},
634635
},
635-
}
636-
637-
element := &Yo{
638-
Fuu: "test",
639-
}
640-
641-
sub1 := &Command{
642-
Name: "sub1",
643-
Description: "sub1",
644-
Configuration: element,
645-
Resources: []ResourceLoader{&FileLoader{}, &FlagLoader{}},
646-
Run: func(args []string) error {
647-
return nil
636+
{
637+
desc: "configfile arg in lower case",
638+
args: []string{"", "sub1", "--configfile=./fixtures/config.toml"},
648639
},
649640
}
650-
err := rootCmd.AddCommand(sub1)
651-
require.NoError(t, err)
652641

653-
args := []string{"", "sub1", "--configFile=./fixtures/config.toml"}
642+
for _, test := range testCases {
643+
t.Run(test.desc, func(t *testing.T) {
644+
rootCmd := &Command{
645+
Name: "root",
646+
Description: "This is a test",
647+
Configuration: nil,
648+
Run: func(_ []string) error {
649+
return nil
650+
},
651+
}
654652

655-
err = execute(rootCmd, args, true)
656-
require.NoError(t, err)
653+
element := &Yo{
654+
Fuu: "test",
655+
}
657656

658-
expected := &Yo{
659-
Foo: "bar",
660-
Fii: "bir",
661-
Fuu: "test",
662-
Yi: &Yi{
663-
Foo: "foo",
664-
Fii: "fii",
665-
},
657+
sub1 := &Command{
658+
Name: "sub1",
659+
Description: "sub1",
660+
Configuration: element,
661+
Resources: []ResourceLoader{&FileLoader{}, &FlagLoader{}},
662+
Run: func(args []string) error {
663+
return nil
664+
},
665+
}
666+
err := rootCmd.AddCommand(sub1)
667+
require.NoError(t, err)
668+
669+
err = execute(rootCmd, test.args, true)
670+
require.NoError(t, err)
671+
672+
expected := &Yo{
673+
Foo: "bar",
674+
Fii: "bir",
675+
Fuu: "test",
676+
Yi: &Yi{
677+
Foo: "foo",
678+
Fii: "fii",
679+
},
680+
}
681+
assert.Equal(t, expected, element)
682+
})
666683
}
667-
assert.Equal(t, expected, element)
668684
}
669685

670686
func Test_execute_help(t *testing.T) {

pkg/cli/loader_file.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,15 @@ func (f *FileLoader) Load(args []string, cmd *Command) (bool, error) {
3030
}
3131

3232
configFileFlag := "traefik.configfile"
33+
if _, ok := ref["traefik.configFile"]; ok {
34+
configFileFlag = "traefik.configFile"
35+
}
36+
3337
if f.ConfigFileFlag != "" {
34-
configFileFlag = "traefik." + strings.ToLower(f.ConfigFileFlag)
38+
configFileFlag = "traefik." + f.ConfigFileFlag
39+
if _, ok := ref[strings.ToLower(configFileFlag)]; ok {
40+
configFileFlag = "traefik." + strings.ToLower(f.ConfigFileFlag)
41+
}
3542
}
3643

3744
configFile, err := loadConfigFiles(ref[configFileFlag], cmd.Configuration)

pkg/config/flag/flag_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,20 @@ func TestDecode(t *testing.T) {
136136
},
137137
},
138138
},
139+
{
140+
desc: "map string case sensitive",
141+
args: []string{"--foo.caseSensitiveName=barBoo"},
142+
element: &struct {
143+
Foo map[string]string
144+
}{},
145+
expected: &struct {
146+
Foo map[string]string
147+
}{
148+
Foo: map[string]string{
149+
"caseSensitiveName": "barBoo",
150+
},
151+
},
152+
},
139153
{
140154
desc: "map struct",
141155
args: []string{"--foo.name.value=bar"},

pkg/config/flag/flagparser.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ func Parse(args []string, element interface{}) (map[string]string, error) {
1616
flagTypes: getFlagTypes(element),
1717
args: args,
1818
values: make(map[string]string),
19+
keys: make(map[string]string),
1920
}
2021

2122
for {
@@ -35,6 +36,7 @@ type flagSet struct {
3536
flagTypes map[string]reflect.Kind
3637
args []string
3738
values map[string]string
39+
keys map[string]string
3840
}
3941

4042
func (f *flagSet) parseOne() (bool, error) {
@@ -78,7 +80,8 @@ func (f *flagSet) parseOne() (bool, error) {
7880
return true, nil
7981
}
8082

81-
if f.flagTypes[name] == reflect.Bool || f.flagTypes[name] == reflect.Ptr {
83+
n := strings.ToLower(name)
84+
if f.flagTypes[n] == reflect.Bool || f.flagTypes[n] == reflect.Ptr {
8285
f.setValue(name, "true")
8386
return true, nil
8487
}
@@ -98,13 +101,20 @@ func (f *flagSet) parseOne() (bool, error) {
98101
}
99102

100103
func (f *flagSet) setValue(name string, value string) {
101-
n := strings.ToLower(parser.DefaultRootName + "." + name)
102-
v, ok := f.values[n]
104+
srcKey := parser.DefaultRootName + "." + name
105+
neutralKey := strings.ToLower(srcKey)
103106

104-
if ok && f.flagTypes[name] == reflect.Slice {
105-
f.values[n] = v + "," + value
107+
key, ok := f.keys[neutralKey]
108+
if !ok {
109+
f.keys[neutralKey] = srcKey
110+
key = srcKey
111+
}
112+
113+
v, ok := f.values[key]
114+
if ok && f.flagTypes[strings.ToLower(name)] == reflect.Slice {
115+
f.values[key] = v + "," + value
106116
return
107117
}
108118

109-
f.values[n] = value
119+
f.values[key] = value
110120
}

pkg/config/flag/flagparser_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ func TestParse(t *testing.T) {
2929
"traefik.foo": "true",
3030
},
3131
},
32+
{
33+
desc: "bool value capitalized",
34+
args: []string{"--Foo"},
35+
element: &struct {
36+
Foo bool
37+
}{},
38+
expected: map[string]string{
39+
"traefik.Foo": "true",
40+
},
41+
},
3242
{
3343
desc: "equal",
3444
args: []string{"--foo=bar"},
@@ -39,6 +49,16 @@ func TestParse(t *testing.T) {
3949
"traefik.foo": "bar",
4050
},
4151
},
52+
{
53+
desc: "equal",
54+
args: []string{"--Foo=Bar"},
55+
element: &struct {
56+
Foo string
57+
}{},
58+
expected: map[string]string{
59+
"traefik.Foo": "Bar",
60+
},
61+
},
4262
{
4363
desc: "space separated",
4464
args: []string{"--foo", "bar"},
@@ -49,6 +69,16 @@ func TestParse(t *testing.T) {
4969
"traefik.foo": "bar",
5070
},
5171
},
72+
{
73+
desc: "space separated capitalized",
74+
args: []string{"--Foo", "Bar"},
75+
element: &struct {
76+
Foo string
77+
}{},
78+
expected: map[string]string{
79+
"traefik.Foo": "Bar",
80+
},
81+
},
5282
{
5383
desc: "space separated with end of parameter",
5484
args: []string{"--foo=bir", "--", "--bar"},
@@ -91,6 +121,16 @@ func TestParse(t *testing.T) {
91121
"traefik.foo.name": "bar",
92122
},
93123
},
124+
{
125+
desc: "map string capitalized",
126+
args: []string{"--foo.Name=Bar"},
127+
element: &struct {
128+
Foo map[string]string
129+
}{},
130+
expected: map[string]string{
131+
"traefik.foo.Name": "Bar",
132+
},
133+
},
94134
{
95135
desc: "map struct",
96136
args: []string{"--foo.name.value=bar"},
@@ -199,6 +239,50 @@ func TestParse(t *testing.T) {
199239
"traefik.foo": "true",
200240
},
201241
},
242+
{
243+
desc: "map string case sensitive",
244+
args: []string{"--foo.caseSensitiveName=barBoo"},
245+
element: &struct {
246+
Foo map[string]string
247+
}{},
248+
expected: map[string]string{
249+
"traefik.foo.caseSensitiveName": "barBoo",
250+
},
251+
},
252+
{
253+
desc: "map struct with sub-map case senstitive",
254+
args: []string{"--foo.Name1.bar.name2.value=firstValue", "--foo.naMe1.bar.name2.value=secondValue"},
255+
element: &struct {
256+
Foo map[string]struct {
257+
Bar map[string]struct{ Value string }
258+
}
259+
}{},
260+
expected: map[string]string{
261+
"traefik.foo.Name1.bar.name2.value": "secondValue",
262+
},
263+
},
264+
{
265+
desc: "map struct with sub-map and different case",
266+
args: []string{"--foo.Name1.bar.name2.value=firstValue", "--foo.naMe1.bar.name2.value=secondValue"},
267+
element: &struct {
268+
Foo map[string]struct {
269+
Bar map[string]struct{ Value string }
270+
}
271+
}{},
272+
expected: map[string]string{
273+
"traefik.foo.Name1.bar.name2.value": "secondValue",
274+
},
275+
},
276+
{
277+
desc: "slice with several flags 2 and different cases.",
278+
args: []string{"--foo", "bar", "--Foo", "baz"},
279+
element: &struct {
280+
Foo []string
281+
}{},
282+
expected: map[string]string{
283+
"traefik.foo": "bar,baz",
284+
},
285+
},
202286
}
203287

204288
for _, test := range testCases {

0 commit comments

Comments
 (0)