Skip to content

Commit

Permalink
feat(envs): add function to parse without prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
henrybarreto authored and gustavosbarreto committed Nov 7, 2023
1 parent 0a69863 commit bce9204
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 1 deletion.
21 changes: 21 additions & 0 deletions pkg/envs/envs.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,24 @@ func ParseWithPrefix[T any](prefix string) (*T, error) {

return envs, nil
}

var ErrParse = errors.New("failed to parse environment variables")

// Parse parses the environment variables.
//
// This function uses the [envconfig] package as its default backend, so it requires the struct to be annotated with
// the [envconfig] tags. Check the [envconfig] documentation for more information.
//
// The T generic parameter must be a struct with the fields annotated with the [envconfig] tags, that will be returned
// with the values parsed from the environment variables.
//
// [envconfig]: https://github.com/sethvargo/go-envconfig
func Parse[T any]() (*T, error) {
envs := new(T)

if err := DefaultBackend.Process("", envs); err != nil {
return nil, errors.Join(ErrParse, err)
}

return envs, nil
}
153 changes: 152 additions & 1 deletion pkg/envs/envs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func TestParseWithPrefix_with_default(t *testing.T) {
}
}

func TestParse_with_required(t *testing.T) {
func TestParseWithPrefix_with_required(t *testing.T) {
type Envs struct {
RedisURI string `env:"REDIS_URI,required"`
MongoURI string `env:"MONGO_URI,required"`
Expand Down Expand Up @@ -210,3 +210,154 @@ func TestParse_with_required(t *testing.T) {
})
}
}

func TestParse_with_default(t *testing.T) {
type Envs struct {
RedisURI string `env:"REDIS_URI,default=redis://redis:6379/default"`
MongoURI string `env:"MONGO_URI,default=mongodb://mongo:27017/default"`
}

type Expected struct {
Envs *Envs
Error error
}

tests := []struct {
description string
before func()
after func()
expected Expected
}{
{
description: "parse envs",
before: func() {
os.Setenv("REDIS_URI", "redis://redis:6379/test")
os.Setenv("MONGO_URI", "mongodb://mongo:27017/test")
},
after: func() {
os.Unsetenv("REDIS_URI")
os.Unsetenv("MONGO_URI")
},
expected: Expected{
Envs: &Envs{
RedisURI: "redis://redis:6379/test",
MongoURI: "mongodb://mongo:27017/test",
},
Error: nil,
},
},
{
description: "parse envs with one set and one default",
before: func() {
os.Setenv("REDIS_URI", "redis://redis:6379/test")
},
after: func() {
os.Unsetenv("REDIS_URI")
},
expected: Expected{
Envs: &Envs{
RedisURI: "redis://redis:6379/test",
MongoURI: "mongodb://mongo:27017/default",
},
Error: nil,
},
},
{
description: "parse envs with all default",
before: func() {},
after: func() {},
expected: Expected{
Envs: &Envs{
RedisURI: "redis://redis:6379/default",
MongoURI: "mongodb://mongo:27017/default",
},
Error: nil,
},
},
}

for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
tt.before()

envs, err := Parse[Envs]()
assert.Equal(t, tt.expected.Envs, envs)
assert.ErrorIs(t, err, tt.expected.Error)

tt.after()
})
}
}

func TestParse_with_required(t *testing.T) {
type Envs struct {
RedisURI string `env:"REDIS_URI,required"`
MongoURI string `env:"MONGO_URI,required"`
}

type Expected struct {
Envs *Envs
Error error
}

tests := []struct {
description string
before func()
after func()
expected Expected
}{
{
description: "parse envs",
before: func() {
os.Setenv("REDIS_URI", "redis://redis:6379/test")
os.Setenv("MONGO_URI", "mongodb://mongo:27017/test")
},
after: func() {
os.Unsetenv("REDIS_URI")
os.Unsetenv("MONGO_URI")
},
expected: Expected{
Envs: &Envs{
RedisURI: "redis://redis:6379/test",
MongoURI: "mongodb://mongo:27017/test",
},
Error: nil,
},
},
{
description: "fail to parse envs when one env is missing",
before: func() {
os.Setenv("REDIS_URI", "redis://redis:6379/test")
},
after: func() {
os.Unsetenv("REDIS_URI")
},
expected: Expected{
Error: ErrParse,
},
},
{
description: "fails to parse when all envs are missing",
before: func() {
},
after: func() {
},
expected: Expected{
Envs: nil,
Error: ErrParse,
},
},
}

for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
tt.before()

envs, err := Parse[Envs]()
assert.Equal(t, tt.expected.Envs, envs)
assert.ErrorIs(t, err, tt.expected.Error)

tt.after()
})
}
}

0 comments on commit bce9204

Please sign in to comment.