Find Java package versions in additional manifest sections (#673)

* Add failing test for missing versions

Signed-off-by: Dan Luhring <dan+github@luhrings.com>

* Look through all named sections for version

Signed-off-by: Dan Luhring <dan+github@luhrings.com>

* Consistent installation of yajsv

Signed-off-by: Dan Luhring <dan+github@luhrings.com>

* Adjust output text for test assertion

Signed-off-by: Dan Luhring <dan+github@luhrings.com>
This commit is contained in:
Dan Luhring 2021-12-13 15:39:42 -05:00 committed by GitHub
parent ab9fe53ff2
commit f98868b55e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 114 additions and 15 deletions

View File

@ -82,7 +82,7 @@ help:
.PHONY: ci-bootstrap
ci-bootstrap:
DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y bc jq libxml2-utils && go install github.com/neilpa/yajsv@latest
DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y bc jq libxml2-utils
.PHONY:
ci-bootstrap-mac:
@ -101,6 +101,7 @@ bootstrap-tools: $(TEMPDIR)
curl -sSfL https://raw.githubusercontent.com/wagoodman/go-bouncer/master/bouncer.sh | sh -s -- -b $(TEMPDIR)/ v0.2.0
curl -sSfL https://raw.githubusercontent.com/anchore/chronicle/main/install.sh | sh -s -- -b $(TEMPDIR)/ v0.3.0
.github/scripts/goreleaser-install.sh -b $(TEMPDIR)/ v0.177.0
GOBIN="$(shell realpath $(TEMPDIR))" go install github.com/neilpa/yajsv@v1.4.0
.PHONY: bootstrap-go
bootstrap-go:

View File

@ -4,4 +4,4 @@ validate-schema:
go run ../../main.go ubuntu:latest -vv -o cyclonedx > bom.xml
xmllint --noout --schema ./cyclonedx.xsd bom.xml
go run ../../main.go ubuntu:latest -vv -o cyclonedx-json > bom.json
yajsv -s bom-1.3.schema.json bom.json
../../.tmp/yajsv -s bom-1.3.schema.json bom.json

View File

@ -115,16 +115,39 @@ func selectName(manifest *pkg.JavaManifest, filenameObj archiveFilename) string
}
func selectVersion(manifest *pkg.JavaManifest, filenameObj archiveFilename) string {
var version string
switch {
case filenameObj.version != "":
version = filenameObj.version
case manifest.Main["Implementation-Version"] != "":
version = manifest.Main["Implementation-Version"]
case manifest.Main["Specification-Version"] != "":
version = manifest.Main["Specification-Version"]
case manifest.Main["Plugin-Version"] != "":
version = manifest.Main["Plugin-Version"]
if v := filenameObj.version; v != "" {
return v
}
return version
if manifest == nil {
return ""
}
fieldNames := []string{
"Implementation-Version",
"Specification-Version",
"Plugin-Version",
}
for _, fieldName := range fieldNames {
if v := fieldValueFromManifest(*manifest, fieldName); v != "" {
return v
}
}
return ""
}
func fieldValueFromManifest(manifest pkg.JavaManifest, fieldName string) string {
if value := manifest.Main[fieldName]; value != "" {
return value
}
for _, section := range manifest.NamedSections {
if value := section[fieldName]; value != "" {
return value
}
}
return ""
}

View File

@ -5,6 +5,8 @@ import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/anchore/syft/syft/pkg"
"github.com/go-test/deep"
)
@ -145,5 +147,78 @@ func TestSelectName(t *testing.T) {
}
})
}
}
func TestSelectVersion(t *testing.T) {
tests := []struct {
name string
manifest pkg.JavaManifest
archive archiveFilename
expected string
}{
{
name: "Get name from Implementation-Version",
archive: archiveFilename{},
manifest: pkg.JavaManifest{
Main: map[string]string{
"Implementation-Version": "1.8.2",
},
},
expected: "1.8.2",
},
{
name: "Implementation-Version takes precedence over Specification-Version",
manifest: pkg.JavaManifest{
Main: map[string]string{
"Implementation-Version": "1.8.2",
"Specification-Version": "1.0",
},
},
expected: "1.8.2",
},
{
name: "Implementation-Version found outside the main section",
manifest: pkg.JavaManifest{
Main: map[string]string{
"Manifest-Version": "1.0",
"Ant-Version": "Apache Ant 1.8.2",
"Created-By": "1.5.0_22-b03 (Sun Microsystems Inc.)",
},
NamedSections: map[string]map[string]string{
"org/apache/tools/ant/taskdefs/optional/": {
"Implementation-Version": "1.8.2",
},
},
},
expected: "1.8.2",
},
{
name: "Implementation-Version takes precedence over Specification-Version in subsequent section",
manifest: pkg.JavaManifest{
Main: map[string]string{
"Manifest-Version": "1.0",
"Ant-Version": "Apache Ant 1.8.2",
"Created-By": "1.5.0_22-b03 (Sun Microsystems Inc.)",
"Specification-Version": "2.0",
},
NamedSections: map[string]map[string]string{
"org/apache/tools/ant/taskdefs/optional/": {
"Specification-Version": "1.8",
},
"some-other-section": {
"Implementation-Version": "1.8.2",
},
},
},
expected: "1.8.2",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result := selectVersion(&test.manifest, test.archive)
assert.Equal(t, test.expected, result)
})
}
}

View File

@ -42,7 +42,7 @@ func TestPackagesCmdFlags(t *testing.T) {
// a CLI test is much easier.
args: []string{"packages", "-vv", badBinariesImage},
assertions: []traitAssertion{
assertInOutput("recovered from panic while parse go binary"),
assertInOutput("could not parse possible go binary"),
assertSuccessfulReturnCode,
},
},