serviceman/vendor/github.com/UnnoTed/fileb0x/config/file.go

116 lines
2.5 KiB
Go

package config
import (
"encoding/json"
"errors"
"io/ioutil"
"os"
"path"
"github.com/UnnoTed/fileb0x/utils"
"github.com/BurntSushi/toml"
"gopkg.in/yaml.v2"
"fmt"
)
// File holds config file info
type File struct {
FilePath string
Data []byte
Mode string // "json" || "yaml" || "yml" || "toml"
}
// FromArg gets the json/yaml/toml file from args
func (f *File) FromArg(read bool) error {
// (length - 1)
arg := os.Args[len(os.Args)-1:][0]
// get extension
ext := path.Ext(arg)
if len(ext) > 1 {
ext = ext[1:] // remove dot
}
// when json/yaml/toml file isn't found on last arg
// it searches for a ".json", ".yaml", ".yml" or ".toml" string in all args
if ext != "json" && ext != "yaml" && ext != "yml" && ext != "toml" {
// loop through args
for _, a := range os.Args {
// get extension
ext := path.Ext(a)
// check for valid extensions
if ext == ".json" || ext == ".yaml" || ext == ".yml" || ext == ".toml" {
f.Mode = ext[1:] // remove dot
ext = f.Mode
arg = a
break
}
}
} else {
f.Mode = ext
}
// check if extension is json, yaml or toml
// then get it's absolute path
if ext == "json" || ext == "yaml" || ext == "yml" || ext == "toml" {
f.FilePath = arg
// so we can test without reading a file
if read {
if !utils.Exists(f.FilePath) {
return errors.New("Error: I Can't find the config file at [" + f.FilePath + "]")
}
}
} else {
return errors.New("Error: You must specify a json, yaml or toml file")
}
return nil
}
// Parse gets the config file's content from File.Data
func (f *File) Parse() (*Config, error) {
// remove comments
f.RemoveJSONComments()
to := &Config{}
switch f.Mode {
case "json":
return to, json.Unmarshal(f.Data, to)
case "yaml", "yml":
return to, yaml.Unmarshal(f.Data, to)
case "toml":
return to, toml.Unmarshal(f.Data, to)
default:
return nil, fmt.Errorf("unknown mode '%s'", f.Mode)
}
}
// Load the json/yaml file that was specified from args
// and transform it into a config struct
func (f *File) Load() (*Config, error) {
var err error
if !utils.Exists(f.FilePath) {
return nil, errors.New("Error: I Can't find the config file at [" + f.FilePath + "]")
}
// read file
f.Data, err = ioutil.ReadFile(f.FilePath)
if err != nil {
return nil, err
}
// parse file
return f.Parse()
}
// RemoveJSONComments from the file
func (f *File) RemoveJSONComments() {
if f.Mode == "json" {
// remove inline comments
f.Data = []byte(regexComments.ReplaceAllString(string(f.Data), ""))
}
}