Skip to content

Commit c5a9f77

Browse files
authored
Merge pull request #4 from agorman/multi_line_config
Allowing for the same flag to be set multiple times when using a conf…
2 parents 6f3a2cf + f244bf6 commit c5a9f77

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

extras.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ func (f *FlagSet) ParseFile(path string) error {
114114
}
115115
defer fp.Close()
116116

117+
// Allow multiple values for the same flag while still allowing arguments to take precedence.
118+
// We create a temporary map that stores if an arg has already been set but won't be modified
119+
// when we set args while parsing the file.
120+
hasArg := make(map[string]bool)
121+
for name := range f.actual {
122+
hasArg[name] = true
123+
}
124+
117125
scanner := bufio.NewScanner(fp)
118126
for scanner.Scan() {
119127
line := scanner.Text()
@@ -144,7 +152,7 @@ func (f *FlagSet) ParseFile(path string) error {
144152
}
145153

146154
// Ignore flag when already set; arguments have precedence over file
147-
if f.actual[name] != nil {
155+
if hasArg[name] {
148156
continue
149157
}
150158

extras_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package flag_test
66

77
import (
88
"os"
9+
"strings"
910
"syscall"
1011
"testing"
1112
"time"
@@ -71,6 +72,17 @@ func TestParseEnv(t *testing.T) {
7172
}
7273
}
7374

75+
type arrayFlags []string
76+
77+
func (i *arrayFlags) String() string {
78+
return strings.Join(*i, " ")
79+
}
80+
81+
func (i *arrayFlags) Set(value string) error {
82+
*i = append(*i, value)
83+
return nil
84+
}
85+
7486
// Test parsing a configuration file
7587
func TestParseFile(t *testing.T) {
7688

@@ -86,6 +98,9 @@ func TestParseFile(t *testing.T) {
8698
float64Flag := f.Float64("float64", 0, "float64 value")
8799
durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value")
88100

101+
multi := new(arrayFlags)
102+
f.Var(multi, "multi", "Array flags value")
103+
89104
err := f.ParseFile("./testdata/test.conf")
90105
if err != nil {
91106
t.Fatal("expected no error; got ", err)
@@ -117,6 +132,10 @@ func TestParseFile(t *testing.T) {
117132
if *durationFlag != 2*time.Minute {
118133
t.Error("duration flag should be 2m, is ", *durationFlag)
119134
}
135+
if multi.String() != "hello world" {
136+
t.Error("value of array flags should be hello world, is ", multi.String())
137+
}
138+
120139
}
121140

122141
func TestParseFileUnknownFlag(t *testing.T) {
@@ -139,6 +158,9 @@ func TestDefaultConfigFlagname(t *testing.T) {
139158
f.Float64("float64", 0, "float64 value")
140159
f.Duration("duration", 5*time.Second, "time.Duration value")
141160

161+
multi := new(arrayFlags)
162+
f.Var(multi, "multi", "Array flags value")
163+
142164
f.String(DefaultConfigFlagname, "./testdata/test.conf", "config path")
143165

144166
if err := os.Unsetenv("STRING"); err != nil {

testdata/test.conf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ uint 24
88
uint64 25
99
string hello
1010
float64 2718e28
11-
duration 2m
11+
duration 2m
12+
multi hello
13+
multi world

0 commit comments

Comments
 (0)