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* diff --git a/cfg/filebackend.go b/cfg/filebackend.go index cbe44456..4f83a9b0 100644 --- a/cfg/filebackend.go +++ b/cfg/filebackend.go @@ -6,31 +6,56 @@ 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 func (fs *FileBackend) Load(u *url.URL) (*Config, error) { var config 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 !exist(u.Path) { 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) + if fs.format == FormatYAML { + err = yaml.Unmarshal(content, &config) + } else { + err = json.Unmarshal(content, &config) + } if err != nil { return nil, err } @@ -50,10 +75,15 @@ func (fs *FileBackend) Save(config *Config) error { } } - 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 f9a17510..ed186460 100644 --- a/cfg/filebackend_test.go +++ b/cfg/filebackend_test.go @@ -104,3 +104,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 diff --git a/go.mod b/go.mod index 0d820d66..ceb911ea 100644 --- a/go.mod +++ b/go.mod @@ -103,5 +103,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 fea6ead3..d8008067 100644 --- a/go.sum +++ b/go.sum @@ -318,5 +318,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=