116 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			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), ""))
 | |
| 	}
 | |
| }
 |