package utils import ( "fmt" "sort" "golang.org/x/exp/maps" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" ) func UniqueStrings(ss []string) []string { var results []string uniq := make(map[string]struct{}) for _, s := range ss { if _, ok := uniq[s]; ok { continue } results = append(results, s) uniq[s] = struct{}{} } return results } func UniquePackages(pkgs []ftypes.Package) []ftypes.Package { if len(pkgs) == 0 { return nil } unique := make(map[string]ftypes.Package) for _, pkg := range pkgs { identifier := fmt.Sprintf("%s@%s", pkg.Name, pkg.Version) if l, ok := unique[identifier]; !ok { unique[identifier] = pkg } else { // There are times when we get 2 same packages as root and dev dependencies. // https://github.com/aquasecurity/trivy/issues/5532 // In these cases, we need to mark the dependency as a root dependency. if !pkg.Dev { l.Dev = pkg.Dev unique[identifier] = l } if len(pkg.Locations) > 0 { // merge locations l.Locations = append(l.Locations, pkg.Locations...) sort.Sort(l.Locations) unique[identifier] = l } } } pkgSlice := maps.Values(unique) sort.Sort(ftypes.Packages(pkgSlice)) return pkgSlice } func MergeMaps(parent, child map[string]string) map[string]string { if parent == nil { return child } // Clone parent map to avoid shadow overwrite newParent := maps.Clone(parent) for k, v := range child { newParent[k] = v } return newParent }