diff --git a/syft/pkg/cataloger/golang/package.go b/syft/pkg/cataloger/golang/package.go index 70be97454..f05ee0850 100644 --- a/syft/pkg/cataloger/golang/package.go +++ b/syft/pkg/cataloger/golang/package.go @@ -9,7 +9,7 @@ import ( "github.com/anchore/syft/syft/pkg" ) -func (c *goBinaryCataloger) newGoBinaryPackage(dep *debug.Module, mainModule, goVersion, architecture string, buildSettings pkg.KeyValues, cryptoSettings, experiments []string, licenses []pkg.License, locations ...file.Location) pkg.Package { +func (c *goBinaryCataloger) newGoBinaryPackage(dep *debug.Module, mainModule, goVersion, architecture string, buildSettings pkg.KeyValues, cryptoSettings, experiments []string, licenses []pkg.License, dependencies pkg.DependencyCompleteness, locations ...file.Location) pkg.Package { if dep.Replace != nil { dep = dep.Replace } @@ -24,7 +24,7 @@ func (c *goBinaryCataloger) newGoBinaryPackage(dep *debug.Module, mainModule, go Locations: file.NewLocationSet(locations...), // we don't have a way to express on a package or relationship the nature of "//indirect" markings on dependencies // so though the dependencies are complete and separable with the raw data, the data in the SBOM is not separable. - Dependencies: pkg.MixedDependencies, + Dependencies: dependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goVersion, H1Digest: dep.Sum, diff --git a/syft/pkg/cataloger/golang/parse_go_binary.go b/syft/pkg/cataloger/golang/parse_go_binary.go index b0fe56a4e..f8ff66662 100644 --- a/syft/pkg/cataloger/golang/parse_go_binary.go +++ b/syft/pkg/cataloger/golang/parse_go_binary.go @@ -134,6 +134,10 @@ func (c *goBinaryCataloger) buildGoPkgInfo(ctx context.Context, licenseScanner l mod.cryptoSettings, experiments, lics, + // the buildinfo section is a flat list of dependencies missing all edge information. So all direct and indirect + // dependencies are related directly to the main module. This means that we don't have any way to discover + // the completeness of the dependency's dependencies, thus they are incomplete. + pkg.IncompleteDependencies, location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ) if pkg.IsValid(&p) { @@ -178,6 +182,9 @@ func (c *goBinaryCataloger) makeGoMainPackage(ctx context.Context, licenseScanne mod.cryptoSettings, experiments, lics, + // the buildinfo section is a flat list of dependencies missing all edge information. So all direct and indirect + // dependencies are related directly to the main module. + pkg.CompleteWithIndirectDependencies, location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ) diff --git a/syft/pkg/cataloger/golang/parse_go_binary_test.go b/syft/pkg/cataloger/golang/parse_go_binary_test.go index 924950520..37def9285 100644 --- a/syft/pkg/cataloger/golang/parse_go_binary_test.go +++ b/syft/pkg/cataloger/golang/parse_go_binary_test.go @@ -161,7 +161,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.CompleteWithIndirectDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -209,7 +209,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{}, }, }, @@ -255,7 +255,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -294,7 +294,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.CompleteWithIndirectDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -369,7 +369,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.CompleteWithIndirectDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -437,7 +437,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.CompleteWithIndirectDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -503,7 +503,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.CompleteWithIndirectDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -561,7 +561,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.CompleteWithIndirectDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -619,7 +619,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.CompleteWithIndirectDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -678,7 +678,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.CompleteWithIndirectDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -751,7 +751,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -773,7 +773,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -831,7 +831,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -853,7 +853,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -897,7 +897,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.CompleteWithIndirectDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: goCompiledVersion, Architecture: archDetails, @@ -957,7 +957,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.CompleteWithIndirectDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: "go1.22.2", Architecture: archDetails, @@ -1010,7 +1010,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: "go1.22.2", Architecture: archDetails, @@ -1031,7 +1031,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ), - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.CompleteWithIndirectDependencies, Metadata: pkg.GolangBinaryBuildinfoEntry{ GoCompiledVersion: "go1.22.2", BuildSettings: []pkg.KeyValue{ diff --git a/syft/pkg/cataloger/golang/parse_go_mod.go b/syft/pkg/cataloger/golang/parse_go_mod.go index 14786c94b..eb3e2844e 100644 --- a/syft/pkg/cataloger/golang/parse_go_mod.go +++ b/syft/pkg/cataloger/golang/parse_go_mod.go @@ -59,16 +59,14 @@ func (c *goModCataloger) parseGoModFile(ctx context.Context, resolver file.Resol } packages[m.Mod.Path] = pkg.Package{ - Name: m.Mod.Path, - Version: m.Mod.Version, - Licenses: pkg.NewLicenseSet(lics...), - Locations: file.NewLocationSet(reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), - PURL: packageURL(m.Mod.Path, m.Mod.Version), - Language: pkg.Go, - Type: pkg.GoModulePkg, - // we don't have a way to express on a package or relationship the nature of "//indirect" markings on dependencies - // so though the dependencies are complete and separable with the raw data, the data in the SBOM is not separable. - Dependencies: pkg.MixedDependencies, + Name: m.Mod.Path, + Version: m.Mod.Version, + Licenses: pkg.NewLicenseSet(lics...), + Locations: file.NewLocationSet(reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), + PURL: packageURL(m.Mod.Path, m.Mod.Version), + Language: pkg.Go, + Type: pkg.GoModulePkg, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{ H1Digest: digests[fmt.Sprintf("%s %s", m.Mod.Path, m.Mod.Version)], }, @@ -87,16 +85,14 @@ func (c *goModCataloger) parseGoModFile(ctx context.Context, resolver file.Resol delete(packages, m.Old.Path) packages[m.New.Path] = pkg.Package{ - Name: m.New.Path, - Version: m.New.Version, - Licenses: pkg.NewLicenseSet(lics...), - Locations: file.NewLocationSet(reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), - PURL: packageURL(m.New.Path, m.New.Version), - Language: pkg.Go, - Type: pkg.GoModulePkg, - // we don't have a way to express on a package or relationship the nature of "//indirect" markings on dependencies - // so though the dependencies are complete and separable with the raw data, the data in the SBOM is not separable. - Dependencies: pkg.MixedDependencies, + Name: m.New.Path, + Version: m.New.Version, + Licenses: pkg.NewLicenseSet(lics...), + Locations: file.NewLocationSet(reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), + PURL: packageURL(m.New.Path, m.New.Version), + Language: pkg.Go, + Type: pkg.GoModulePkg, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{ H1Digest: digests[fmt.Sprintf("%s %s", m.New.Path, m.New.Version)], }, diff --git a/syft/pkg/cataloger/golang/parse_go_mod_test.go b/syft/pkg/cataloger/golang/parse_go_mod_test.go index 3c699b8a0..8e2243d89 100644 --- a/syft/pkg/cataloger/golang/parse_go_mod_test.go +++ b/syft/pkg/cataloger/golang/parse_go_mod_test.go @@ -24,7 +24,7 @@ func TestParseGoMod(t *testing.T) { Locations: file.NewLocationSet(file.NewLocation("test-fixtures/one-package")), Language: pkg.Go, Type: pkg.GoModulePkg, - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{}, }, }, @@ -40,7 +40,7 @@ func TestParseGoMod(t *testing.T) { Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Language: pkg.Go, Type: pkg.GoModulePkg, - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{}, }, { @@ -50,7 +50,7 @@ func TestParseGoMod(t *testing.T) { Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Language: pkg.Go, Type: pkg.GoModulePkg, - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{}, }, { @@ -60,7 +60,7 @@ func TestParseGoMod(t *testing.T) { Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Language: pkg.Go, Type: pkg.GoModulePkg, - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{}, }, { @@ -70,7 +70,7 @@ func TestParseGoMod(t *testing.T) { Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Language: pkg.Go, Type: pkg.GoModulePkg, - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{}, }, { @@ -80,7 +80,7 @@ func TestParseGoMod(t *testing.T) { Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Language: pkg.Go, Type: pkg.GoModulePkg, - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{}, }, { @@ -90,7 +90,7 @@ func TestParseGoMod(t *testing.T) { Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Language: pkg.Go, Type: pkg.GoModulePkg, - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{}, }, }, @@ -125,7 +125,7 @@ func Test_GoSumHashes(t *testing.T) { FoundBy: "go-module-file-cataloger", Language: pkg.Go, Type: pkg.GoModulePkg, - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{}, }, { @@ -136,7 +136,7 @@ func Test_GoSumHashes(t *testing.T) { FoundBy: "go-module-file-cataloger", Language: pkg.Go, Type: pkg.GoModulePkg, - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{ H1Digest: "h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=", }, @@ -149,7 +149,7 @@ func Test_GoSumHashes(t *testing.T) { FoundBy: "go-module-file-cataloger", Language: pkg.Go, Type: pkg.GoModulePkg, - Dependencies: pkg.MixedDependencies, + Dependencies: pkg.IncompleteDependencies, Metadata: pkg.GolangModuleEntry{ H1Digest: "h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=", }, diff --git a/syft/pkg/dependencies.go b/syft/pkg/dependencies.go index 8fe51ff51..95a4a3fcd 100644 --- a/syft/pkg/dependencies.go +++ b/syft/pkg/dependencies.go @@ -21,11 +21,11 @@ const ( // this package. Note that any indirect (transitive) dependencies must not be directly linked to this package. CompleteDependencies DependencyCompleteness = "complete" - // MixedDependencies is a superset of complete. It indicates that the package has all of its direct dependencies + // CompleteWithIndirectDependencies is a superset of complete. It indicates that the package has all of its direct dependencies // resolved as well as some or all of indirect dependencies. What is notable about this is that direct and // indirect dependencies are linked directly to this package and are not separable (you cannot distinguish between // a direct and indirect dependency from the perspective of this package). - MixedDependencies DependencyCompleteness = "mixed" + CompleteWithIndirectDependencies DependencyCompleteness = "complete-with-indirect" // IncompleteDependencies indicates that the package does not have all of its direct dependencies resolved. // This is useful in times when there is more than one mechanism at play for resolving dependencies and the @@ -37,8 +37,8 @@ func ParseDependencyCompleteness(value string) DependencyCompleteness { switch strings.ToLower(strings.TrimSpace(value)) { case string(CompleteDependencies): return CompleteDependencies - case string(MixedDependencies): - return MixedDependencies + case string(CompleteWithIndirectDependencies): + return CompleteWithIndirectDependencies case string(IncompleteDependencies): return IncompleteDependencies default: