From 813b6242c3b7e180758dda671775e73e7a89d267 Mon Sep 17 00:00:00 2001 From: Luiz Augusto Volpi Nascimento Date: Sat, 14 Dec 2019 23:12:11 -0300 Subject: [PATCH 1/4] Closing the file --- gonfig.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gonfig.go b/gonfig.go index cd7fbd2..025808e 100644 --- a/gonfig.go +++ b/gonfig.go @@ -12,6 +12,8 @@ const ( func Load(path string, config interface{}) error { configFile, err := os.Open(path) + defer configFile.Close() + if err != nil { config = nil return LoadError From c780ace02d65f76dba76610bab08a6c78f6145b8 Mon Sep 17 00:00:00 2001 From: Luiz Augusto Volpi Nascimento Date: Sat, 14 Dec 2019 23:30:29 -0300 Subject: [PATCH 2/4] Created xml support --- error.go | 4 +- gonfig.go | 24 ++++++-- gonfig_test.go | 57 +++++++++++++++---- config.json => test/config.json | 0 test/config.xml | 4 ++ .../invalid_config.json | 0 test/invalid_config.xml | 4 ++ 7 files changed, 75 insertions(+), 18 deletions(-) rename config.json => test/config.json (100%) create mode 100644 test/config.xml rename invalid_config.json => test/invalid_config.json (100%) create mode 100644 test/invalid_config.xml diff --git a/error.go b/error.go index c2db36f..19e8581 100644 --- a/error.go +++ b/error.go @@ -1,8 +1,10 @@ package gonfig const ( - //LoadError = "Error loading the configuration" + // LoadError = "Error loading the configuration" LoadError = GonfigError("Error loading the configuration") + // UnsupportedFileError = "Unsupported file extension" + UnsupportedFileError = GonfigError("Unsupported file extension") ) // GonfigError is an error in the module. diff --git a/gonfig.go b/gonfig.go index 025808e..a4d6607 100644 --- a/gonfig.go +++ b/gonfig.go @@ -2,29 +2,41 @@ package gonfig import ( "encoding/json" + "encoding/xml" "io/ioutil" "os" + "path/filepath" ) -const ( - typeJSON = "json" -) +type unmarshalerFunc func(data []byte, v interface{}) error +// Load a struct with the configuration from a config file. func Load(path string, config interface{}) error { configFile, err := os.Open(path) - defer configFile.Close() - if err != nil { config = nil return LoadError } + defer configFile.Close() b, err := ioutil.ReadAll(configFile) if err != nil { config = nil return LoadError } - err = json.Unmarshal(b, &config) + + ext := filepath.Ext(path) + + var unmarshaler unmarshalerFunc + switch ext { + case ".json": + unmarshaler = json.Unmarshal + case ".xml": + unmarshaler = xml.Unmarshal + default: + return UnsupportedFileError + } + err = unmarshaler(b, &config) if err != nil { config = nil return LoadError diff --git a/gonfig_test.go b/gonfig_test.go index da18172..e5a4d57 100644 --- a/gonfig_test.go +++ b/gonfig_test.go @@ -11,17 +11,20 @@ import ( ) const ( - validJsonFile = "config.json" - invalidJsonFile = "invalid.json" - invalidJsonBodyFile = "invalid_config.json" + validJsonFile = "./test/config.json" + invalidJsonFile = "./test/invalid.json" + invalidJsonBodyFile = "./test/invalid_config.json" + validXMLFile = "./test/config.xml" + invalidXMLFile = "./test/invalid.xml" + invalidXMLBodyFile = "./test/invalid_config.xml" ) type SomeConfiguration struct { Version string `json:"version" xml:"version"` - ProjectName string `json:"project_name" xml:"project_name"` + ProjectName string `json:"project_name" xml:"project-name"` } -var configJSON SomeConfiguration +var configValid SomeConfiguration func init() { file, err := os.Open(validJsonFile) @@ -32,7 +35,7 @@ func init() { if err != nil { panic("Error Loading teste sample") } - json.Unmarshal(b, &configJSON) + json.Unmarshal(b, &configValid) } func TestLoadJSON(t *testing.T) { config := SomeConfiguration{} @@ -42,12 +45,12 @@ func TestLoadJSON(t *testing.T) { if err != nil { t.Errorf("Error loading the configuration: %v", err) } - if !reflect.DeepEqual(config, configJSON) { - t.Errorf("Error loading the configuration: expected %v, got %v", configJSON, config) + if !reflect.DeepEqual(config, configValid) { + t.Errorf("Error loading the configuration: expected %v, got %v", configValid, config) } }) - t.Run("Load a configuration from a invalid json file", func(t *testing.T) { + t.Run("Load a configuration from an invalid json file", func(t *testing.T) { err := gonfig.Load(invalidJsonFile, &config) if err == nil { t.Errorf("It was expected to get an error. Got nil") @@ -57,8 +60,31 @@ func TestLoadJSON(t *testing.T) { } }) - t.Run("Load a configuration from a invalid json body", func(t *testing.T) { - err := gonfig.Load(invalidJsonFile, &config) + t.Run("Load a configuration from an invalid json body", func(t *testing.T) { + err := gonfig.Load(invalidJsonBodyFile, &config) + if err == nil { + t.Errorf("It was expected to get an error. Got nil") + } + if err != gonfig.LoadError { + t.Errorf("Expected the error %v, got %v", gonfig.LoadError, err) + } + }) +} + +func TestLoadXML(t *testing.T) { + config := SomeConfiguration{} + + t.Run("Load a configuration from a valid xml file", func(t *testing.T) { + err := gonfig.Load(validXMLFile, &config) + if err != nil { + t.Errorf("Error loading the configuration: %v", err) + } + if !reflect.DeepEqual(config, configValid) { + t.Errorf("Error loading the configuration: expected %v, got %v", configValid, config) + } + }) + t.Run("Load a configuration from an invalid json file", func(t *testing.T) { + err := gonfig.Load(invalidXMLFile, &config) if err == nil { t.Errorf("It was expected to get an error. Got nil") } @@ -67,4 +93,13 @@ func TestLoadJSON(t *testing.T) { } }) + t.Run("Load a configuration from an invalid json body", func(t *testing.T) { + err := gonfig.Load(invalidXMLBodyFile, &config) + if err == nil { + t.Errorf("It was expected to get an error. Got nil") + } + if err != gonfig.LoadError { + t.Errorf("Expected the error %v, got %v", gonfig.LoadError, err) + } + }) } diff --git a/config.json b/test/config.json similarity index 100% rename from config.json rename to test/config.json diff --git a/test/config.xml b/test/config.xml new file mode 100644 index 0000000..e8e7574 --- /dev/null +++ b/test/config.xml @@ -0,0 +1,4 @@ + + 1.0.0 + gonfig + diff --git a/invalid_config.json b/test/invalid_config.json similarity index 100% rename from invalid_config.json rename to test/invalid_config.json diff --git a/test/invalid_config.xml b/test/invalid_config.xml new file mode 100644 index 0000000..2129ce1 --- /dev/null +++ b/test/invalid_config.xml @@ -0,0 +1,4 @@ + + 1.0.0 + gonfig + From 60d71dccab97176cce5c3426c4b78164ea65db58 Mon Sep 17 00:00:00 2001 From: Luiz Augusto Volpi Nascimento Date: Sat, 14 Dec 2019 23:33:34 -0300 Subject: [PATCH 3/4] created xml example --- examples/xml/config.xml | 5 +++++ examples/xml/main.go | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 examples/xml/config.xml create mode 100644 examples/xml/main.go diff --git a/examples/xml/config.xml b/examples/xml/config.xml new file mode 100644 index 0000000..cc25761 --- /dev/null +++ b/examples/xml/config.xml @@ -0,0 +1,5 @@ + + 1.0.0 + A xml exemple + + diff --git a/examples/xml/main.go b/examples/xml/main.go new file mode 100644 index 0000000..4fa5303 --- /dev/null +++ b/examples/xml/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + + "github.com/luizvnasc/gonfig" +) + +//Config struct to store the app configuration +type Config struct { + Version string `xml:"version"` + Description string `xml:"description"` + Redis struct { + Host string `xml:"host,attr"` + Port uint `xml:"port,attr"` + } `xml:"redis"` +} + +func main() { + var config Config + gonfig.Load("config.xml", &config) + fmt.Printf("%v", config) +} From 7f8ef6013517e9938f7390f2ae11283352ebe432 Mon Sep 17 00:00:00 2001 From: Luiz Augusto Volpi Nascimento Date: Sat, 14 Dec 2019 23:35:14 -0300 Subject: [PATCH 4/4] created xml example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f1b9cde..f0a98c6 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ A simple module to load configurations file to a struct. | Extension | is supported? | |:---------:|:-----------------:| | .json |:heavy_check_mark: | -| .xml |:x: | +| .xml |:heavy_check_mark: | | .yaml |:x: | | .toml |:x: |