Skip to content

Commit

Permalink
add Get helper
Browse files Browse the repository at this point in the history
  • Loading branch information
ysmood committed Dec 7, 2023
1 parent e16cbf1 commit ad8230f
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 10 deletions.
3 changes: 2 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
VALUE="ok"
NUM="1"
STR="hello"
10 changes: 8 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ linters:
- paralleltest
- gochecknoglobals
- varnamelen
- forcetypeassert
- ireturn

- structcheck
- interfacer
Expand All @@ -23,8 +25,12 @@ linters:
- nosnakecase
- scopelint

gocyclo:
min-complexity: 15
linters-settings:
gocyclo:
min-complexity: 15

cyclop:
max-complexity: 20

issues:
exclude-use-default: false
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Load the `.env` file from current directory or one of the parent directories, then use it to set the process environment variables.

It also provides a function to parse the value of environment variables, it uses generics so you don't need to cast the value manually.

For usage check the [example](example/basic.go).

About the format of `.env`: [link](https://docs.docker.com/compose/environment-variables/env-file/)
5 changes: 5 additions & 0 deletions dotenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@ func init() {

lg.Println(msg)
}

// Get is a shortcut for [lib.Get].
func Get[T lib.EnvType](name string, defaultVal T) T {
return lib.Get(name, defaultVal)
}
12 changes: 8 additions & 4 deletions example/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ package main

import (
"fmt"
"os"

_ "github.com/ysmood/dotenv"
dotenv "github.com/ysmood/dotenv"
)

func main() {
// It will output the VALUE in "../.env" which is "ok"
fmt.Println(os.Getenv("VALUE"))
num := dotenv.Get("NUM", 0)
str := dotenv.Get("STR", "")

// It will output the env variables in "../.env"
// The output will be:
// 2 hello world
fmt.Println(num+1, str+" world")
}
9 changes: 7 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
module github.com/ysmood/dotenv

go 1.20
go 1.21

require github.com/joho/godotenv v1.5.1
require (
github.com/joho/godotenv v1.5.1
github.com/ysmood/got v0.38.2
)

require github.com/ysmood/gop v0.2.0 // indirect
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/ysmood/gop v0.2.0 h1:+tFrG0TWPxT6p9ZaZs+VY+opCvHU8/3Fk6BaNv6kqKg=
github.com/ysmood/gop v0.2.0/go.mod h1:rr5z2z27oGEbyB787hpEcx4ab8cCiPnKxn0SUHt6xzk=
github.com/ysmood/got v0.38.2 h1:h2RYvAe5nIK+oBRMLzNIrkZaX5kjmkOBqfRMIsFzLyU=
github.com/ysmood/got v0.38.2/go.mod h1:W7DdpuX6skL3NszLmAsC5hT7JAhuLZhByVzHTq874Qg=
55 changes: 55 additions & 0 deletions lib/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"os"
"path/filepath"
"strconv"
"time"

"github.com/joho/godotenv"
)
Expand Down Expand Up @@ -45,3 +47,56 @@ func LookupFile(file string) string {

return ""
}

type EnvType interface {
bool | string | int | float64 | time.Duration
}

// Get env var with default value.
func Get[T EnvType](name string, defaultVal T) T {
envStr, has := os.LookupEnv(name)
if !has {
return defaultVal
}

var v any = defaultVal

switch v.(type) {
case bool:
b, err := strconv.ParseBool(envStr)
if err != nil {
panic(err)
}

v = b

case string:
v = envStr

case int:
i, err := strconv.ParseInt(envStr, 10, 64)
if err != nil {
panic(err)
}

v = int(i)

case float64:
f, err := strconv.ParseFloat(envStr, 64)
if err != nil {
panic(err)
}

v = f

case time.Duration:
d, err := time.ParseDuration(envStr)
if err != nil {
panic(err)
}

v = d
}

return v.(T)
}
30 changes: 30 additions & 0 deletions lib/lib_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package lib_test

import (
"testing"
"time"

"github.com/ysmood/dotenv/lib"
"github.com/ysmood/got"
)

func TestGet(t *testing.T) {
g := got.T(t)

t.Setenv("BOOL", "true")
t.Setenv("NUM", "2")
t.Setenv("STR", "ok")
t.Setenv("FLOAT", "1.2")
t.Setenv("DURATION", "1m")

g.Eq(lib.Get("BOOL", false), true)
g.Eq(lib.Get("BOOL_DEFAULT", true), true)
g.Eq(lib.Get("NUM", 0), 2)
g.Eq(lib.Get("NUM_DEFAULT", 1), 1)
g.Eq(lib.Get("STR", ""), "ok")
g.Eq(lib.Get("STR_DEFAULT", "yes"), "yes")
g.Eq(lib.Get("FLOAT", 0.0), 1.2)
g.Eq(lib.Get("FLOAT_DEFAULT", 1.1), 1.1)
g.Eq(lib.Get("DURATION", time.Second), time.Minute)
g.Eq(lib.Get("DURATION_DEFAULT", time.Hour), time.Hour)
}
2 changes: 1 addition & 1 deletion test/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func TestBasic(t *testing.T) {
if os.Getenv("VALUE") != "ok" {
if os.Getenv("STR") != "hello" {
t.Fail()
}
}

0 comments on commit ad8230f

Please sign in to comment.