github.com/theliebeskind/genfig@v0.1.5-alpha/plugins/update_from_env.go (about) 1 package plugins 2 3 import ( 4 "io" 5 "strings" 6 "text/template" 7 8 "github.com/theliebeskind/genfig/models" 9 ) 10 11 type updateFromEnvPlugin struct { 12 s models.SchemaMap 13 tpl *template.Template 14 } 15 16 var ( 17 updateFromEnv = updateFromEnvPlugin{ 18 s: models.SchemaMap{}, 19 tpl: template.Must(template. 20 New("updateFromEnv"). 21 Funcs(template.FuncMap{ 22 "upper": strings.ToUpper, 23 "title": strings.Title, 24 // Remove root (usually "Config_") from env var name 25 "cleanPrefixEnv": func(s string) string { 26 return strings.Join(strings.Split(s, "_")[1:], "_") 27 }, 28 // Converte an env var name to a Config path 29 "makePath": func(s string) string { 30 return strings.Join(strings.Split(s, "_")[1:], ".") 31 }, 32 // Substitute []*type* with *type*Slice 33 "renameSlice": func(s string) string { 34 if strings.HasPrefix(s, "[]") { 35 return s[2:] + "Slice" 36 } 37 return s 38 }, 39 }). 40 Parse(`import ( 41 "encoding/json" 42 "fmt" 43 "os" 44 "strconv" 45 ) 46 47 var ( 48 _ = os.LookupEnv 49 _ = fmt.Sprintf 50 _ = json.Marshal 51 ) 52 53 func (c *Config) UpdateFromEnv() []error { 54 var val string 55 _ = val 56 var exists bool 57 _ = exists 58 var errors = []error{} 59 {{range $_, $v := .}}{{if not $v.IsStruct}} 60 if val, exists = os.LookupEnv("{{cleanPrefixEnv (upper $v.Path)}}"); exists { {{if eq $v.Content "string"}} 61 c.{{makePath $v.Path}} = val {{else}} 62 if v, err := parse{{title (renameSlice $v.Content)}}(val); err == nil { 63 c.{{makePath $v.Path}} = v 64 } else { 65 errors = append(errors, fmt.Errorf("Genfig: could not parse {{$v.Content}} from {{upper $v.Path}} ('%s')\n", val)) 66 } {{end}} 67 } 68 {{end}}{{end}} 69 if len(errors) == 0 { 70 return nil 71 } else { 72 return errors 73 } 74 } 75 76 // these are wrappers, so that they can 77 // a) be referenced easily be the code generator and 78 // b) be replaces easily by you (or me) 79 func parseInt64(s string) (i int64, err error) { 80 i, err = strconv.ParseInt(s, 10, 0) 81 return 82 } 83 84 func parseFloat64(s string) (f float64, err error) { 85 f, err = strconv.ParseFloat(s, 0) 86 return 87 } 88 89 func parseBool(s string) (b bool, err error) { 90 b, err = strconv.ParseBool(s) 91 return 92 } 93 94 func parseStringSlice(s string) (a []string, err error) { 95 err = json.Unmarshal([]byte(s), &a) 96 return 97 } 98 99 func parseInt64Slice(s string) (a []int64, err error) { 100 err = json.Unmarshal([]byte(s), &a) 101 return 102 } 103 104 func parseFloat64Slice(s string) (a []float64, err error) { 105 err = json.Unmarshal([]byte(s), &a) 106 return 107 } 108 109 func parseInterfaceSlice(s string) (a []interface{}, err error) { 110 err = json.Unmarshal([]byte(s), &a) 111 return 112 } 113 `))} 114 ) 115 116 func init() { 117 // "register" plugin 118 Plugins["update_from_env"] = &updateFromEnv 119 } 120 121 // GetInitCall returns the availibility and the string of the 122 // function to be called on init 123 func (p *updateFromEnvPlugin) GetInitCall() (string, bool) { 124 return "if errs := Current.UpdateFromEnv(); errs != nil {\n\tfmt.Println(errs)\n}", true 125 } 126 127 // SetSchemaMap sets the schema to be used when WriteTo is called 128 func (p *updateFromEnvPlugin) SetSchemaMap(s models.SchemaMap) { 129 p.s = s 130 } 131 132 // WriteTo performs the acutal writing to a buffer (or io.Writer). 133 // For this plugin, the template is simply "rendered" into the writer. 134 func (p *updateFromEnvPlugin) WriteTo(w io.Writer) (l int64, err error) { 135 err = p.tpl.Execute(w, p.s) 136 return 137 }