From 0c77875292476d3825f4f71ab8cb09b02ce536ea Mon Sep 17 00:00:00 2001 From: orsinium Date: Mon, 5 Oct 2020 12:07:37 +0200 Subject: [PATCH 1/4] YAML support for file backend --- cfg/filebackend.go | 48 +++++++++++++++++++++++++++++++-------- cfg/filebackend_test.go | 34 +++++++++++++++++++++++++++ cfg/testdata/beehive.yaml | 4 ++++ 3 files changed, 77 insertions(+), 9 deletions(-) create mode 100644 cfg/testdata/beehive.yaml diff --git a/cfg/filebackend.go b/cfg/filebackend.go index 5ebcb211..97b4c629 100644 --- a/cfg/filebackend.go +++ b/cfg/filebackend.go @@ -6,15 +6,27 @@ import ( "net/url" "os" "path/filepath" + "strings" + + "gopkg.in/yaml.v2" +) + +type Format int + +const ( + FormatJSON Format = iota + FormatYAML = iota ) // FileBackend implements a filesystem backend for the configuration -type FileBackend struct{} +type FileBackend struct { + format Format +} // NewFileBackend returns a FileBackend that handles loading and // saving files from the local filesytem. func NewFileBackend() *FileBackend { - return &FileBackend{} + return &FileBackend{format: FormatJSON} } // Load loads chains from config @@ -25,12 +37,25 @@ func (fs *FileBackend) Load(u *url.URL) (*Config, error) { return &Config{url: u}, nil } - j, err := ioutil.ReadFile(u.Path) + content, err := ioutil.ReadFile(u.Path) if err != nil { return &config, err } - err = json.Unmarshal(j, &config) + // detect file format by extension + if strings.HasSuffix(u.Path, ".yaml") { + fs.format = FormatYAML + } else if strings.HasSuffix(u.Path, ".yml") { + fs.format = FormatYAML + } else { + fs.format = FormatJSON + } + + if fs.format == FormatYAML { + err = yaml.Unmarshal(content, &config) + } else { + err = json.Unmarshal(content, &config) + } if err != nil { return nil, err } @@ -47,10 +72,15 @@ func (fs *FileBackend) Save(config *Config) error { os.MkdirAll(cfgDir, 0755) } - j, err := json.MarshalIndent(config, "", " ") - if err == nil { - err = ioutil.WriteFile(config.URL().Path, j, 0644) + var content []byte + var err error + if fs.format == FormatYAML { + content, err = yaml.Marshal(config) + } else { + content, err = json.MarshalIndent(config, "", " ") } - - return err + if err != nil { + return err + } + return ioutil.WriteFile(config.URL().Path, content, 0644) } diff --git a/cfg/filebackend_test.go b/cfg/filebackend_test.go index 2c115407..43d09efd 100644 --- a/cfg/filebackend_test.go +++ b/cfg/filebackend_test.go @@ -82,3 +82,37 @@ func TestFileSave(t *testing.T) { t.Errorf("Configuration file wasn't saved to %s", p) } } + +func Test_FileLoad_FileSave_YAML(t *testing.T) { + // load + u, err := url.Parse(filepath.Join("testdata", "beehive.yaml")) + if err != nil { + t.Error("cannot parse config path") + } + backend := NewFileBackend() + conf, err := backend.Load(u) + if err != nil { + t.Errorf("Error loading config file fixture from relative path %s. %v", u, err) + } + if conf.Bees[0].Name != "echo" { + t.Error("The first bee should be an exec bee named echo") + } + + tmpdir, err := ioutil.TempDir("", "beehivetest") + if err != nil { + t.Error("Could not create temp directory") + } + p := filepath.Join(tmpdir, "beehive.yaml") + u, err = url.Parse("file://" + p) + if err != nil { + t.Error("cannot parse config path") + } + err = conf.SetURL(u.String()) + if err != nil { + t.Error("cannot set url") + } + err = backend.Save(conf) + if err != nil { + t.Error("cannot save config") + } +} diff --git a/cfg/testdata/beehive.yaml b/cfg/testdata/beehive.yaml new file mode 100644 index 00000000..6706e553 --- /dev/null +++ b/cfg/testdata/beehive.yaml @@ -0,0 +1,4 @@ +bees: + - name: echo + class: execbee + description: echo From d2b4c2573d4c635964677730b36efdff9ea5bd13 Mon Sep 17 00:00:00 2001 From: Gram Date: Mon, 5 Oct 2020 12:09:50 +0200 Subject: [PATCH 2/4] add deps --- go.mod | 1 + go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/go.mod b/go.mod index 7e517c76..8c60ed2e 100644 --- a/go.mod +++ b/go.mod @@ -102,5 +102,6 @@ require ( gopkg.in/ini.v1 v1.42.0 // indirect gopkg.in/mail.v2 v2.3.1 // indirect gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce // indirect + gopkg.in/yaml.v2 v2.3.0 layeh.com/gumble v0.0.0-20180508205105-1ea1159c4956 ) diff --git a/go.sum b/go.sum index 6c1136e3..ba05bacf 100644 --- a/go.sum +++ b/go.sum @@ -316,5 +316,7 @@ 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.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= layeh.com/gumble v0.0.0-20180508205105-1ea1159c4956 h1:TaQ2ECrcAom2bkjRvOxhsUkD6l5iiCJ/++lHHZ42zII= layeh.com/gumble v0.0.0-20180508205105-1ea1159c4956/go.mod h1:ZWnZxbDNsg1uFq6Zu7mRdCi7xechwiqWYsFdedd0GUc= From 91bc71c303ea101a59963029916f22de7229c5ef Mon Sep 17 00:00:00 2001 From: Gram Date: Mon, 5 Oct 2020 12:19:53 +0200 Subject: [PATCH 3/4] gitignore YAML config --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8731c7fd..de6d705b 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ _testmain.go *~ beehive /beehive.conf +/beehive.yaml # Texteditor-specific stuff .*.sw* From 31f423ab4869474478f07356414092c2290f2850 Mon Sep 17 00:00:00 2001 From: Gram Date: Mon, 5 Oct 2020 12:34:54 +0200 Subject: [PATCH 4/4] detect file format before all --- cfg/filebackend.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cfg/filebackend.go b/cfg/filebackend.go index 97b4c629..fcac9763 100644 --- a/cfg/filebackend.go +++ b/cfg/filebackend.go @@ -33,15 +33,6 @@ func NewFileBackend() *FileBackend { func (fs *FileBackend) Load(u *url.URL) (*Config, error) { var config Config - if !exist(u.Path) { - return &Config{url: u}, nil - } - - content, err := ioutil.ReadFile(u.Path) - if err != nil { - return &config, err - } - // detect file format by extension if strings.HasSuffix(u.Path, ".yaml") { fs.format = FormatYAML @@ -51,6 +42,15 @@ func (fs *FileBackend) Load(u *url.URL) (*Config, error) { fs.format = FormatJSON } + if !exist(u.Path) { + return &Config{url: u}, nil + } + + content, err := ioutil.ReadFile(u.Path) + if err != nil { + return &config, err + } + if fs.format == FormatYAML { err = yaml.Unmarshal(content, &config) } else {