You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

93 lines
2.5 KiB

  1. // Disabling building of yaml support in cases where golang is 1.0 or 1.1
  2. // as the encoding library is not implemented or supported.
  3. // +build go1.2
  4. package altsrc
  5. import (
  6. "fmt"
  7. "io/ioutil"
  8. "net/http"
  9. "net/url"
  10. "os"
  11. "runtime"
  12. "strings"
  13. "gopkg.in/urfave/cli.v1"
  14. "gopkg.in/yaml.v2"
  15. )
  16. type yamlSourceContext struct {
  17. FilePath string
  18. }
  19. // NewYamlSourceFromFile creates a new Yaml InputSourceContext from a filepath.
  20. func NewYamlSourceFromFile(file string) (InputSourceContext, error) {
  21. ysc := &yamlSourceContext{FilePath: file}
  22. var results map[interface{}]interface{}
  23. err := readCommandYaml(ysc.FilePath, &results)
  24. if err != nil {
  25. return nil, fmt.Errorf("Unable to load Yaml file '%s': inner error: \n'%v'", ysc.FilePath, err.Error())
  26. }
  27. return &MapInputSource{valueMap: results}, nil
  28. }
  29. // NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a provided flag name and source context.
  30. func NewYamlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
  31. return func(context *cli.Context) (InputSourceContext, error) {
  32. filePath := context.String(flagFileName)
  33. return NewYamlSourceFromFile(filePath)
  34. }
  35. }
  36. func readCommandYaml(filePath string, container interface{}) (err error) {
  37. b, err := loadDataFrom(filePath)
  38. if err != nil {
  39. return err
  40. }
  41. err = yaml.Unmarshal(b, container)
  42. if err != nil {
  43. return err
  44. }
  45. err = nil
  46. return
  47. }
  48. func loadDataFrom(filePath string) ([]byte, error) {
  49. u, err := url.Parse(filePath)
  50. if err != nil {
  51. return nil, err
  52. }
  53. if u.Host != "" { // i have a host, now do i support the scheme?
  54. switch u.Scheme {
  55. case "http", "https":
  56. res, err := http.Get(filePath)
  57. if err != nil {
  58. return nil, err
  59. }
  60. return ioutil.ReadAll(res.Body)
  61. default:
  62. return nil, fmt.Errorf("scheme of %s is unsupported", filePath)
  63. }
  64. } else if u.Path != "" { // i dont have a host, but I have a path. I am a local file.
  65. if _, notFoundFileErr := os.Stat(filePath); notFoundFileErr != nil {
  66. return nil, fmt.Errorf("Cannot read from file: '%s' because it does not exist.", filePath)
  67. }
  68. return ioutil.ReadFile(filePath)
  69. } else if runtime.GOOS == "windows" && strings.Contains(u.String(), "\\") {
  70. // on Windows systems u.Path is always empty, so we need to check the string directly.
  71. if _, notFoundFileErr := os.Stat(filePath); notFoundFileErr != nil {
  72. return nil, fmt.Errorf("Cannot read from file: '%s' because it does not exist.", filePath)
  73. }
  74. return ioutil.ReadFile(filePath)
  75. } else {
  76. return nil, fmt.Errorf("unable to determine how to load from path %s", filePath)
  77. }
  78. }