github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/formats/template/encoder.go (about) 1 package template 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "reflect" 8 "text/template" 9 10 "github.com/Masterminds/sprig/v3" 11 "github.com/mitchellh/go-homedir" 12 ) 13 14 func makeTemplateExecutor(templateFilePath string) (*template.Template, error) { 15 if templateFilePath == "" { 16 return nil, errors.New("no template file: please provide a template path") 17 } 18 19 expandedPathToTemplateFile, err := homedir.Expand(templateFilePath) 20 if err != nil { 21 return nil, fmt.Errorf("unable to expand path %s", templateFilePath) 22 } 23 24 templateContents, err := os.ReadFile(expandedPathToTemplateFile) 25 if err != nil { 26 return nil, fmt.Errorf("unable to get template content: %w", err) 27 } 28 29 templateName := expandedPathToTemplateFile 30 tmpl, err := template.New(templateName).Funcs(funcMap).Parse(string(templateContents)) 31 if err != nil { 32 return nil, fmt.Errorf("unable to parse template: %w", err) 33 } 34 35 return tmpl, nil 36 } 37 38 // These are custom functions available to template authors. 39 var funcMap = func() template.FuncMap { 40 f := sprig.HermeticTxtFuncMap() 41 f["getLastIndex"] = func(collection interface{}) int { 42 if v := reflect.ValueOf(collection); v.Kind() == reflect.Slice { 43 return v.Len() - 1 44 } 45 46 return 0 47 } 48 // Checks if a field is defined 49 f["hasField"] = func(obj interface{}, field string) bool { 50 t := reflect.TypeOf(obj) 51 _, ok := t.FieldByName(field) 52 return ok 53 } 54 return f 55 }()