From e30c1eeefd4f75bf73564c1443a37c6b4ce6da66 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Wed, 24 Sep 2014 16:29:47 -0700 Subject: [PATCH] pkg: move SetFlagsFromEnv to pkg package --- main.go | 23 +--------------------- main_test.go | 50 +++-------------------------------------------- pkg/flag.go | 22 +++++++++++++++++++++ pkg/flag_test.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ test | 4 ++-- 5 files changed, 79 insertions(+), 71 deletions(-) create mode 100644 pkg/flag_test.go diff --git a/main.go b/main.go index a7025271d..e2b4ac9bd 100644 --- a/main.go +++ b/main.go @@ -95,7 +95,7 @@ func main() { flag.Usage = pkg.UsageWithIgnoredFlagsFunc(flag.CommandLine, deprecated) flag.Parse() - SetFlagsFromEnv(flag.CommandLine) + pkg.SetFlagsFromEnv(flag.CommandLine) if string(*proxyFlag) == proxyFlagValueOff { startEtcd() @@ -328,24 +328,3 @@ func (pf *ProxyFlag) Set(s string) error { func (pf *ProxyFlag) String() string { return string(*pf) } - -// SetFlagsFromEnv parses all registered flags in the given flagset, -// and if they are not already set it attempts to set their values from -// environment variables. Environment variables take the name of the flag but -// are UPPERCASE, have the prefix "ETCD_", and any dashes are replaced by -// underscores - for example: some-flag => ETCD_SOME_FLAG -func SetFlagsFromEnv(fs *flag.FlagSet) { - alreadySet := make(map[string]bool) - fs.Visit(func(f *flag.Flag) { - alreadySet[f.Name] = true - }) - fs.VisitAll(func(f *flag.Flag) { - if !alreadySet[f.Name] { - key := "ETCD_" + strings.ToUpper(strings.Replace(f.Name, "-", "_", -1)) - val := os.Getenv(key) - if val != "" { - fs.Set(f.Name, val) - } - } - }) -} diff --git a/main_test.go b/main_test.go index 200b50969..46aa848d9 100644 --- a/main_test.go +++ b/main_test.go @@ -1,52 +1,8 @@ package main -import "os" -import "flag" -import "testing" - -func TestSetFlagsFromEnv(t *testing.T) { - fs := flag.NewFlagSet("testing", flag.ExitOnError) - fs.String("a", "", "") - fs.String("b", "", "") - fs.String("c", "", "") - fs.Parse([]string{}) - - os.Clearenv() - // flags should be settable using env vars - os.Setenv("ETCD_A", "foo") - // and command-line flags - if err := fs.Set("b", "bar"); err != nil { - t.Fatal(err) - } - // command-line flags take precedence over env vars - os.Setenv("ETCD_C", "woof") - if err := fs.Set("c", "quack"); err != nil { - t.Fatal(err) - } - - // first verify that flags are as expected before reading the env - for f, want := range map[string]string{ - "a": "", - "b": "bar", - "c": "quack", - } { - if got := fs.Lookup(f).Value.String(); got != want { - t.Fatalf("flag %q=%q, want %q", f, got, want) - } - } - - // now read the env and verify flags were updated as expected - SetFlagsFromEnv(fs) - for f, want := range map[string]string{ - "a": "foo", - "b": "bar", - "c": "quack", - } { - if got := fs.Lookup(f).Value.String(); got != want { - t.Errorf("flag %q=%q, want %q", f, got, want) - } - } -} +import ( + "testing" +) func TestProxyFlagSet(t *testing.T) { tests := []struct { diff --git a/pkg/flag.go b/pkg/flag.go index 225af0ce6..b09374268 100644 --- a/pkg/flag.go +++ b/pkg/flag.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "os" + "strings" ) type DeprecatedFlag struct { @@ -42,3 +43,24 @@ func UsageWithIgnoredFlagsFunc(fs *flag.FlagSet, ignore []string) func() { }) } } + +// SetFlagsFromEnv parses all registered flags in the given flagset, +// and if they are not already set it attempts to set their values from +// environment variables. Environment variables take the name of the flag but +// are UPPERCASE, have the prefix "ETCD_", and any dashes are replaced by +// underscores - for example: some-flag => ETCD_SOME_FLAG +func SetFlagsFromEnv(fs *flag.FlagSet) { + alreadySet := make(map[string]bool) + fs.Visit(func(f *flag.Flag) { + alreadySet[f.Name] = true + }) + fs.VisitAll(func(f *flag.Flag) { + if !alreadySet[f.Name] { + key := "ETCD_" + strings.ToUpper(strings.Replace(f.Name, "-", "_", -1)) + val := os.Getenv(key) + if val != "" { + fs.Set(f.Name, val) + } + } + }) +} diff --git a/pkg/flag_test.go b/pkg/flag_test.go new file mode 100644 index 000000000..0ae424e6d --- /dev/null +++ b/pkg/flag_test.go @@ -0,0 +1,51 @@ +package pkg + +import ( + "flag" + "os" + "testing" +) + +func TestSetFlagsFromEnv(t *testing.T) { + fs := flag.NewFlagSet("testing", flag.ExitOnError) + fs.String("a", "", "") + fs.String("b", "", "") + fs.String("c", "", "") + fs.Parse([]string{}) + + os.Clearenv() + // flags should be settable using env vars + os.Setenv("ETCD_A", "foo") + // and command-line flags + if err := fs.Set("b", "bar"); err != nil { + t.Fatal(err) + } + // command-line flags take precedence over env vars + os.Setenv("ETCD_C", "woof") + if err := fs.Set("c", "quack"); err != nil { + t.Fatal(err) + } + + // first verify that flags are as expected before reading the env + for f, want := range map[string]string{ + "a": "", + "b": "bar", + "c": "quack", + } { + if got := fs.Lookup(f).Value.String(); got != want { + t.Fatalf("flag %q=%q, want %q", f, got, want) + } + } + + // now read the env and verify flags were updated as expected + SetFlagsFromEnv(fs) + for f, want := range map[string]string{ + "a": "foo", + "b": "bar", + "c": "quack", + } { + if got := fs.Lookup(f).Value.String(); got != want { + t.Errorf("flag %q=%q, want %q", f, got, want) + } + } +} diff --git a/test b/test index f4b0a69ad..010635b58 100755 --- a/test +++ b/test @@ -15,9 +15,9 @@ COVER=${COVER:-"-cover"} source ./build # Hack: gofmt ./ will recursively check the .git directory. So use *.go for gofmt. -TESTABLE_AND_FORMATTABLE="client etcdserver etcdserver/etcdhttp etcdserver/etcdserverpb functional proxy raft snap store wait wal transport" +TESTABLE_AND_FORMATTABLE="client etcdserver etcdserver/etcdhttp etcdserver/etcdserverpb functional proxy raft snap store wait wal transport pkg" TESTABLE="$TESTABLE_AND_FORMATTABLE ./" -FORMATTABLE="$TESTABLE_AND_FORMATTABLE *.go pkg" +FORMATTABLE="$TESTABLE_AND_FORMATTABLE *.go" # user has not provided PKG override if [ -z "$PKG" ]; then