package output
import (
"embed"
"html/template"
"io"
"strings"
"github.com/google/osv-scanner/v2/internal/utility/results"
"github.com/google/osv-scanner/v2/internal/utility/severity"
"github.com/google/osv-scanner/v2/pkg/models"
)
// TemplateDir is the directory containing the HTML templates
const TemplateDir = "html/*"
//go:embed html/*
var templates embed.FS
// uniqueIndex creates a function that generates unique indices for HTML elements.
// It takes an integer pointer as input and increments the integer's value each time the
// returned function is called. This ensures that each call to the returned function
// produces a different index, even when called concurrently from multiple goroutines.
func uniqueIndex(index *int) func() int {
return func() int {
*index += 1
return *index
}
}
func formatSlice(slice []string) string {
return strings.Join(slice, ", ")
}
func formatLicense(slice []models.License) string {
stringSlice := make([]string, len(slice))
for i, license := range slice {
stringSlice[i] = string(license)
}
return formatSlice(stringSlice)
}
func formatRating(rating severity.Rating) string {
return strings.ToLower(string(rating))
}
type VulnTableEntryArgument struct {
Element VulnResult
IsHidden bool
}
func buildVulnTableEntryArgument(element VulnResult, isHidden bool) VulnTableEntryArgument {
return VulnTableEntryArgument{
IsHidden: isHidden,
Element: element,
}
}
func hasOSResult(ecosystems []EcosystemResult) bool {
for _, ecosystem := range ecosystems {
if ecosystem.IsOS {
return true
}
}
return false
}
func PrintHTMLResults(vulnResult *models.VulnerabilityResults, outputWriter io.Writer) error {
// htmlResult := BuildHTMLResults(vulnResult)
result := BuildResults(vulnResult)
vulnIndex := 0
// Parse embedded templates
funcMap := template.FuncMap{
"uniqueID": uniqueIndex(&vulnIndex),
"join": strings.Join,
"formatRating": formatRating,
"add": func(a, b int) int {
return a + b
},
"getFilteredVulnReasons": getFilteredVulnReasons,
"getBaseImageName": getBaseImageName,
"formatSlice": formatSlice,
"formatLayerCommand": formatLayerCommand,
"buildVulnTableEntryArgument": buildVulnTableEntryArgument,
"formatLicense": formatLicense,
"hasOSResult": hasOSResult,
"GetShortCommit": results.GetShortCommit,
"isOSResult": isOSResult,
}
tmpl := template.Must(template.New("").Funcs(funcMap).ParseFS(templates, TemplateDir))
// Execute template
return tmpl.ExecuteTemplate(outputWriter, "report_template.gohtml", result)
}