From 64ce431dfafb32661b64596fe46ce3a479cd2613 Mon Sep 17 00:00:00 2001 From: Daniel Sutto <28776655+suttod@users.noreply.github.com> Date: Wed, 7 Jun 2023 22:37:04 +0200 Subject: [PATCH 1/5] Load content of .env file before merging env --- cobrautil.go | 19 +++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ 3 files changed, 22 insertions(+) diff --git a/cobrautil.go b/cobrautil.go index 2bed329..6120272 100644 --- a/cobrautil.go +++ b/cobrautil.go @@ -2,8 +2,10 @@ package cobrautil import ( "fmt" + "os" "strings" + "github.com/joho/godotenv" "github.com/jzelinskie/stringz" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -21,6 +23,21 @@ func IsBuiltinCommand(cmd *cobra.Command) bool { ) } +// Read dotenv files according to conventions +func ReadDotEnv(prefix string) { + env := os.Getenv(prefix + "_ENV") + if env == "" { + env = "development" + } + + godotenv.Load(".env." + env + ".local") + if env != "test" { + godotenv.Load(".env.local") + } + godotenv.Load(".env." + env) + godotenv.Load() // The Original .env +} + // SyncViperPreRunE returns a Cobra run func that synchronizes Viper environment // flags prefixed with the provided argument. // @@ -32,6 +49,8 @@ func SyncViperPreRunE(prefix string) CobraRunFunc { return nil // No-op for builtins } + ReadDotEnv(prefix) + v := viper.New() v.AllowEmptyEnv(true) viper.SetEnvPrefix(prefix) diff --git a/go.mod b/go.mod index 9941b1f..00b5d84 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect diff --git a/go.sum b/go.sum index 3b48dc2..d45d177 100644 --- a/go.sum +++ b/go.sum @@ -158,6 +158,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jzelinskie/stringz v0.0.1 h1:IahR+y8ct2nyj7B6i8UtFsGFj4ex1SX27iKFYsAheLk= From 184d6db27d88ebf04d48e407246c8c0077c6e3a9 Mon Sep 17 00:00:00 2001 From: Daniel Sutto <28776655+suttod@users.noreply.github.com> Date: Wed, 21 Jun 2023 23:34:32 +0200 Subject: [PATCH 2/5] split env file loading to separate function --- cobrautil.go | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/cobrautil.go b/cobrautil.go index 6120272..cc6f2d9 100644 --- a/cobrautil.go +++ b/cobrautil.go @@ -2,7 +2,6 @@ package cobrautil import ( "fmt" - "os" "strings" "github.com/joho/godotenv" @@ -23,21 +22,6 @@ func IsBuiltinCommand(cmd *cobra.Command) bool { ) } -// Read dotenv files according to conventions -func ReadDotEnv(prefix string) { - env := os.Getenv(prefix + "_ENV") - if env == "" { - env = "development" - } - - godotenv.Load(".env." + env + ".local") - if env != "test" { - godotenv.Load(".env.local") - } - godotenv.Load(".env." + env) - godotenv.Load() // The Original .env -} - // SyncViperPreRunE returns a Cobra run func that synchronizes Viper environment // flags prefixed with the provided argument. // @@ -49,8 +33,6 @@ func SyncViperPreRunE(prefix string) CobraRunFunc { return nil // No-op for builtins } - ReadDotEnv(prefix) - v := viper.New() v.AllowEmptyEnv(true) viper.SetEnvPrefix(prefix) @@ -69,6 +51,19 @@ func SyncViperPreRunE(prefix string) CobraRunFunc { } } +// SyncViperPreRunEWithFiles returns a Cobra run func that synchronizes +// Viper environment flags prefixed with the provided argument. +// +// If envfile is not an empty string, it should contain a path of a dotenv file. +// Viper will load environment variables from file with lower precedence, +// than env of the process. +func SyncViperPreRunEWithFile(prefix string, envfile string) CobraRunFunc { + if envfile != "" { + godotenv.Load(envfile) + } + return SyncViperPreRunE(prefix) +} + // CobraRunFunc is the signature of cobra.Command RunFuncs. type CobraRunFunc func(cmd *cobra.Command, args []string) error From 52be2e8391b5568ffcec09146dc4f9f0196f0f00 Mon Sep 17 00:00:00 2001 From: Daniel Sutto <28776655+suttod@users.noreply.github.com> Date: Thu, 6 Jul 2023 08:08:00 +0200 Subject: [PATCH 3/5] load .env by default --- cobrautil.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cobrautil.go b/cobrautil.go index cc6f2d9..bd59a49 100644 --- a/cobrautil.go +++ b/cobrautil.go @@ -51,16 +51,18 @@ func SyncViperPreRunE(prefix string) CobraRunFunc { } } -// SyncViperPreRunEWithFiles returns a Cobra run func that synchronizes +// SyncViperDotEnvPreRunE returns a Cobra run func that synchronizes // Viper environment flags prefixed with the provided argument. // // If envfile is not an empty string, it should contain a path of a dotenv file. +// In case of an empty string, ./.evn is loaded. // Viper will load environment variables from file with lower precedence, // than env of the process. -func SyncViperPreRunEWithFile(prefix string, envfile string) CobraRunFunc { - if envfile != "" { - godotenv.Load(envfile) +func SyncViperDotEnvPreRunE(prefix string, envfile string) CobraRunFunc { + if envfile == "" { + envfile = ".env" } + godotenv.Load(envfile) return SyncViperPreRunE(prefix) } From f5e4f28c86dc4503d8422655c504f5207f63c40e Mon Sep 17 00:00:00 2001 From: Daniel Sutto <28776655+suttod@users.noreply.github.com> Date: Thu, 6 Jul 2023 08:11:47 +0200 Subject: [PATCH 4/5] go mod tidy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 00b5d84..34fe32a 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.18 require ( github.com/go-logr/logr v1.2.3 + github.com/joho/godotenv v1.5.1 github.com/jzelinskie/stringz v0.0.1 github.com/mattn/go-isatty v0.0.16 github.com/rs/zerolog v1.28.0 @@ -29,7 +30,6 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/joho/godotenv v1.5.1 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect From 436564f320fe09fde7dc4af675fe650386d1f506 Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Fri, 14 Jul 2023 10:09:58 -0700 Subject: [PATCH 5/5] dotenv: tidying up and handling the error --- cobrautil.go | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/cobrautil.go b/cobrautil.go index bd59a49..ef255a3 100644 --- a/cobrautil.go +++ b/cobrautil.go @@ -22,8 +22,8 @@ func IsBuiltinCommand(cmd *cobra.Command) bool { ) } -// SyncViperPreRunE returns a Cobra run func that synchronizes Viper environment -// flags prefixed with the provided argument. +// SyncViperPreRunE returns a CobraRunFunc that synchronizes Viper environment +// flags with the provided prefix. // // Thanks to Carolyn Van Slyck: https://github.com/carolynvs/stingoftheviper func SyncViperPreRunE(prefix string) CobraRunFunc { @@ -51,19 +51,18 @@ func SyncViperPreRunE(prefix string) CobraRunFunc { } } -// SyncViperDotEnvPreRunE returns a Cobra run func that synchronizes -// Viper environment flags prefixed with the provided argument. +// SyncViperDotEnvPreRunE returns a CobraRunFunc that loads a .dotenv file +// before synchronizing Viper environment flags with the provided prefix. // -// If envfile is not an empty string, it should contain a path of a dotenv file. -// In case of an empty string, ./.evn is loaded. -// Viper will load environment variables from file with lower precedence, -// than env of the process. -func SyncViperDotEnvPreRunE(prefix string, envfile string) CobraRunFunc { - if envfile == "" { - envfile = ".env" +// If empty, envfilePath defaults to ".env". +// The .dotenv file is loaded first before any additional Viper behavior. +func SyncViperDotEnvPreRunE(prefix string, envfilePath string) CobraRunFunc { + return func(cmd *cobra.Command, args []string) error { + if err := godotenv.Load(stringz.DefaultEmpty(envfilePath, ".env")); err != nil { + return err + } + return SyncViperPreRunE(prefix)(cmd, args) } - godotenv.Load(envfile) - return SyncViperPreRunE(prefix) } // CobraRunFunc is the signature of cobra.Command RunFuncs.