mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
Merge pull request #403 from anchore/pom-persist-not-for-shaded-jars
Update parent pom persistence with regard to shaded jars
This commit is contained in:
commit
1b62b10b2b
@ -184,14 +184,17 @@ func (j *archiveParser) discoverPkgsFromAllPomProperties(parentPkg *pkg.Package)
|
||||
continue
|
||||
}
|
||||
|
||||
pkgs = append(pkgs, j.packagesFromPomProperties(*pomProperties, parentPkg)...)
|
||||
pkgFromPom := j.newPackageFromPomProperties(*pomProperties, parentPkg)
|
||||
if pkgFromPom != nil {
|
||||
pkgs = append(pkgs, *pkgFromPom)
|
||||
}
|
||||
}
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
// packagesFromPomProperties processes a single Maven POM properties for a given parent package, returning all listed Java packages found and
|
||||
// associating each discovered package to the given parent package.
|
||||
func (j *archiveParser) packagesFromPomProperties(pomProperties pkg.PomProperties, parentPkg *pkg.Package) []pkg.Package {
|
||||
func (j *archiveParser) newPackageFromPomProperties(pomProperties pkg.PomProperties, parentPkg *pkg.Package) *pkg.Package {
|
||||
// keep the artifact name within the virtual path if this package does not match the parent package
|
||||
vPathSuffix := ""
|
||||
if !strings.HasPrefix(pomProperties.ArtifactID, parentPkg.Name) {
|
||||
@ -213,45 +216,12 @@ func (j *archiveParser) packagesFromPomProperties(pomProperties pkg.PomPropertie
|
||||
},
|
||||
}
|
||||
|
||||
pkgKey := uniquePkgKey(&p)
|
||||
parentKey := uniquePkgKey(parentPkg)
|
||||
|
||||
// the name/version pair matches...
|
||||
matchesParentPkg := pkgKey == parentKey
|
||||
|
||||
// the virtual path matches...
|
||||
matchesParentPkg = matchesParentPkg || parentPkg.Metadata.(pkg.JavaMetadata).VirtualPath == virtualPath
|
||||
|
||||
// the pom artifactId has the parent name or vice versa
|
||||
if pomProperties.ArtifactID != "" {
|
||||
matchesParentPkg = matchesParentPkg || strings.Contains(parentPkg.Name, pomProperties.ArtifactID) || strings.Contains(pomProperties.ArtifactID, parentPkg.Name)
|
||||
}
|
||||
|
||||
if !matchesParentPkg {
|
||||
// only keep packages we haven't seen yet (and are not related to the parent package)
|
||||
return []pkg.Package{p}
|
||||
}
|
||||
|
||||
// we've run across more information about our parent package, add this info to the parent package metadata
|
||||
// the pom properties is typically a better source of information for name and version than the manifest
|
||||
if parentPkg.Name == "" {
|
||||
parentPkg.Name = p.Name
|
||||
}
|
||||
if parentPkg.Version == "" {
|
||||
parentPkg.Version = p.Version
|
||||
}
|
||||
|
||||
// We may have learned more about the type via data in the pom properties
|
||||
parentPkg.Type = p.Type
|
||||
|
||||
// keep the pom properties, but don't overwrite existing pom properties
|
||||
parentMetadata, ok := parentPkg.Metadata.(pkg.JavaMetadata)
|
||||
if ok && parentMetadata.PomProperties == nil {
|
||||
parentMetadata.PomProperties = &pomProperties
|
||||
parentPkg.Metadata = parentMetadata
|
||||
}
|
||||
|
||||
if packageIdentitiesMatch(p, parentPkg) {
|
||||
updatePackage(p, parentPkg)
|
||||
return nil
|
||||
}
|
||||
|
||||
return &p
|
||||
}
|
||||
|
||||
// discoverPkgsFromNestedArchives finds Java archives within Java archives, returning all listed Java packages found and
|
||||
@ -297,3 +267,50 @@ func (j *archiveParser) discoverPkgsFromNestedArchives(parentPkg *pkg.Package) (
|
||||
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
func packageIdentitiesMatch(p pkg.Package, parentPkg *pkg.Package) bool {
|
||||
// the name/version pair matches...
|
||||
if uniquePkgKey(&p) == uniquePkgKey(parentPkg) {
|
||||
return true
|
||||
}
|
||||
|
||||
metadata := p.Metadata.(pkg.JavaMetadata)
|
||||
|
||||
// the virtual path matches...
|
||||
if parentPkg.Metadata.(pkg.JavaMetadata).VirtualPath == metadata.VirtualPath {
|
||||
return true
|
||||
}
|
||||
|
||||
// the pom artifactId is the parent name
|
||||
// note: you CANNOT use name-is-subset-of-artifact-id or vice versa --this is too generic. Shaded jars are a good
|
||||
// example of this: where the package name is "cloudbees-analytics-segment-driver" and a child is "analytics", but
|
||||
// they do not indicate the same package.
|
||||
if metadata.PomProperties.ArtifactID != "" && parentPkg.Name == metadata.PomProperties.ArtifactID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func updatePackage(p pkg.Package, parentPkg *pkg.Package) {
|
||||
// we've run across more information about our parent package, add this info to the parent package metadata
|
||||
// the pom properties is typically a better source of information for name and version than the manifest
|
||||
parentPkg.Name = p.Name
|
||||
parentPkg.Version = p.Version
|
||||
|
||||
// we may have learned more about the type via data in the pom properties
|
||||
parentPkg.Type = p.Type
|
||||
|
||||
metadata, ok := p.Metadata.(pkg.JavaMetadata)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
pomPropertiesCopy := *metadata.PomProperties
|
||||
|
||||
// keep the pom properties, but don't overwrite existing pom properties
|
||||
parentMetadata, ok := parentPkg.Metadata.(pkg.JavaMetadata)
|
||||
if ok && parentMetadata.PomProperties == nil {
|
||||
parentMetadata.PomProperties = &pomPropertiesCopy
|
||||
parentPkg.Metadata = parentMetadata
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,7 +568,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
props *pkg.PomProperties
|
||||
parent *pkg.Package
|
||||
expectedParent pkg.Package
|
||||
expectedPackages []pkg.Package
|
||||
expectedPackage *pkg.Package
|
||||
}{
|
||||
{
|
||||
name: "go case: get a single package from pom properties",
|
||||
@ -599,8 +599,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedPackages: []pkg.Package{
|
||||
{
|
||||
expectedPackage: &pkg.Package{
|
||||
Name: "some-artifact-id",
|
||||
Version: "1.0",
|
||||
Language: pkg.Java,
|
||||
@ -627,7 +626,6 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "single package from pom properties that's a Jenkins plugin",
|
||||
props: &pkg.PomProperties{
|
||||
@ -657,8 +655,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedPackages: []pkg.Package{
|
||||
{
|
||||
expectedPackage: &pkg.Package{
|
||||
Name: "some-artifact-id",
|
||||
Version: "1.0",
|
||||
Language: pkg.Java,
|
||||
@ -685,7 +682,6 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "child matches parent by key",
|
||||
props: &pkg.PomProperties{
|
||||
@ -723,7 +719,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedPackages: nil,
|
||||
expectedPackage: nil,
|
||||
},
|
||||
{
|
||||
name: "child matches parent by key and is Jenkins plugin",
|
||||
@ -761,45 +757,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedPackages: nil,
|
||||
},
|
||||
{
|
||||
name: "child matches parent by virtual path",
|
||||
props: &pkg.PomProperties{
|
||||
Name: "some-name",
|
||||
GroupID: "some-group-id",
|
||||
ArtifactID: "some-parent-name", // note: matches parent package
|
||||
Version: "NOT_THE_PARENT_VERSION", // note: DOES NOT match parent package
|
||||
},
|
||||
parent: &pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
Manifest: nil,
|
||||
PomProperties: nil,
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedParent: pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
Manifest: nil,
|
||||
// note: we attach the discovered pom properties data
|
||||
PomProperties: &pkg.PomProperties{
|
||||
Name: "some-name",
|
||||
GroupID: "some-group-id",
|
||||
ArtifactID: "some-parent-name", // note: matches parent package
|
||||
Version: "NOT_THE_PARENT_VERSION", // note: DOES NOT match parent package
|
||||
},
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedPackages: nil,
|
||||
expectedPackage: nil,
|
||||
},
|
||||
{
|
||||
name: "child matches parent by virtual path -- override name and version",
|
||||
@ -810,11 +768,11 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
Version: "3.0", // note: DOES NOT match parent package
|
||||
},
|
||||
parent: &pkg.Package{
|
||||
Name: "", // note: empty
|
||||
Version: "", // note: empty
|
||||
Name: "", // note: empty, so should not be matched on
|
||||
Version: "", // note: empty, so should not be matched on
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
VirtualPath: virtualPath, // note: matching virtual path
|
||||
Manifest: nil,
|
||||
PomProperties: nil,
|
||||
Parent: nil,
|
||||
@ -825,56 +783,19 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
Version: "3.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
VirtualPath: virtualPath,
|
||||
Manifest: nil,
|
||||
// note: we attach the discovered pom properties data
|
||||
PomProperties: &pkg.PomProperties{
|
||||
Name: "some-name",
|
||||
GroupID: "some-group-id",
|
||||
ArtifactID: "some-parent-name", // note: DOES NOT match parent package
|
||||
Version: "3.0", // note: DOES NOT match parent package
|
||||
ArtifactID: "some-parent-name",
|
||||
Version: "3.0",
|
||||
},
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedPackages: nil,
|
||||
},
|
||||
{
|
||||
name: "child matches parent by virtual path -- do not override existing pom properties",
|
||||
props: &pkg.PomProperties{
|
||||
Name: "some-name",
|
||||
GroupID: "some-group-id",
|
||||
ArtifactID: "some-parent-name", // note: matches parent package
|
||||
Version: "NOT_THE_PARENT_VERSION", // note: DOES NOT match parent package
|
||||
},
|
||||
parent: &pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
Manifest: nil,
|
||||
PomProperties: &pkg.PomProperties{
|
||||
Name: "EXISTS", // note: this already exists and should not be overridden
|
||||
},
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedParent: pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
Manifest: nil,
|
||||
// note: we attach the discovered pom properties data
|
||||
PomProperties: &pkg.PomProperties{
|
||||
Name: "EXISTS", // note: this already exists and should not be overridden
|
||||
},
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedPackages: nil,
|
||||
expectedPackage: nil,
|
||||
},
|
||||
{
|
||||
name: "child matches parent by artifact id",
|
||||
@ -898,7 +819,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
// note: the SAME as the original parent values
|
||||
expectedParent: pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Version: "NOT_THE_PARENT_VERSION", // note: the version is updated from pom properties
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":NEW_VIRTUAL_PATH",
|
||||
@ -907,13 +828,13 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
PomProperties: &pkg.PomProperties{
|
||||
Name: "some-name",
|
||||
GroupID: "some-group-id",
|
||||
ArtifactID: "some-parent-name", // note: matches parent package
|
||||
Version: "NOT_THE_PARENT_VERSION", // note: DOES NOT match parent package
|
||||
ArtifactID: "some-parent-name",
|
||||
Version: "NOT_THE_PARENT_VERSION",
|
||||
},
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedPackages: nil,
|
||||
expectedPackage: nil,
|
||||
},
|
||||
}
|
||||
|
||||
@ -929,9 +850,9 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
t.Cleanup(cleanup)
|
||||
|
||||
// get the test data
|
||||
actualPackages := parser.packagesFromPomProperties(*test.props, test.parent)
|
||||
assert.Equal(t, test.expectedPackages, actualPackages)
|
||||
assert.Equal(t, test.expectedParent, *test.parent)
|
||||
actualPackage := parser.newPackageFromPomProperties(*test.props, test.parent)
|
||||
assert.Equal(t, test.expectedPackage, actualPackage, "new package doesn't match")
|
||||
assert.Equal(t, test.expectedParent, *test.parent, "parent doesn't match")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user