fix: improve groupid extraction for Jenkins plugins (#2815)

* fix: improve groupid extraction for Jenkins plugins

Consider the `Group-Id` java manifest property as this is typically set
for Jenkins plugins if there is no pom file

Signed-off-by: Weston Steimel <commits@weston.slmail.me>

* test: update java purl integration test image

Signed-off-by: Weston Steimel <commits@weston.slmail.me>

---------

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
This commit is contained in:
Weston Steimel 2024-08-12 17:01:44 +00:00 committed by GitHub
parent d2b33f1acb
commit df1e5b57fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 748 additions and 301 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1 +1,3 @@
FROM anchore/test_images:java-1abc58f@sha256:3add9f90e9ed35739cc99b7830767e09eec921052e2412adf4491648c741f066
FROM docker.io/anchore/test_images:java-88948cc@sha256:dea0e6c24636937f53bdc997d9960c2a18966d1e38bcd8ebd0c395d4e169b806
RUN rm /packages/gradle-7.1.1-bin.zip

View File

@ -23,6 +23,7 @@ var (
}
PrimaryJavaManifestGroupIDFields = []string{
"Group-Id",
"Bundle-SymbolicName",
"Extension-Name",
"Specification-Vendor",

View File

@ -155,9 +155,14 @@ func (j *archiveParser) parse(ctx context.Context) ([]pkg.Package, []artifact.Re
p := &pkgs[i]
if m, ok := p.Metadata.(pkg.JavaArchive); ok {
p.PURL = packageURL(p.Name, p.Version, m)
if strings.Contains(p.PURL, "io.jenkins.plugins") || strings.Contains(p.PURL, "org.jenkins-ci.plugins") {
p.Type = pkg.JenkinsPluginPkg
}
} else {
log.WithFields("package", p.String()).Warn("unable to extract java metadata to generate purl")
}
p.SetID()
}

View File

@ -65,7 +65,7 @@ func TestSearchMavenForLicenses(t *testing.T) {
// this fixture has a pomProjectObject and has a parent object
// it has no licenses on either which is the condition for testing
// the searchMavenForLicenses functionality
jarName := generateJavaMetadataJarFixture(t, tc.fixture)
jarName := generateJavaMetadataJarFixture(t, tc.fixture, "jar")
fixture, err := os.Open(jarName)
require.NoError(t, err)
@ -1082,6 +1082,7 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
tests := []struct {
name string
fixtureName string
fileExtension string
expectedPkgs []pkg.Package
expectedRelationships []artifact.Relationship
assignParent bool
@ -1274,6 +1275,45 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
fixtureName: "spring-instrumentation-4.3.0-1.0",
expectedPkgs: nil, // we expect no packages to be discovered when Weave-Classes present in the manifest
},
{
name: "Jenkins plugins assigned jenkins-plugin package type",
fixtureName: "gradle",
fileExtension: "hpi",
expectedPkgs: []pkg.Package{
{
Name: "gradle",
Version: "2.11",
Type: pkg.JenkinsPluginPkg,
Language: pkg.Java,
PURL: "pkg:maven/org.jenkins-ci.plugins/gradle@2.11",
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/jar-metadata/cache/gradle.hpi")),
Metadata: pkg.JavaArchive{
VirtualPath: "test-fixtures/jar-metadata/cache/gradle.hpi",
Manifest: &pkg.JavaManifest{
Main: pkg.KeyValues{
{Key: "Manifest-Version", Value: "1.0"},
{
Key: "Plugin-Dependencies",
Value: "maven-plugin:3.14;resolution:=optional...snip",
},
{Key: "Group-Id", Value: "org.jenkins-ci.plugins"},
{Key: "Minimum-Java-Version", Value: "1.8"},
{Key: "Short-Name", Value: "gradle"},
{Key: "Extension-Name", Value: "gradle"},
{Key: "Long-Name", Value: "Gradle Plugin"},
{Key: "Jenkins-Version", Value: "2.303.3"},
{Key: "Url", Value: "https://github.com/jenkinsci/gradle-plugin"},
{Key: "Compatible-Since-Version", Value: "1.0"},
{Key: "Plugin-Version", Value: "2.11"},
{Key: "Plugin-Developers", Value: "Stefan Wolf:wolfs:"},
},
},
// not under test
//ArchiveDigests: []file.Digest{{Algorithm: "sha1", Value: "d8bc1d9c428c96fe447e2c429fc4304d141024df"}},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -1285,7 +1325,7 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
tt.expectedPkgs[i].SetID()
}
pkgtest.NewCatalogTester().
FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName)).
FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName, tt.fileExtension)).
Expects(tt.expectedPkgs, tt.expectedRelationships).
WithCompareOptions(
cmpopts.IgnoreFields(pkg.JavaArchive{}, "ArchiveDigests"),
@ -1318,7 +1358,7 @@ func Test_deterministicMatchingPomProperties(t *testing.T) {
for _, test := range tests {
t.Run(test.fixture, func(t *testing.T) {
fixturePath := generateJavaMetadataJarFixture(t, test.fixture)
fixturePath := generateJavaMetadataJarFixture(t, test.fixture, "jar")
for i := 0; i < 5; i++ {
func() {
@ -1372,14 +1412,18 @@ func generateJavaBuildFixture(t *testing.T, fixturePath string) {
run(t, cmd)
}
func generateJavaMetadataJarFixture(t *testing.T, fixtureName string) string {
fixturePath := filepath.Join("test-fixtures/jar-metadata/cache/", fixtureName+".jar")
func generateJavaMetadataJarFixture(t *testing.T, fixtureName string, fileExtension string) string {
if fileExtension == "" {
fileExtension = "jar"
}
fixturePath := filepath.Join("test-fixtures/jar-metadata/cache/", fixtureName+"."+fileExtension)
if _, err := os.Stat(fixturePath); !os.IsNotExist(err) {
// fixture already exists...
return fixturePath
}
makeTask := filepath.Join("cache", fixtureName+".jar")
makeTask := filepath.Join("cache", fixtureName+"."+fileExtension)
t.Logf(color.Bold.Sprintf("Generating Fixture from 'make %s'", makeTask))
cwd, err := os.Getwd()

View File

@ -28,3 +28,8 @@ $(CACHE_DIR)/$(SPRING_INSTRUMENTATION).jar: $(CACHE_DIR)
$(CACHE_DIR)/$(MULTIPLE_MATCHING).jar: $(CACHE_DIR)
cd $(MULTIPLE_MATCHING) && zip -r $(CACHE_PATH)/$(MULTIPLE_MATCHING).jar .
# Jenkins plugins typically do not have the version included in the archive name,
# so it is important to not include it in the generated test fixture
$(CACHE_DIR)/gradle.hpi: $(CACHE_DIR)
cd jenkins-plugins/gradle/2.11 && zip -r $(CACHE_PATH)/gradle.hpi .

View File

@ -0,0 +1,13 @@
Manifest-Version: 1.0
Plugin-Dependencies: maven-plugin:3.14;resolution:=optional...snip
Group-Id: org.jenkins-ci.plugins
Minimum-Java-Version: 1.8
Short-Name: gradle
Extension-Name: gradle
Long-Name: Gradle Plugin
Jenkins-Version: 2.303.3
Url: https://github.com/jenkinsci/gradle-plugin
Compatible-Since-Version: 1.0
Plugin-Version: 2.11
Plugin-Developers: Stefan Wolf:wolfs: