github.com/anchore/syft@v1.38.2/internal/task/scope_tasks.go (about)

     1  package task
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/anchore/syft/internal/sbomsync"
     8  	"github.com/anchore/syft/syft/artifact"
     9  	"github.com/anchore/syft/syft/file"
    10  	"github.com/anchore/syft/syft/pkg"
    11  	"github.com/anchore/syft/syft/sbom"
    12  )
    13  
    14  func NewDeepSquashedScopeCleanupTask() Task {
    15  	fn := func(_ context.Context, _ file.Resolver, builder sbomsync.Builder) error {
    16  		accessor := builder.(sbomsync.Accessor)
    17  
    18  		// remove all packages that doesn't exist in the final state of the image
    19  		builder.DeletePackages(packagesToRemove(accessor)...)
    20  		return nil
    21  	}
    22  
    23  	return NewTask("deep-squashed-cleaner", fn)
    24  }
    25  
    26  func packagesToRemove(accessor sbomsync.Accessor) []artifact.ID {
    27  	pkgsToDelete := make([]artifact.ID, 0)
    28  	accessor.ReadFromSBOM(func(s *sbom.SBOM) {
    29  		filterDuplicates := make(map[string]bool)
    30  		for p := range s.Artifacts.Packages.Enumerate() {
    31  			noSquashed := true
    32  			noPrimary := true
    33  			for _, l := range p.Locations.ToSlice() {
    34  				isPrimaryEvidence := l.Annotations[pkg.EvidenceAnnotationKey] == pkg.PrimaryEvidenceAnnotation
    35  				switch l.Annotations[file.VisibleAnnotationKey] {
    36  				case file.VisibleAnnotation:
    37  					if isPrimaryEvidence || p.Type == pkg.BinaryPkg {
    38  						noSquashed = false
    39  						break
    40  					}
    41  				case "":
    42  					if isPrimaryEvidence {
    43  						if exists := filterDuplicates[getKey(p, l)]; exists {
    44  							break
    45  						}
    46  						filterDuplicates[getKey(p, l)] = true
    47  						noPrimary = false
    48  						break
    49  					}
    50  				}
    51  			}
    52  
    53  			if noSquashed && noPrimary {
    54  				pkgsToDelete = append(pkgsToDelete, p.ID())
    55  			}
    56  		}
    57  	})
    58  	return pkgsToDelete
    59  }
    60  
    61  func getKey(pkg pkg.Package, loc file.Location) string {
    62  	return fmt.Sprintf("%s-%s-%s-%s", pkg.Name, pkg.Version, loc.RealPath, loc.AccessPath)
    63  }