diff --git a/config.go b/config.go index 59ff54a..3ead6f3 100644 --- a/config.go +++ b/config.go @@ -28,6 +28,9 @@ type LoadOptions struct { // Config name, default: config.yml, and type is YAML Name string + + // AllowEnv is whether to allow environment variables in the config file, default is false. + AllowEnv bool } // Load loads the config from the given file path. @@ -44,8 +47,9 @@ func Load(config any, options ...*LoadOptions) error { fileType := DefaultFileType filepathX := fs.JoinCurrentDir(".config.yml") + optionsX := &LoadOptions{} if len(options) > 0 && options[0] != nil { - optionsX := options[0] + optionsX = options[0] if optionsX.FilePath != "" { filepathX = optionsX.FilePath @@ -84,6 +88,10 @@ func Load(config any, options ...*LoadOptions) error { } if !fs.IsExist(filepathX) { + if optionsX.AllowEnv { + return Env(config) + } + return fmt.Errorf("config path (%s) not found", filepathX) } @@ -115,5 +123,13 @@ func Load(config any, options ...*LoadOptions) error { tg := tag.New("config", datasource.NewMapDataSource(configDataSource)) - return tg.Decode(config) + if err := tg.Decode(config); err != nil { + return err + } + + if optionsX.AllowEnv { + return Env(config) + } + + return nil } diff --git a/config_test.go b/config_test.go index 03ca35a..f161303 100644 --- a/config_test.go +++ b/config_test.go @@ -1,6 +1,7 @@ package config import ( + "os" "testing" ) @@ -33,6 +34,9 @@ type Config struct { Crypto string `config:"crypto"` // Actions map[string]Action `config:"actions"` + + // + AllowEnvValue string `config:"allow_env_value" env:"ALLOW_ENV_VALUE"` } type Action struct { @@ -118,3 +122,18 @@ func TestConfig(t *testing.T) { t.Fatal("actions.action1.socks5 is not empty string") } } + +func TestConfigAllowEnv(t *testing.T) { + var cfg Config + os.Setenv("ALLOW_ENV_VALUE", "value_from_env_with_allow_env") + if err := Load(&cfg, &LoadOptions{ + FilePath: "./testdata/config.yml", + AllowEnv: true, + }); err != nil { + t.Fatal(err) + } + + if cfg.AllowEnvValue != "value_from_env_with_allow_env" { + t.Fatalf("allow_env_value is not value_from_env_with_allow_env, but got %s", cfg.AllowEnvValue) + } +} diff --git a/env.go b/env.go new file mode 100644 index 0000000..b1dc63e --- /dev/null +++ b/env.go @@ -0,0 +1,25 @@ +package config + +import ( + "github.com/go-zoox/tag" + "github.com/go-zoox/tag/datasource" +) + +// Env loads the config from the environment variables. +// The config must be a pointer to a struct. +// Example: +// +// type Config struct { +// Host string `env:"HOST"` +// Port int `env:"PORT"` +// } +// +// var config Config +// if err := config.Env(&config); err != nil { +// log.Fatal(err) +// } +func Env(config interface{}) error { + tg := tag.New("env", datasource.NewEnvSource()) + + return tg.Decode(config) +} diff --git a/go.mod b/go.mod index aaa31f2..3724d7a 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,10 @@ module github.com/go-zoox/config go 1.18 require ( - github.com/go-zoox/core-utils v1.2.9 + github.com/go-zoox/core-utils v1.3.5 github.com/go-zoox/encoding v1.2.1 github.com/go-zoox/fs v1.3.13 - github.com/go-zoox/tag v1.2.2 + github.com/go-zoox/tag v1.2.7 ) require ( diff --git a/go.sum b/go.sum index 76a4a2d..e19dae8 100644 --- a/go.sum +++ b/go.sum @@ -12,17 +12,17 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-zoox/core-utils v1.2.9 h1:OEp4BEk/s/DAIqNz2hJC8fQJPlK9UyKz+BjcIwfkATk= -github.com/go-zoox/core-utils v1.2.9/go.mod h1:Y6izFcxuELrkOen5mTQccCJxJqqPJaZV5dQtUMBdkBM= +github.com/go-zoox/core-utils v1.3.5 h1:uxnPjUdo20ZCYCJp+1deuoqdMByTTJxQFrMp8e5ty+E= +github.com/go-zoox/core-utils v1.3.5/go.mod h1:raOOwr2l2sJQyjR0Dg33sg0ry4U1/L2eNTuLFRpUXWs= github.com/go-zoox/encoding v1.2.1 h1:38rQRsfL1f1YHZaqsPaGcNMkPnzatnPlYiHioUh9F4A= github.com/go-zoox/encoding v1.2.1/go.mod h1:NdcM7Ln73oVW3vJgx3MH4fJknCcdQfq+NgJ0tuCo7tU= github.com/go-zoox/fs v1.3.13 h1:fe0uvtXCM+9s51z/CnQ5kxB4hBYaK55tkrE9gq0385U= github.com/go-zoox/fs v1.3.13/go.mod h1:wCM+UQkjFTxNjOOCNlGcN3k9FeXXUwn9bFnpyjOn55c= github.com/go-zoox/ini v1.0.4 h1:N4mUbAO0juYIRrv3ysjKtpEn/+yQv57eQietsgpkAYQ= github.com/go-zoox/ini v1.0.4/go.mod h1:SisQneNLb1EBeZ5bA5GnrJd8FNg372hQrPh+gb3IzV4= -github.com/go-zoox/tag v1.2.2 h1:MLtfFEEBVwV3HVhgNHXGDl0Xv4h9hj1+6Hx9GaRHvFc= -github.com/go-zoox/tag v1.2.2/go.mod h1:z9z4iZb/XPE4HwTXJgPIdwgH90c2NysGxIMq9tW+GuU= -github.com/go-zoox/testify v1.0.0 h1:zXuj+JMcudM/dWk8HgMfCKpGYDcyHbTUBGxH35SGubU= +github.com/go-zoox/tag v1.2.7 h1:B+TLmlnm21YKZz+Ytmo4aiS1WhOc0pv+9IF2HodrGnM= +github.com/go-zoox/tag v1.2.7/go.mod h1:r8rpj8j4cFe2d79oXjbEVgy9bVAWUvvgRblYo8tyhig= +github.com/go-zoox/testify v1.0.2 h1:G5sQ3xm0uwCuytnMhgnqZ5BItCt2DN3n2wLBqlIJEWA= github.com/go-zoox/uuid v0.0.1 h1:txqmDavRTq68gzzqWfJQLorFyUp9a7M2lmq2KcwPGPA= github.com/go-zoox/uuid v0.0.1/go.mod h1:0/F4LdfLqFdyqOf7aXoiYXRkXHU324JQ5DZEytXYBPM= github.com/goccy/go-yaml v1.9.8 h1:5gMyLUeU1/6zl+WFfR1hN7D2kf+1/eRGa7DFtToiBvQ=