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  }()