Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowing for the same flag to be set multiple times when using a conf… #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion extras.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ func (f *FlagSet) ParseFile(path string) error {
}
defer fp.Close()

// Allow multiple values for the same flag while still allowing arguments to take precedence.
// We create a temporary map that stores if an arg has already been set but won't be modified
// when we set args while parsing the file.
hasArg := make(map[string]bool)
for name := range f.actual {
hasArg[name] = true
}

scanner := bufio.NewScanner(fp)
for scanner.Scan() {
line := scanner.Text()
Expand Down Expand Up @@ -144,7 +152,7 @@ func (f *FlagSet) ParseFile(path string) error {
}

// Ignore flag when already set; arguments have precedence over file
if f.actual[name] != nil {
if hasArg[name] {
continue
}

Expand Down
22 changes: 22 additions & 0 deletions extras_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package flag_test

import (
"os"
"strings"
"syscall"
"testing"
"time"
Expand Down Expand Up @@ -71,6 +72,17 @@ func TestParseEnv(t *testing.T) {
}
}

type arrayFlags []string

func (i *arrayFlags) String() string {
return strings.Join(*i, " ")
}

func (i *arrayFlags) Set(value string) error {
*i = append(*i, value)
return nil
}

// Test parsing a configuration file
func TestParseFile(t *testing.T) {

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

multi := new(arrayFlags)
f.Var(multi, "multi", "Array flags value")

err := f.ParseFile("./testdata/test.conf")
if err != nil {
t.Fatal("expected no error; got ", err)
Expand Down Expand Up @@ -117,6 +132,10 @@ func TestParseFile(t *testing.T) {
if *durationFlag != 2*time.Minute {
t.Error("duration flag should be 2m, is ", *durationFlag)
}
if multi.String() != "hello world" {
t.Error("value of array flags should be hello world, is ", multi.String())
}

}

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

multi := new(arrayFlags)
f.Var(multi, "multi", "Array flags value")

f.String(DefaultConfigFlagname, "./testdata/test.conf", "config path")

if err := os.Unsetenv("STRING"); err != nil {
Expand Down
4 changes: 3 additions & 1 deletion testdata/test.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ uint 24
uint64 25
string hello
float64 2718e28
duration 2m
duration 2m
multi hello
multi world