github.com/argoproj/argo-cd/v3@v3.2.1/util/hydrator/template.go (about) 1 package hydrator 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "text/template" 8 9 "github.com/Masterminds/sprig/v3" 10 ) 11 12 var sprigFuncMap = sprig.GenericFuncMap() // a singleton for better performance 13 14 func init() { 15 // Avoid allowing the user to learn things about the environment. 16 delete(sprigFuncMap, "env") 17 delete(sprigFuncMap, "expandenv") 18 delete(sprigFuncMap, "getHostByName") 19 } 20 21 // Render use a parsed template and calls the Execute to apply the data. 22 // currently the method supports struct and a map[string]any as data 23 func Render(tmpl string, data HydratorCommitMetadata) (string, error) { 24 var dataMap map[string]any 25 var err error 26 // short-circuit if template is not defined 27 if tmpl == "" { 28 return "", nil 29 } 30 dataMap, err = structToMap(data) 31 if err != nil { 32 return "", fmt.Errorf("marshaling failed: %w", err) 33 } 34 metadata := map[string]any{ 35 "metadata": dataMap, 36 } 37 template, err := template.New("commit-template").Funcs(sprigFuncMap).Parse(tmpl) 38 if err != nil { 39 return "", fmt.Errorf("failed to parse template %s: %w", tmpl, err) 40 } 41 var replacedTmplBuffer bytes.Buffer 42 if err = template.Execute(&replacedTmplBuffer, metadata); err != nil { 43 return "", fmt.Errorf("failed to execute go template %s: %w", tmpl, err) 44 } 45 46 return replacedTmplBuffer.String(), nil 47 } 48 49 func structToMap(s any) (map[string]any, error) { 50 jsonOut, err := json.Marshal(s) 51 if err != nil { 52 return nil, err 53 } 54 55 var result map[string]any 56 err = json.Unmarshal(jsonOut, &result) 57 if err != nil { 58 return nil, err 59 } 60 return result, nil 61 }