move implementation to internal/ directory (#828)

This commit is contained in:
Christian Schwarz
2024-10-18 19:21:17 +02:00
committed by GitHub
parent b9b9ad10cf
commit 908807bd59
360 changed files with 507 additions and 507 deletions
+176
View File
@@ -0,0 +1,176 @@
package envconst
import (
"flag"
"fmt"
"os"
"reflect"
"strconv"
"sync"
"time"
)
var cache sync.Map
func Reset() {
cache.Range(func(key, _ interface{}) bool {
cache.Delete(key)
return true
})
}
func Duration(varname string, def time.Duration) (d time.Duration) {
var err error
if v, ok := cache.Load(varname); ok {
return v.(time.Duration)
}
e := os.Getenv(varname)
if e == "" {
d = def
} else {
d, err = time.ParseDuration(e)
if err != nil {
panic(err)
}
}
cache.Store(varname, d)
return d
}
func Int(varname string, def int) (d int) {
if v, ok := cache.Load(varname); ok {
return v.(int)
}
e := os.Getenv(varname)
if e == "" {
d = def
} else {
d64, err := strconv.ParseInt(e, 10, strconv.IntSize)
if err != nil {
panic(err)
}
d = int(d64)
}
cache.Store(varname, d)
return d
}
func Int64(varname string, def int64) (d int64) {
var err error
if v, ok := cache.Load(varname); ok {
return v.(int64)
}
e := os.Getenv(varname)
if e == "" {
d = def
} else {
d, err = strconv.ParseInt(e, 10, 64)
if err != nil {
panic(err)
}
}
cache.Store(varname, d)
return d
}
func Uint64(varname string, def uint64) (d uint64) {
var err error
if v, ok := cache.Load(varname); ok {
return v.(uint64)
}
e := os.Getenv(varname)
if e == "" {
d = def
} else {
d, err = strconv.ParseUint(e, 10, 64)
if err != nil {
panic(err)
}
}
cache.Store(varname, d)
return d
}
func Bool(varname string, def bool) (d bool) {
var err error
if v, ok := cache.Load(varname); ok {
return v.(bool)
}
e := os.Getenv(varname)
if e == "" {
d = def
} else {
d, err = strconv.ParseBool(e)
if err != nil {
panic(err)
}
}
cache.Store(varname, d)
return d
}
func String(varname string, def string) (d string) {
if v, ok := cache.Load(varname); ok {
return v.(string)
}
e := os.Getenv(varname)
if e == "" {
d = def
} else {
d = e
}
cache.Store(varname, d)
return d
}
func Var(varname string, def flag.Value) (d interface{}) {
// use def's type to instantiate a new object of that same type
// and call flag.Value.Set() on it
defType := reflect.TypeOf(def)
if defType.Kind() != reflect.Ptr {
panic(fmt.Sprintf("envconst var must be a pointer, got %T", def))
}
defElemType := defType.Elem()
if v, ok := cache.Load(varname); ok {
return v
}
e := os.Getenv(varname)
if e == "" {
d = def
} else {
newInstance := reflect.New(defElemType)
if err := newInstance.Interface().(flag.Value).Set(e); err != nil {
panic(err)
}
d = newInstance.Interface()
}
cache.Store(varname, d)
return d
}
type Report struct {
Entries []EntryReport
}
type EntryReport struct {
Var string
Value string
ValueGoType string
}
func GetReport() *Report {
var r Report
cache.Range(func(key, value interface{}) bool {
r.Entries = append(r.Entries, EntryReport{
Var: key.(string),
Value: fmt.Sprintf("%v", value),
ValueGoType: fmt.Sprintf("%T", value),
})
return true
})
return &r
}
+58
View File
@@ -0,0 +1,58 @@
package envconst_test
import (
"fmt"
"os"
"testing"
"github.com/stretchr/testify/require"
"github.com/zrepl/zrepl/internal/util/envconst"
)
type ExampleVarType struct{ string }
var (
Var1 = ExampleVarType{"var1"}
Var2 = ExampleVarType{"var2"}
)
func (m ExampleVarType) String() string { return string(m.string) }
func (m *ExampleVarType) Set(s string) error {
switch s {
case Var1.String():
*m = Var1
case Var2.String():
*m = Var2
default:
return fmt.Errorf("unknown var %q", s)
}
return nil
}
const EnvVarName = "ZREPL_ENVCONST_UNIT_TEST_VAR"
func TestVarDefaultValue(t *testing.T) {
envconst.Reset()
_, set := os.LookupEnv(EnvVarName)
require.False(t, set)
defer os.Unsetenv(EnvVarName)
val := envconst.Var(EnvVarName, &Var1)
if &Var1 != val {
t.Errorf("default value should be same address")
}
}
func TestVarOverriddenValue(t *testing.T) {
envconst.Reset()
_, set := os.LookupEnv(EnvVarName)
require.False(t, set)
defer os.Unsetenv(EnvVarName)
err := os.Setenv(EnvVarName, "var2")
require.NoError(t, err)
val := envconst.Var(EnvVarName, &Var1)
require.Equal(t, &Var2, val, "only structural identity is required for non-default vars")
}