From c62770822d2135095a78555dee9ed01db6ea91ce Mon Sep 17 00:00:00 2001 From: John Peterson Date: Mon, 15 Jul 2024 15:28:07 -0600 Subject: [PATCH 1/2] Add functionality for parsing comma list value into a slice of strings --- env.go | 10 +++++++++ env_test.go | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 7 ++++++ go.sum | 9 ++++++++ 4 files changed, 91 insertions(+) diff --git a/env.go b/env.go index e9c75f7..034e87c 100644 --- a/env.go +++ b/env.go @@ -2,6 +2,7 @@ package env import ( "os" + "strings" "github.com/joho/godotenv" ) @@ -31,6 +32,15 @@ func GetWithFallback(key string, fallback string) string { return fallback } +// GetSliceWithFallback returns the value of a comma separated environment variable as a slice +// of strings or a fallback value if the environment variable is not set. +func GetSliceWithFallback(key string, fallback []string) []string { + if value, ok := Lookup(key); ok { + return strings.Split(value, ",") + } + return fallback +} + // GetBool returns the value of an environment variable as a boolean. func GetBool(key string) bool { return Get(key) == "true" diff --git a/env_test.go b/env_test.go index e000af7..d8621ab 100644 --- a/env_test.go +++ b/env_test.go @@ -3,6 +3,8 @@ package env import ( "os" "testing" + + "github.com/stretchr/testify/assert" ) func TestGetWithFallback(t *testing.T) { @@ -103,3 +105,66 @@ func TestGetBoolWithFallback(t *testing.T) { }) } } +func TestGetSliceWithFallback(t *testing.T) { + tests := []struct { + setValue bool + key string + fallback []string + envValue string + wantValue []string + }{ + { + setValue: true, + key: "EXISTING_KEY_SLICE_ONE_VALUE", + fallback: []string{"fallback_value_1"}, + envValue: "existing_value", + wantValue: []string{"existing_value"}, + }, + { + setValue: false, + key: "NON_EXISTING_KEY_SLICE", + fallback: []string{"fallback_value"}, + envValue: "", + wantValue: []string{"fallback_value"}, + }, + { + setValue: true, + key: "EMPTY_VALUE_KEY_SLICE", + fallback: []string{"fallback_value"}, + envValue: "", + wantValue: []string{""}, + }, + { + setValue: true, + key: "EXISTING_KEY_SLICE_MULTI_VALUE", + fallback: []string{"fallback_value_1", "fallback_value_2"}, + envValue: "existing_value_1,existing_value_2", + wantValue: []string{"existing_value_1", "existing_value_2"}, + }, + { + setValue: false, + key: "NON_EXISTING_KEY_SLICE_MULTI_VALUE", + fallback: []string{"fallback_value_1", "fallback_value_2"}, + envValue: "", + wantValue: []string{"fallback_value_1", "fallback_value_2"}, + }, + } + + for _, tt := range tests { + t.Run(tt.key, func(t *testing.T) { + // Set the environment variable + if tt.setValue { + os.Setenv(tt.key, tt.envValue) + } + + // Call the function under test + got := GetSliceWithFallback(tt.key, tt.fallback) + + // Check if the returned value matches the expected value + assert.ElementsMatch(t, tt.wantValue, got, "GetSliceWithFallback(%q, %q) should return expected slice elements, order ignored", tt.key, tt.fallback) + + // Unset the environment variable + os.Unsetenv(tt.key) + }) + } +} diff --git a/go.mod b/go.mod index 2e55ee9..9b599e7 100644 --- a/go.mod +++ b/go.mod @@ -3,3 +3,10 @@ module github.com/syntaqx/env go 1.22.3 require github.com/joho/godotenv v1.5.1 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.9.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum index d61b19e..7838054 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,11 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From b6e3d4286ea645590ca37b5a22da87642463a32d Mon Sep 17 00:00:00 2001 From: John Peterson Date: Mon, 15 Jul 2024 15:38:38 -0600 Subject: [PATCH 2/2] Update README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index f926ae1..895b597 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,11 @@ func main() { port := env.GetWithFallback("PORT", "8080") fmt.Printf("Port: %s\n", port) + + // Assuming the value of HOSTS is a comma separated list of strings + // Example: some-host:8000,another-host:8000 + hosts := env.GetSliceWithFallback("HOSTS", []string{"fallback-host-1:8000", "fallback-host-2:8000"}) + fmt.Printf("Hosts: %v\n", hosts) } ```