yaml.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package yamlutil
  2. import (
  3. "flag"
  4. "fmt"
  5. "strings"
  6. "gopkg.in/yaml.v1"
  7. )
  8. // SetFlagsFromYaml goes through all registered flags in the given flagset,
  9. // and if they are not already set it attempts to set their values from
  10. // the YAML config. It will use the key REPLACE(UPPERCASE(flagname), '-', '_')
  11. func SetFlagsFromYaml(fs *flag.FlagSet, rawYaml []byte) (err error) {
  12. conf := make(map[string]string)
  13. if err = yaml.Unmarshal(rawYaml, conf); err != nil {
  14. return
  15. }
  16. alreadySet := map[string]struct{}{}
  17. fs.Visit(func(f *flag.Flag) {
  18. alreadySet[f.Name] = struct{}{}
  19. })
  20. errs := make([]error, 0)
  21. fs.VisitAll(func(f *flag.Flag) {
  22. if f.Name == "" {
  23. return
  24. }
  25. if _, ok := alreadySet[f.Name]; ok {
  26. return
  27. }
  28. tag := strings.Replace(strings.ToUpper(f.Name), "-", "_", -1)
  29. val, ok := conf[tag]
  30. if !ok {
  31. return
  32. }
  33. if serr := fs.Set(f.Name, val); serr != nil {
  34. errs = append(errs, fmt.Errorf("invalid value %q for %s: %v", val, tag, serr))
  35. }
  36. })
  37. if len(errs) != 0 {
  38. err = ErrorSlice(errs)
  39. }
  40. return
  41. }
  42. type ErrorSlice []error
  43. func (e ErrorSlice) Error() string {
  44. s := ""
  45. for _, err := range e {
  46. s += ", " + err.Error()
  47. }
  48. return "Errors: " + s
  49. }