mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
Enhance CPE generation for java GroupId and filtering (#402)
* enhance cpe generation for group id and filtering Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * rename group id const + add doc comment for HasAnyOfPrefixes Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
0c29090b42
commit
d9de63c837
14
internal/string_helpers.go
Normal file
14
internal/string_helpers.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
// HasAnyOfPrefixes returns an indication if the given string has any of the given prefixes.
|
||||||
|
func HasAnyOfPrefixes(input string, prefixes ...string) bool {
|
||||||
|
for _, prefix := range prefixes {
|
||||||
|
if strings.HasPrefix(input, prefix) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
65
internal/string_helpers_test.go
Normal file
65
internal/string_helpers_test.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHasAnyOfPrefixes(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
prefixes []string
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "go case",
|
||||||
|
input: "this has something",
|
||||||
|
prefixes: []string{
|
||||||
|
"this has",
|
||||||
|
"that does not have",
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no match",
|
||||||
|
input: "this has something",
|
||||||
|
prefixes: []string{
|
||||||
|
"this DOES NOT has",
|
||||||
|
"that does not have",
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
input: "this has something",
|
||||||
|
prefixes: []string{},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "positive match last",
|
||||||
|
input: "this has something",
|
||||||
|
prefixes: []string{
|
||||||
|
"that does not have",
|
||||||
|
"this has",
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty input",
|
||||||
|
input: "",
|
||||||
|
prefixes: []string{
|
||||||
|
"that does not have",
|
||||||
|
"this has",
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
assert.Equal(t, test.expected, HasAnyOfPrefixes(test.input, test.prefixes...))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,12 +10,6 @@ import (
|
|||||||
"github.com/facebookincubator/nvdtools/wfn"
|
"github.com/facebookincubator/nvdtools/wfn"
|
||||||
)
|
)
|
||||||
|
|
||||||
// this is functionally equivalent to "*" and consistent with no input given (thus easier to test)
|
|
||||||
const any = ""
|
|
||||||
|
|
||||||
// this is a static mapping of known package names (keys) to official cpe names for each package
|
|
||||||
type candidateStore map[pkg.Type]map[string][]string
|
|
||||||
|
|
||||||
var productCandidatesByPkgType = candidateStore{
|
var productCandidatesByPkgType = candidateStore{
|
||||||
pkg.JavaPkg: {
|
pkg.JavaPkg: {
|
||||||
"springframework": []string{"spring_framework", "springsource_spring_framework"},
|
"springframework": []string{"spring_framework", "springsource_spring_framework"},
|
||||||
@ -42,6 +36,25 @@ var productCandidatesByPkgType = candidateStore{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cpeFilters = []filterFn{
|
||||||
|
// nolint: goconst
|
||||||
|
func(cpe pkg.CPE, p pkg.Package) bool {
|
||||||
|
// jira / atlassian should not apply to clients
|
||||||
|
if cpe.Vendor == "atlassian" && cpe.Product == "jira" && strings.Contains(p.Name, "client") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if cpe.Vendor == "jira" && cpe.Product == "jira" && strings.Contains(p.Name, "client") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
type filterFn func(cpe pkg.CPE, p pkg.Package) bool
|
||||||
|
|
||||||
|
// this is a static mapping of known package names (keys) to official cpe names for each package
|
||||||
|
type candidateStore map[pkg.Type]map[string][]string
|
||||||
|
|
||||||
func (s candidateStore) getCandidates(t pkg.Type, key string) []string {
|
func (s candidateStore) getCandidates(t pkg.Type, key string) []string {
|
||||||
if _, ok := s[t]; !ok {
|
if _, ok := s[t]; !ok {
|
||||||
return nil
|
return nil
|
||||||
@ -65,6 +78,20 @@ func newCPE(product, vendor, version, targetSW string) wfn.Attributes {
|
|||||||
return cpe
|
return cpe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func filterCpes(cpes []pkg.CPE, p pkg.Package, filters ...filterFn) (result []pkg.CPE) {
|
||||||
|
cpeLoop:
|
||||||
|
for _, cpe := range cpes {
|
||||||
|
for _, fn := range filters {
|
||||||
|
if fn(cpe, p) {
|
||||||
|
continue cpeLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// all filter functions passed on filtering this CPE
|
||||||
|
result = append(result, cpe)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// generatePackageCPEs Create a list of CPEs, trying to guess the vendor, product tuple and setting TargetSoftware if possible
|
// generatePackageCPEs Create a list of CPEs, trying to guess the vendor, product tuple and setting TargetSoftware if possible
|
||||||
func generatePackageCPEs(p pkg.Package) []pkg.CPE {
|
func generatePackageCPEs(p pkg.Package) []pkg.CPE {
|
||||||
targetSws := candidateTargetSoftwareAttrs(p)
|
targetSws := candidateTargetSoftwareAttrs(p)
|
||||||
@ -74,8 +101,8 @@ func generatePackageCPEs(p pkg.Package) []pkg.CPE {
|
|||||||
keys := internal.NewStringSet()
|
keys := internal.NewStringSet()
|
||||||
cpes := make([]pkg.CPE, 0)
|
cpes := make([]pkg.CPE, 0)
|
||||||
for _, product := range products {
|
for _, product := range products {
|
||||||
for _, vendor := range append([]string{any}, vendors...) {
|
for _, vendor := range append([]string{wfn.Any}, vendors...) {
|
||||||
for _, targetSw := range append([]string{any}, targetSws...) {
|
for _, targetSw := range append([]string{wfn.Any}, targetSws...) {
|
||||||
// prevent duplicate entries...
|
// prevent duplicate entries...
|
||||||
key := fmt.Sprintf("%s|%s|%s|%s", product, vendor, p.Version, targetSw)
|
key := fmt.Sprintf("%s|%s|%s|%s", product, vendor, p.Version, targetSw)
|
||||||
if keys.Contains(key) {
|
if keys.Contains(key) {
|
||||||
@ -90,6 +117,9 @@ func generatePackageCPEs(p pkg.Package) []pkg.CPE {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// filter out any known combinations that don't accurately represent this package
|
||||||
|
cpes = filterCpes(cpes, p, cpeFilters...)
|
||||||
|
|
||||||
sort.Sort(ByCPESpecificity(cpes))
|
sort.Sort(ByCPESpecificity(cpes))
|
||||||
|
|
||||||
return cpes
|
return cpes
|
||||||
@ -157,6 +187,11 @@ func candidateProducts(p pkg.Package) []string {
|
|||||||
|
|
||||||
func candidateProductsForJava(p pkg.Package) []string {
|
func candidateProductsForJava(p pkg.Package) []string {
|
||||||
if product, _ := productAndVendorFromPomPropertiesGroupID(p); product != "" {
|
if product, _ := productAndVendorFromPomPropertiesGroupID(p); product != "" {
|
||||||
|
// ignore group ID info from a jenkins plugin, as using this info may imply that this package
|
||||||
|
// CPE belongs to the cloudbees org (or similar) which is wrong.
|
||||||
|
if p.Type == pkg.JenkinsPluginPkg && strings.ToLower(product) == "jenkins" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return []string{product}
|
return []string{product}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +212,7 @@ func productAndVendorFromPomPropertiesGroupID(p pkg.Package) (string, string) {
|
|||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if !hasAnyOfPrefixes(groupID, "com", "org") {
|
if !internal.HasAnyOfPrefixes(groupID, "com", "org") {
|
||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,26 +244,7 @@ func shouldConsiderGroupID(groupID string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
excludedGroupIDs := []string{
|
excludedGroupIDs := append([]string{pkg.JiraPluginPomPropertiesGroupID}, pkg.JenkinsPluginPomPropertiesGroupIDs...)
|
||||||
pkg.PomPropertiesGroupIDJiraPlugins,
|
|
||||||
pkg.PomPropertiesGroupIDJenkinsPlugins,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, excludedGroupID := range excludedGroupIDs {
|
return !internal.HasAnyOfPrefixes(groupID, excludedGroupIDs...)
|
||||||
if groupID == excludedGroupID {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasAnyOfPrefixes(input string, prefixes ...string) bool {
|
|
||||||
for _, prefix := range prefixes {
|
|
||||||
if strings.HasPrefix(input, prefix) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -220,7 +220,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "jenkins package identified via groupId",
|
name: "cloudbees jenkins package identified via groupId",
|
||||||
p: pkg.Package{
|
p: pkg.Package{
|
||||||
Name: "name",
|
Name: "name",
|
||||||
Version: "3.2",
|
Version: "3.2",
|
||||||
@ -242,6 +242,135 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
|||||||
"cpe:2.3:a:name:name:3.2:*:*:*:*:cloudbees_jenkins:*:*",
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:cloudbees_jenkins:*:*",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "jenkins.io package identified via groupId prefix",
|
||||||
|
p: pkg.Package{
|
||||||
|
Name: "name",
|
||||||
|
Version: "3.2",
|
||||||
|
FoundBy: "some-analyzer",
|
||||||
|
Language: pkg.Java,
|
||||||
|
Type: pkg.JenkinsPluginPkg,
|
||||||
|
Metadata: pkg.JavaMetadata{
|
||||||
|
PomProperties: &pkg.PomProperties{
|
||||||
|
GroupID: "io.jenkins.plugins.name.something",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:jenkins:*:*",
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:cloudbees_jenkins:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:jenkins:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:cloudbees_jenkins:*:*",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "jenkins.io package identified via groupId",
|
||||||
|
p: pkg.Package{
|
||||||
|
Name: "name",
|
||||||
|
Version: "3.2",
|
||||||
|
FoundBy: "some-analyzer",
|
||||||
|
Language: pkg.Java,
|
||||||
|
Type: pkg.JenkinsPluginPkg,
|
||||||
|
Metadata: pkg.JavaMetadata{
|
||||||
|
PomProperties: &pkg.PomProperties{
|
||||||
|
GroupID: "io.jenkins.plugins",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:jenkins:*:*",
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:cloudbees_jenkins:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:jenkins:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:cloudbees_jenkins:*:*",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "jenkins-ci.io package identified via groupId",
|
||||||
|
p: pkg.Package{
|
||||||
|
Name: "name",
|
||||||
|
Version: "3.2",
|
||||||
|
FoundBy: "some-analyzer",
|
||||||
|
Language: pkg.Java,
|
||||||
|
Type: pkg.JenkinsPluginPkg,
|
||||||
|
Metadata: pkg.JavaMetadata{
|
||||||
|
PomProperties: &pkg.PomProperties{
|
||||||
|
GroupID: "io.jenkins-ci.plugins",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:jenkins:*:*",
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:cloudbees_jenkins:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:jenkins:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:cloudbees_jenkins:*:*",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "jenkins-ci.org package identified via groupId",
|
||||||
|
p: pkg.Package{
|
||||||
|
Name: "name",
|
||||||
|
Version: "3.2",
|
||||||
|
FoundBy: "some-analyzer",
|
||||||
|
Language: pkg.Java,
|
||||||
|
Type: pkg.JenkinsPluginPkg,
|
||||||
|
Metadata: pkg.JavaMetadata{
|
||||||
|
PomProperties: &pkg.PomProperties{
|
||||||
|
GroupID: "org.jenkins-ci.plugins",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:jenkins:*:*",
|
||||||
|
"cpe:2.3:a:*:name:3.2:*:*:*:*:cloudbees_jenkins:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:jenkins:*:*",
|
||||||
|
"cpe:2.3:a:name:name:3.2:*:*:*:*:cloudbees_jenkins:*:*",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "jira-atlassian filtering",
|
||||||
|
p: pkg.Package{
|
||||||
|
Name: "jira_client_core",
|
||||||
|
Version: "3.2",
|
||||||
|
FoundBy: "some-analyzer",
|
||||||
|
Language: pkg.Java,
|
||||||
|
Type: pkg.JavaPkg,
|
||||||
|
MetadataType: pkg.JavaMetadataType,
|
||||||
|
Metadata: pkg.JavaMetadata{
|
||||||
|
PomProperties: &pkg.PomProperties{
|
||||||
|
GroupID: "org.atlassian.jira",
|
||||||
|
ArtifactID: "jira_client_core",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
"cpe:2.3:a:*:jira:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:*:jira:3.2:*:*:*:*:java:*:*",
|
||||||
|
"cpe:2.3:a:*:jira:3.2:*:*:*:*:maven:*:*",
|
||||||
|
"cpe:2.3:a:*:jira_client_core:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:*:jira_client_core:3.2:*:*:*:*:java:*:*",
|
||||||
|
"cpe:2.3:a:*:jira_client_core:3.2:*:*:*:*:maven:*:*",
|
||||||
|
"cpe:2.3:a:atlassian:jira_client_core:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:atlassian:jira_client_core:3.2:*:*:*:*:java:*:*",
|
||||||
|
"cpe:2.3:a:atlassian:jira_client_core:3.2:*:*:*:*:maven:*:*",
|
||||||
|
"cpe:2.3:a:jira:jira_client_core:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:jira:jira_client_core:3.2:*:*:*:*:java:*:*",
|
||||||
|
"cpe:2.3:a:jira:jira_client_core:3.2:*:*:*:*:maven:*:*",
|
||||||
|
"cpe:2.3:a:jira_client_core:jira:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:jira_client_core:jira:3.2:*:*:*:*:java:*:*",
|
||||||
|
"cpe:2.3:a:jira_client_core:jira:3.2:*:*:*:*:maven:*:*",
|
||||||
|
"cpe:2.3:a:jira_client_core:jira_client_core:3.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:jira_client_core:jira_client_core:3.2:*:*:*:*:java:*:*",
|
||||||
|
"cpe:2.3:a:jira_client_core:jira_client_core:3.2:*:*:*:*:maven:*:*",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|||||||
@ -106,8 +106,6 @@ func (j *archiveParser) parse() ([]pkg.Package, error) {
|
|||||||
|
|
||||||
// lastly, add the parent package to the list (assuming the parent exists)
|
// lastly, add the parent package to the list (assuming the parent exists)
|
||||||
if parentPkg != nil {
|
if parentPkg != nil {
|
||||||
// only the parent package gets the type, nested packages may be of a different package type (or not of a package type at all, since they may not be bundled)
|
|
||||||
parentPkg.Type = j.fileInfo.pkgType()
|
|
||||||
pkgs = append([]pkg.Package{*parentPkg}, pkgs...)
|
pkgs = append([]pkg.Package{*parentPkg}, pkgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +141,7 @@ func (j *archiveParser) discoverMainPackage() (*pkg.Package, error) {
|
|||||||
Name: selectName(manifest, j.fileInfo),
|
Name: selectName(manifest, j.fileInfo),
|
||||||
Version: selectVersion(manifest, j.fileInfo),
|
Version: selectVersion(manifest, j.fileInfo),
|
||||||
Language: pkg.Java,
|
Language: pkg.Java,
|
||||||
Type: pkg.JavaPkg,
|
Type: j.fileInfo.pkgType(),
|
||||||
MetadataType: pkg.JavaMetadataType,
|
MetadataType: pkg.JavaMetadataType,
|
||||||
Metadata: pkg.JavaMetadata{
|
Metadata: pkg.JavaMetadata{
|
||||||
VirtualPath: j.virtualPath,
|
VirtualPath: j.virtualPath,
|
||||||
|
|||||||
@ -1,6 +1,19 @@
|
|||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
import "github.com/package-url/packageurl-go"
|
import (
|
||||||
|
"github.com/anchore/syft/internal"
|
||||||
|
"github.com/package-url/packageurl-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
const JiraPluginPomPropertiesGroupID = "com.atlassian.jira.plugins"
|
||||||
|
|
||||||
|
var JenkinsPluginPomPropertiesGroupIDs = []string{
|
||||||
|
"io.jenkins.plugins",
|
||||||
|
"org.jenkins.plugins",
|
||||||
|
"org.jenkins-ci.plugins",
|
||||||
|
"io.jenkins-ci.plugins",
|
||||||
|
"com.cloudbees.jenkins.plugins",
|
||||||
|
}
|
||||||
|
|
||||||
// JavaMetadata encapsulates all Java ecosystem metadata for a package as well as an (optional) parent relationship.
|
// JavaMetadata encapsulates all Java ecosystem metadata for a package as well as an (optional) parent relationship.
|
||||||
type JavaMetadata struct {
|
type JavaMetadata struct {
|
||||||
@ -22,7 +35,7 @@ type PomProperties struct {
|
|||||||
|
|
||||||
// PkgTypeIndicated returns the package Type indicated by the data contained in the PomProperties.
|
// PkgTypeIndicated returns the package Type indicated by the data contained in the PomProperties.
|
||||||
func (p PomProperties) PkgTypeIndicated() Type {
|
func (p PomProperties) PkgTypeIndicated() Type {
|
||||||
if p.GroupID == PomPropertiesGroupIDJenkinsPlugins {
|
if internal.HasAnyOfPrefixes(p.GroupID, JenkinsPluginPomPropertiesGroupIDs...) {
|
||||||
return JenkinsPluginPkg
|
return JenkinsPluginPkg
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +65,3 @@ func (m JavaMetadata) PackageURL() string {
|
|||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
const PomPropertiesGroupIDJenkinsPlugins = "com.cloudbees.jenkins.plugins"
|
|
||||||
const PomPropertiesGroupIDJiraPlugins = "com.atlassian.jira.plugins"
|
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/sergi/go-diff/diffmatchpatch"
|
"github.com/sergi/go-diff/diffmatchpatch"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPomProperties_PkgTypeIndicated(t *testing.T) {
|
func TestPomProperties_PkgTypeIndicated(t *testing.T) {
|
||||||
@ -24,7 +25,7 @@ func TestPomProperties_PkgTypeIndicated(t *testing.T) {
|
|||||||
expectedType: JavaPkg,
|
expectedType: JavaPkg,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "jenkins plugin",
|
name: "cloudbees jenkins plugin",
|
||||||
pomProperties: PomProperties{
|
pomProperties: PomProperties{
|
||||||
Path: "some path",
|
Path: "some path",
|
||||||
Name: "some name",
|
Name: "some name",
|
||||||
@ -34,6 +35,61 @@ func TestPomProperties_PkgTypeIndicated(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expectedType: JenkinsPluginPkg,
|
expectedType: JenkinsPluginPkg,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "jenkins.io plugin",
|
||||||
|
pomProperties: PomProperties{
|
||||||
|
Path: "some path",
|
||||||
|
Name: "some name",
|
||||||
|
GroupID: "io.jenkins.plugins",
|
||||||
|
ArtifactID: "some artifact ID",
|
||||||
|
Version: "1",
|
||||||
|
},
|
||||||
|
expectedType: JenkinsPluginPkg,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "jenkins-ci.io plugin",
|
||||||
|
pomProperties: PomProperties{
|
||||||
|
Path: "some path",
|
||||||
|
Name: "some name",
|
||||||
|
GroupID: "io.jenkins-ci.plugins",
|
||||||
|
ArtifactID: "some artifact ID",
|
||||||
|
Version: "1",
|
||||||
|
},
|
||||||
|
expectedType: JenkinsPluginPkg,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "jenkins-ci.org plugin",
|
||||||
|
pomProperties: PomProperties{
|
||||||
|
Path: "some path",
|
||||||
|
Name: "some name",
|
||||||
|
GroupID: "org.jenkins-ci.plugins",
|
||||||
|
ArtifactID: "some artifact ID",
|
||||||
|
Version: "1",
|
||||||
|
},
|
||||||
|
expectedType: JenkinsPluginPkg,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "jenkins.org plugin",
|
||||||
|
pomProperties: PomProperties{
|
||||||
|
Path: "some path",
|
||||||
|
Name: "some name",
|
||||||
|
GroupID: "org.jenkins.plugins",
|
||||||
|
ArtifactID: "some artifact ID",
|
||||||
|
Version: "1",
|
||||||
|
},
|
||||||
|
expectedType: JenkinsPluginPkg,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "jenkins plugin prefix",
|
||||||
|
pomProperties: PomProperties{
|
||||||
|
Path: "some path",
|
||||||
|
Name: "some name",
|
||||||
|
GroupID: "com.cloudbees.jenkins.plugins.bluesteel",
|
||||||
|
ArtifactID: "some artifact ID",
|
||||||
|
Version: "1",
|
||||||
|
},
|
||||||
|
expectedType: JenkinsPluginPkg,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
|
|||||||
@ -6,6 +6,7 @@ type testCase struct {
|
|||||||
name string
|
name string
|
||||||
pkgType pkg.Type
|
pkgType pkg.Type
|
||||||
pkgLanguage pkg.Language
|
pkgLanguage pkg.Language
|
||||||
|
duplicates int
|
||||||
pkgInfo map[string]string
|
pkgInfo map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +156,6 @@ var commonTestCases = []testCase{
|
|||||||
pkgLanguage: pkg.Java,
|
pkgLanguage: pkg.Java,
|
||||||
pkgInfo: map[string]string{
|
pkgInfo: map[string]string{
|
||||||
"example-java-app-maven": "0.1.0",
|
"example-java-app-maven": "0.1.0",
|
||||||
"example-jenkins-plugin": "1.0-SNAPSHOT", // the jenkins HPI file has a nested JAR of the same name
|
|
||||||
"joda-time": "2.9.2",
|
"joda-time": "2.9.2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -163,6 +163,7 @@ var commonTestCases = []testCase{
|
|||||||
name: "find jenkins plugins",
|
name: "find jenkins plugins",
|
||||||
pkgType: pkg.JenkinsPluginPkg,
|
pkgType: pkg.JenkinsPluginPkg,
|
||||||
pkgLanguage: pkg.Java,
|
pkgLanguage: pkg.Java,
|
||||||
|
duplicates: 1, // there is a "example-jenkins-plugin" HPI, and nested within that a JAR of the same name
|
||||||
pkgInfo: map[string]string{
|
pkgInfo: map[string]string{
|
||||||
"example-jenkins-plugin": "1.0-SNAPSHOT",
|
"example-jenkins-plugin": "1.0-SNAPSHOT",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -96,7 +96,7 @@ func TestPkgCoverageImage(t *testing.T) {
|
|||||||
pkgCount++
|
pkgCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
if pkgCount != len(c.pkgInfo) {
|
if pkgCount != len(c.pkgInfo)+c.duplicates {
|
||||||
t.Logf("Discovered packages of type %+v", c.pkgType)
|
t.Logf("Discovered packages of type %+v", c.pkgType)
|
||||||
for a := range catalog.Enumerate(c.pkgType) {
|
for a := range catalog.Enumerate(c.pkgType) {
|
||||||
t.Log(" ", a)
|
t.Log(" ", a)
|
||||||
@ -175,7 +175,7 @@ func TestPkgCoverageDirectory(t *testing.T) {
|
|||||||
actualPkgCount++
|
actualPkgCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
if actualPkgCount != len(test.pkgInfo) {
|
if actualPkgCount != len(test.pkgInfo)+test.duplicates {
|
||||||
for actualPkg := range catalog.Enumerate(test.pkgType) {
|
for actualPkg := range catalog.Enumerate(test.pkgType) {
|
||||||
t.Log(" ", actualPkg)
|
t.Log(" ", actualPkg)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user