Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support load from fs.FS #72

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 25 additions & 14 deletions configor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package configor

import (
"fmt"
"io/fs"
"os"
"reflect"
"regexp"
Expand Down Expand Up @@ -54,7 +55,7 @@ func New(config *Config) *Configor {
return &Configor{Config: config}
}

var testRegexp = regexp.MustCompile("_test|(\\.test$)")
var testRegexp = regexp.MustCompile(`_test|(\.test$)`)

// GetEnvironment get environment
func (configor *Configor) GetEnvironment() string {
Expand All @@ -80,12 +81,32 @@ func (configor *Configor) GetErrorOnUnmatchedKeys() bool {
}

// Load will unmarshal configurations to struct from files that you provide
func (configor *Configor) Load(config interface{}, files ...string) (err error) {
func (configor *Configor) Load(config interface{}, files ...string) error {
return load(configor, config, nil, files...)
}

// LoadFromFS will unmarshal configurations to struct from files that you provide
func (configor *Configor) LoadFromFS(config interface{}, fsys fs.FS, files ...string) error {
return load(configor, config, fsys, files...)
}

// ENV return environment
func ENV() string {
return New(nil).GetEnvironment()
}

// Load will unmarshal configurations to struct from files that you provide
func Load(config interface{}, files ...string) error {
return New(nil).Load(config, files...)
}

func load(configor *Configor, config interface{}, fsys fs.FS, files ...string) (err error) {
defaultValue := reflect.Indirect(reflect.ValueOf(config))
if !defaultValue.CanAddr() {
return fmt.Errorf("Config %v should be addressable", config)
}
err, _ = configor.load(config, false, files...)

_, err = configor.load(config, false, fsys, files...)

if configor.Config.AutoReload {
go func() {
Expand All @@ -95,7 +116,7 @@ func (configor *Configor) Load(config interface{}, files ...string) (err error)
reflectPtr.Elem().Set(defaultValue)

var changed bool
if err, changed = configor.load(reflectPtr.Interface(), true, files...); err == nil && changed {
if changed, err = configor.load(reflectPtr.Interface(), true, fsys, files...); err == nil && changed {
reflect.ValueOf(config).Elem().Set(reflectPtr.Elem())
if configor.Config.AutoReloadCallback != nil {
configor.Config.AutoReloadCallback(config)
Expand All @@ -109,13 +130,3 @@ func (configor *Configor) Load(config interface{}, files ...string) (err error)
}
return
}

// ENV return environment
func ENV() string {
return New(nil).GetEnvironment()
}

// Load will unmarshal configurations to struct from files that you provide
func Load(config interface{}, files ...string) error {
return New(nil).Load(config, files...)
}
50 changes: 29 additions & 21 deletions configor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package configor

import (
"bytes"
"embed"
"encoding/json"
"io/ioutil"
"os"
"reflect"
"testing"
Expand Down Expand Up @@ -73,7 +73,7 @@ func generateDefaultConfig() testConfig {
func TestLoadNormaltestConfig(t *testing.T) {
config := generateDefaultConfig()
if bytes, err := json.Marshal(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(bytes)
Expand All @@ -96,7 +96,7 @@ func TestLoadtestConfigFromTomlWithExtension(t *testing.T) {
)

if err := toml.NewEncoder(&buffer).Encode(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor.toml"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor.toml"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(buffer.Bytes())
Expand All @@ -119,7 +119,7 @@ func TestLoadtestConfigFromTomlWithoutExtension(t *testing.T) {
)

if err := toml.NewEncoder(&buffer).Encode(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(buffer.Bytes())
Expand All @@ -142,7 +142,7 @@ func TestDefaultValue(t *testing.T) {
config.DB.SSL = false

if bytes, err := json.Marshal(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(bytes)
Expand All @@ -164,7 +164,7 @@ func TestMissingRequiredValue(t *testing.T) {
config.DB.Password = ""

if bytes, err := json.Marshal(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(bytes)
Expand All @@ -189,7 +189,7 @@ func TestUnmatchedKeyInTomltestConfigFile(t *testing.T) {
}
config := configFile{Name: "test", Test: "ATest"}

file, err := ioutil.TempFile("/tmp", "configor")
file, err := os.CreateTemp("/tmp", "configor")
if err != nil {
t.Fatal("Could not create temp file")
}
Expand Down Expand Up @@ -274,7 +274,7 @@ func TestUnmatchedKeyInYamltestConfigFile(t *testing.T) {
}
config := configFile{Name: "test", Test: "ATest"}

file, err := ioutil.TempFile("/tmp", "configor")
file, err := os.CreateTemp("/tmp", "configor")
if err != nil {
t.Fatal("Could not create temp file")
}
Expand Down Expand Up @@ -342,14 +342,14 @@ func TestLoadtestConfigurationByEnvironment(t *testing.T) {
APPName: "config2",
}

if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
configBytes, _ := yaml.Marshal(config)
config2Bytes, _ := yaml.Marshal(config2)
ioutil.WriteFile(file.Name()+".yaml", configBytes, 0644)
os.WriteFile(file.Name()+".yaml", configBytes, 0644)
defer os.Remove(file.Name() + ".yaml")
ioutil.WriteFile(file.Name()+".production.yaml", config2Bytes, 0644)
os.WriteFile(file.Name()+".production.yaml", config2Bytes, 0644)
defer os.Remove(file.Name() + ".production.yaml")

var result testConfig
Expand All @@ -375,14 +375,14 @@ func TestLoadtestConfigurationByEnvironmentSetBytestConfig(t *testing.T) {
APPName: "production_config2",
}

if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
configBytes, _ := yaml.Marshal(config)
config2Bytes, _ := yaml.Marshal(config2)
ioutil.WriteFile(file.Name()+".yaml", configBytes, 0644)
os.WriteFile(file.Name()+".yaml", configBytes, 0644)
defer os.Remove(file.Name() + ".yaml")
ioutil.WriteFile(file.Name()+".production.yaml", config2Bytes, 0644)
os.WriteFile(file.Name()+".production.yaml", config2Bytes, 0644)
defer os.Remove(file.Name() + ".production.yaml")

var result testConfig
Expand All @@ -407,7 +407,7 @@ func TestOverwritetestConfigurationWithEnvironmentWithDefaultPrefix(t *testing.T
config := generateDefaultConfig()

if bytes, err := json.Marshal(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(bytes)
Expand Down Expand Up @@ -435,7 +435,7 @@ func TestOverwritetestConfigurationWithEnvironment(t *testing.T) {
config := generateDefaultConfig()

if bytes, err := json.Marshal(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(bytes)
Expand All @@ -462,7 +462,7 @@ func TestOverwritetestConfigurationWithEnvironmentThatSetBytestConfig(t *testing
config := generateDefaultConfig()

if bytes, err := json.Marshal(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(bytes)
Expand All @@ -489,7 +489,7 @@ func TestResetPrefixToBlank(t *testing.T) {
config := generateDefaultConfig()

if bytes, err := json.Marshal(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(bytes)
Expand All @@ -516,7 +516,7 @@ func TestResetPrefixToBlank2(t *testing.T) {
config := generateDefaultConfig()

if bytes, err := json.Marshal(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(bytes)
Expand All @@ -543,7 +543,7 @@ func TestReadFromEnvironmentWithSpecifiedEnvName(t *testing.T) {
config := generateDefaultConfig()

if bytes, err := json.Marshal(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(bytes)
Expand All @@ -565,7 +565,7 @@ func TestAnonymousStruct(t *testing.T) {
config := generateDefaultConfig()

if bytes, err := json.Marshal(config); err == nil {
if file, err := ioutil.TempFile("/tmp", "configor"); err == nil {
if file, err := os.CreateTemp("/tmp", "configor"); err == nil {
defer file.Close()
defer os.Remove(file.Name())
file.Write(bytes)
Expand Down Expand Up @@ -681,3 +681,11 @@ func TestLoadNestedConfig(t *testing.T) {
adminConfig := MenuList{}
New(&Config{Verbose: true}).Load(&adminConfig, "admin.yml")
}

//go:embed admin.yml
var fsysForAdminYaml embed.FS

func TestLoadNestedConfigFromFS(t *testing.T) {
adminConfig := MenuList{}
New(&Config{Verbose: true}).LoadFromFS(&adminConfig, fsysForAdminYaml, "admin.yml")
}
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module github.com/jinzhu/configor

go 1.12
go 1.17

require (
github.com/BurntSushi/toml v0.3.1
gopkg.in/yaml.v2 v2.2.2
github.com/BurntSushi/toml v0.4.1
gopkg.in/yaml.v2 v2.4.0
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
3 changes: 1 addition & 2 deletions unmarshal_json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package configor_test

import (
"encoding/json"
"io/ioutil"
"os"
"strings"
"testing"
Expand All @@ -20,7 +19,7 @@ func TestUnmatchedKeyInJsonConfigFile(t *testing.T) {
}
config := configFile{Name: "test", Test: "ATest"}

file, err := ioutil.TempFile("/tmp", "configor")
file, err := os.CreateTemp("/tmp", "configor")
if err != nil {
t.Fatal("Could not create temp file")
}
Expand Down
Loading