urfave-cli/altsrc/yaml_file_loader.go
Antonio Fdez b5d06bd2a9 allow to load YAML configuration files on Windows
The funtion `loadDataFrom` does not take care of Windows users since any of the conditions met and it returns an error.

The change looks for the runtime where it's running and then if the filePath contains a `\`
2016-11-17 16:58:46 +01:00

90 lines
2.4 KiB
Go

// Disabling building of yaml support in cases where golang is 1.0 or 1.1
// as the encoding library is not implemented or supported.
// +build go1.2
package altsrc
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"gopkg.in/urfave/cli.v1"
"gopkg.in/yaml.v2"
)
type yamlSourceContext struct {
FilePath string
}
// NewYamlSourceFromFile creates a new Yaml InputSourceContext from a filepath.
func NewYamlSourceFromFile(file string) (InputSourceContext, error) {
ysc := &yamlSourceContext{FilePath: file}
var results map[interface{}]interface{}
err := readCommandYaml(ysc.FilePath, &results)
if err != nil {
return nil, fmt.Errorf("Unable to load Yaml file '%s': inner error: \n'%v'", ysc.FilePath, err.Error())
}
return &MapInputSource{valueMap: results}, nil
}
// NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a provided flag name and source context.
func NewYamlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
return func(context *cli.Context) (InputSourceContext, error) {
filePath := context.String(flagFileName)
return NewYamlSourceFromFile(filePath)
}
}
func readCommandYaml(filePath string, container interface{}) (err error) {
b, err := loadDataFrom(filePath)
if err != nil {
return err
}
err = yaml.Unmarshal(b, container)
if err != nil {
return err
}
err = nil
return
}
func loadDataFrom(filePath string) ([]byte, error) {
u, err := url.Parse(filePath)
if err != nil {
return nil, err
}
if u.Host != "" { // i have a host, now do i support the scheme?
switch u.Scheme {
case "http", "https":
res, err := http.Get(filePath)
if err != nil {
return nil, err
}
return ioutil.ReadAll(res.Body)
default:
return nil, fmt.Errorf("scheme of %s is unsupported", filePath)
}
} else if u.Path != "" { // i dont have a host, but I have a path. I am a local file.
if _, notFoundFileErr := os.Stat(filePath); notFoundFileErr != nil {
return nil, fmt.Errorf("Cannot read from file: '%s' because it does not exist.", filePath)
}
return ioutil.ReadFile(filePath)
} else if runtime.GOOS == "windows" && strings.Contains(u.String(), "\\") {
if _, notFoundFileErr := os.Stat(filePath); notFoundFileErr != nil {
return nil, fmt.Errorf("Cannot read from file: '%s' because it does not exist.", filePath)
}
return ioutil.ReadFile(filePath)
} else {
return nil, fmt.Errorf("unable to determine how to load from path %s", filePath)
}
}