syft/internal/sbomsync/builder.go
Alex Goodman a56eff90d6
fix ui race for package count (#2839)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-05-06 11:45:52 -04:00

96 lines
1.7 KiB
Go

package sbomsync
import (
"sync"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/linux"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/sbom"
)
var _ interface {
Accessor
Builder
} = (*sbomBuilder)(nil) // integrity check
// Builder provides a simple facade for simple additions to the SBOM
type Builder interface {
// nodes
AddPackages(...pkg.Package)
// edges
AddRelationships(...artifact.Relationship)
// other
SetLinuxDistribution(linux.Release)
}
// Accessor allows for low-level access to the SBOM
type Accessor interface {
WriteToSBOM(func(*sbom.SBOM))
ReadFromSBOM(func(*sbom.SBOM))
}
type sbomBuilder struct {
sbom *sbom.SBOM
lock *sync.RWMutex
onWrite []func(*sbom.SBOM)
}
func NewBuilder(s *sbom.SBOM, onWrite ...func(*sbom.SBOM)) Builder {
return &sbomBuilder{
sbom: s,
lock: &sync.RWMutex{},
onWrite: onWrite,
}
}
func (b sbomBuilder) onWriteEvent() {
for _, fn := range b.onWrite {
fn(b.sbom)
}
}
func (b sbomBuilder) WriteToSBOM(fn func(*sbom.SBOM)) {
b.lock.Lock()
defer b.lock.Unlock()
fn(b.sbom)
b.onWriteEvent()
}
func (b sbomBuilder) ReadFromSBOM(fn func(*sbom.SBOM)) {
b.lock.RLock()
defer b.lock.RUnlock()
fn(b.sbom)
}
func (b sbomBuilder) AddPackages(p ...pkg.Package) {
b.lock.Lock()
defer b.lock.Unlock()
b.sbom.Artifacts.Packages.Add(p...)
b.onWriteEvent()
}
func (b sbomBuilder) AddRelationships(relationship ...artifact.Relationship) {
b.lock.Lock()
defer b.lock.Unlock()
b.sbom.Relationships = append(b.sbom.Relationships, relationship...)
b.onWriteEvent()
}
func (b sbomBuilder) SetLinuxDistribution(release linux.Release) {
b.lock.Lock()
defer b.lock.Unlock()
b.sbom.Artifacts.LinuxDistribution = &release
b.onWriteEvent()
}