mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
translate maps to sequences in pkg metadata (#2553)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
parent
fef0e54c0f
commit
6107e5e2ad
@ -3,5 +3,5 @@ package internal
|
|||||||
const (
|
const (
|
||||||
// JSONSchemaVersion is the current schema version output by the JSON encoder
|
// JSONSchemaVersion is the current schema version output by the JSON encoder
|
||||||
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
|
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
|
||||||
JSONSchemaVersion = "14.0.0"
|
JSONSchemaVersion = "15.0.0"
|
||||||
)
|
)
|
||||||
|
|||||||
2147
schema/json/schema-15.0.0.json
Normal file
2147
schema/json/schema-15.0.0.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -68,6 +68,10 @@ func findMetadataDefinitionNames(paths ...string) ([]string, error) {
|
|||||||
// any definition that is used within another struct should not be considered a top-level metadata definition
|
// any definition that is used within another struct should not be considered a top-level metadata definition
|
||||||
names.Remove(usedNames.List()...)
|
names.Remove(usedNames.List()...)
|
||||||
|
|
||||||
|
// remove known exceptions, that is, types exported in the pkg Package that are not used
|
||||||
|
// in a metadata type but are not metadata types themselves.
|
||||||
|
names.Remove("Licenses", "KeyValue")
|
||||||
|
|
||||||
strNames := names.List()
|
strNames := names.List()
|
||||||
sort.Strings(strNames)
|
sort.Strings(strNames)
|
||||||
|
|
||||||
@ -114,7 +118,11 @@ func findMetadataDefinitionNamesInFile(path string) ([]string, []string, error)
|
|||||||
|
|
||||||
structType := extractStructType(spec.Type)
|
structType := extractStructType(spec.Type)
|
||||||
if structType == nil {
|
if structType == nil {
|
||||||
continue
|
// maybe this is a slice of structs? This is useful (say type KeyValues is []KeyValue)
|
||||||
|
structType = extractSliceOfStructType(spec.Type)
|
||||||
|
if structType == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
metadataDefinitions = append(metadataDefinitions, name)
|
metadataDefinitions = append(metadataDefinitions, name)
|
||||||
@ -124,6 +132,34 @@ func findMetadataDefinitionNamesInFile(path string) ([]string, []string, error)
|
|||||||
return metadataDefinitions, usedTypeNames, nil
|
return metadataDefinitions, usedTypeNames, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractSliceOfStructType(exp ast.Expr) *ast.StructType {
|
||||||
|
var structType *ast.StructType
|
||||||
|
switch ty := exp.(type) {
|
||||||
|
case *ast.ArrayType:
|
||||||
|
// this is a standard definition:
|
||||||
|
// type FooMetadata []BarMetadata
|
||||||
|
structType = extractStructType(ty.Elt)
|
||||||
|
case *ast.Ident:
|
||||||
|
if ty.Obj == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// this might be a type created from another type:
|
||||||
|
// type FooMetadata BarMetadata
|
||||||
|
// ... but we need to check that the other type definition is a struct type
|
||||||
|
typeSpec, ok := ty.Obj.Decl.(*ast.TypeSpec)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
nestedStructType, ok := typeSpec.Type.(*ast.StructType)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
structType = nestedStructType
|
||||||
|
}
|
||||||
|
return structType
|
||||||
|
}
|
||||||
|
|
||||||
func extractStructType(exp ast.Expr) *ast.StructType {
|
func extractStructType(exp ast.Expr) *ast.StructType {
|
||||||
var structType *ast.StructType
|
var structType *ast.StructType
|
||||||
switch ty := exp.(type) {
|
switch ty := exp.(type) {
|
||||||
|
|||||||
@ -87,8 +87,8 @@ func parseConanlock(_ context.Context, _ file.Resolver, _ *generic.Environment,
|
|||||||
return pkgs, relationships, nil
|
return pkgs, relationships, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseOptions(options string) map[string]string {
|
func parseOptions(options string) []pkg.KeyValue {
|
||||||
o := make(map[string]string)
|
o := make([]pkg.KeyValue, 0)
|
||||||
if len(options) == 0 {
|
if len(options) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -97,7 +97,10 @@ func parseOptions(options string) map[string]string {
|
|||||||
for _, kvp := range kvps {
|
for _, kvp := range kvps {
|
||||||
kv := strings.Split(kvp, "=")
|
kv := strings.Split(kvp, "=")
|
||||||
if len(kv) == 2 {
|
if len(kv) == 2 {
|
||||||
o[kv[0]] = kv[1]
|
o = append(o, pkg.KeyValue{
|
||||||
|
Key: kv[0],
|
||||||
|
Value: kv[1],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,82 +21,82 @@ func TestParseConanlock(t *testing.T) {
|
|||||||
Type: pkg.ConanPkg,
|
Type: pkg.ConanPkg,
|
||||||
Metadata: pkg.ConanLockEntry{
|
Metadata: pkg.ConanLockEntry{
|
||||||
Ref: "mfast/1.2.2@my_user/my_channel#c6f6387c9b99780f0ee05e25f99d0f39",
|
Ref: "mfast/1.2.2@my_user/my_channel#c6f6387c9b99780f0ee05e25f99d0f39",
|
||||||
Options: map[string]string{
|
Options: pkg.KeyValues{
|
||||||
"fPIC": "True",
|
{Key: "fPIC", Value: "True"},
|
||||||
"shared": "False",
|
{Key: "shared", Value: "False"},
|
||||||
"with_sqlite3": "False",
|
{Key: "with_sqlite3", Value: "False"},
|
||||||
"boost:addr2line_location": "/usr/bin/addr2line",
|
{Key: "boost:addr2line_location", Value: "/usr/bin/addr2line"},
|
||||||
"boost:asio_no_deprecated": "False",
|
{Key: "boost:asio_no_deprecated", Value: "False"},
|
||||||
"boost:buildid": "None",
|
{Key: "boost:buildid", Value: "None"},
|
||||||
"boost:bzip2": "True",
|
{Key: "boost:bzip2", Value: "True"},
|
||||||
"boost:debug_level": "0",
|
{Key: "boost:debug_level", Value: "0"},
|
||||||
"boost:diagnostic_definitions": "False",
|
{Key: "boost:diagnostic_definitions", Value: "False"},
|
||||||
"boost:error_code_header_only": "False",
|
{Key: "boost:error_code_header_only", Value: "False"},
|
||||||
"boost:extra_b2_flags": "None",
|
{Key: "boost:extra_b2_flags", Value: "None"},
|
||||||
"boost:fPIC": "True",
|
{Key: "boost:fPIC", Value: "True"},
|
||||||
"boost:filesystem_no_deprecated": "False",
|
{Key: "boost:filesystem_no_deprecated", Value: "False"},
|
||||||
"boost:header_only": "False",
|
{Key: "boost:header_only", Value: "False"},
|
||||||
"boost:i18n_backend": "deprecated",
|
{Key: "boost:i18n_backend", Value: "deprecated"},
|
||||||
"boost:i18n_backend_iconv": "libc",
|
{Key: "boost:i18n_backend_iconv", Value: "libc"},
|
||||||
"boost:i18n_backend_icu": "False",
|
{Key: "boost:i18n_backend_icu", Value: "False"},
|
||||||
"boost:layout": "system",
|
{Key: "boost:layout", Value: "system"},
|
||||||
"boost:lzma": "False",
|
{Key: "boost:lzma", Value: "False"},
|
||||||
"boost:magic_autolink": "False",
|
{Key: "boost:magic_autolink", Value: "False"},
|
||||||
"boost:multithreading": "True",
|
{Key: "boost:multithreading", Value: "True"},
|
||||||
"boost:namespace": "boost",
|
{Key: "boost:namespace", Value: "boost"},
|
||||||
"boost:namespace_alias": "False",
|
{Key: "boost:namespace_alias", Value: "False"},
|
||||||
"boost:numa": "True",
|
{Key: "boost:numa", Value: "True"},
|
||||||
"boost:pch": "True",
|
{Key: "boost:pch", Value: "True"},
|
||||||
"boost:python_executable": "None",
|
{Key: "boost:python_executable", Value: "None"},
|
||||||
"boost:python_version": "None",
|
{Key: "boost:python_version", Value: "None"},
|
||||||
"boost:segmented_stacks": "False",
|
{Key: "boost:segmented_stacks", Value: "False"},
|
||||||
"boost:shared": "False",
|
{Key: "boost:shared", Value: "False"},
|
||||||
"boost:system_no_deprecated": "False",
|
{Key: "boost:system_no_deprecated", Value: "False"},
|
||||||
"boost:system_use_utf8": "False",
|
{Key: "boost:system_use_utf8", Value: "False"},
|
||||||
"boost:visibility": "hidden",
|
{Key: "boost:visibility", Value: "hidden"},
|
||||||
"boost:with_stacktrace_backtrace": "True",
|
{Key: "boost:with_stacktrace_backtrace", Value: "True"},
|
||||||
"boost:without_atomic": "False",
|
{Key: "boost:without_atomic", Value: "False"},
|
||||||
"boost:without_chrono": "False",
|
{Key: "boost:without_chrono", Value: "False"},
|
||||||
"boost:without_container": "False",
|
{Key: "boost:without_container", Value: "False"},
|
||||||
"boost:without_context": "False",
|
{Key: "boost:without_context", Value: "False"},
|
||||||
"boost:without_contract": "False",
|
{Key: "boost:without_contract", Value: "False"},
|
||||||
"boost:without_coroutine": "False",
|
{Key: "boost:without_coroutine", Value: "False"},
|
||||||
"boost:without_date_time": "False",
|
{Key: "boost:without_date_time", Value: "False"},
|
||||||
"boost:without_exception": "False",
|
{Key: "boost:without_exception", Value: "False"},
|
||||||
"boost:without_fiber": "False",
|
{Key: "boost:without_fiber", Value: "False"},
|
||||||
"boost:without_filesystem": "False",
|
{Key: "boost:without_filesystem", Value: "False"},
|
||||||
"boost:without_graph": "False",
|
{Key: "boost:without_graph", Value: "False"},
|
||||||
"boost:without_graph_parallel": "True",
|
{Key: "boost:without_graph_parallel", Value: "True"},
|
||||||
"boost:without_iostreams": "False",
|
{Key: "boost:without_iostreams", Value: "False"},
|
||||||
"boost:without_json": "False",
|
{Key: "boost:without_json", Value: "False"},
|
||||||
"boost:without_locale": "False",
|
{Key: "boost:without_locale", Value: "False"},
|
||||||
"boost:without_log": "False",
|
{Key: "boost:without_log", Value: "False"},
|
||||||
"boost:without_math": "False",
|
{Key: "boost:without_math", Value: "False"},
|
||||||
"boost:without_mpi": "True",
|
{Key: "boost:without_mpi", Value: "True"},
|
||||||
"boost:without_nowide": "False",
|
{Key: "boost:without_nowide", Value: "False"},
|
||||||
"boost:without_program_options": "False",
|
{Key: "boost:without_program_options", Value: "False"},
|
||||||
"boost:without_python": "True",
|
{Key: "boost:without_python", Value: "True"},
|
||||||
"boost:without_random": "False",
|
{Key: "boost:without_random", Value: "False"},
|
||||||
"boost:without_regex": "False",
|
{Key: "boost:without_regex", Value: "False"},
|
||||||
"boost:without_serialization": "False",
|
{Key: "boost:without_serialization", Value: "False"},
|
||||||
"boost:without_stacktrace": "False",
|
{Key: "boost:without_stacktrace", Value: "False"},
|
||||||
"boost:without_system": "False",
|
{Key: "boost:without_system", Value: "False"},
|
||||||
"boost:without_test": "False",
|
{Key: "boost:without_test", Value: "False"},
|
||||||
"boost:without_thread": "False",
|
{Key: "boost:without_thread", Value: "False"},
|
||||||
"boost:without_timer": "False",
|
{Key: "boost:without_timer", Value: "False"},
|
||||||
"boost:without_type_erasure": "False",
|
{Key: "boost:without_type_erasure", Value: "False"},
|
||||||
"boost:without_wave": "False",
|
{Key: "boost:without_wave", Value: "False"},
|
||||||
"boost:zlib": "True",
|
{Key: "boost:zlib", Value: "True"},
|
||||||
"boost:zstd": "False",
|
{Key: "boost:zstd", Value: "False"},
|
||||||
"bzip2:build_executable": "True",
|
{Key: "bzip2:build_executable", Value: "True"},
|
||||||
"bzip2:fPIC": "True",
|
{Key: "bzip2:fPIC", Value: "True"},
|
||||||
"bzip2:shared": "False",
|
{Key: "bzip2:shared", Value: "False"},
|
||||||
"libbacktrace:fPIC": "True",
|
{Key: "libbacktrace:fPIC", Value: "True"},
|
||||||
"libbacktrace:shared": "False",
|
{Key: "libbacktrace:shared", Value: "False"},
|
||||||
"tinyxml2:fPIC": "True",
|
{Key: "tinyxml2:fPIC", Value: "True"},
|
||||||
"tinyxml2:shared": "False",
|
{Key: "tinyxml2:shared", Value: "False"},
|
||||||
"zlib:fPIC": "True",
|
{Key: "zlib:fPIC", Value: "True"},
|
||||||
"zlib:shared": "False",
|
{Key: "zlib:shared", Value: "False"},
|
||||||
},
|
},
|
||||||
Context: "host",
|
Context: "host",
|
||||||
PackageID: "9d1f076b471417647c2022a78d5e2c1f834289ac",
|
PackageID: "9d1f076b471417647c2022a78d5e2c1f834289ac",
|
||||||
@ -112,77 +112,77 @@ func TestParseConanlock(t *testing.T) {
|
|||||||
Type: pkg.ConanPkg,
|
Type: pkg.ConanPkg,
|
||||||
Metadata: pkg.ConanLockEntry{
|
Metadata: pkg.ConanLockEntry{
|
||||||
Ref: "boost/1.75.0#a9c318f067216f900900e044e7af4ab1",
|
Ref: "boost/1.75.0#a9c318f067216f900900e044e7af4ab1",
|
||||||
Options: map[string]string{
|
Options: pkg.KeyValues{
|
||||||
"addr2line_location": "/usr/bin/addr2line",
|
{Key: "addr2line_location", Value: "/usr/bin/addr2line"},
|
||||||
"asio_no_deprecated": "False",
|
{Key: "asio_no_deprecated", Value: "False"},
|
||||||
"buildid": "None",
|
{Key: "buildid", Value: "None"},
|
||||||
"bzip2": "True",
|
{Key: "bzip2", Value: "True"},
|
||||||
"debug_level": "0",
|
{Key: "debug_level", Value: "0"},
|
||||||
"diagnostic_definitions": "False",
|
{Key: "diagnostic_definitions", Value: "False"},
|
||||||
"error_code_header_only": "False",
|
{Key: "error_code_header_only", Value: "False"},
|
||||||
"extra_b2_flags": "None",
|
{Key: "extra_b2_flags", Value: "None"},
|
||||||
"fPIC": "True",
|
{Key: "fPIC", Value: "True"},
|
||||||
"filesystem_no_deprecated": "False",
|
{Key: "filesystem_no_deprecated", Value: "False"},
|
||||||
"header_only": "False",
|
{Key: "header_only", Value: "False"},
|
||||||
"i18n_backend": "deprecated",
|
{Key: "i18n_backend", Value: "deprecated"},
|
||||||
"i18n_backend_iconv": "libc",
|
{Key: "i18n_backend_iconv", Value: "libc"},
|
||||||
"i18n_backend_icu": "False",
|
{Key: "i18n_backend_icu", Value: "False"},
|
||||||
"layout": "system",
|
{Key: "layout", Value: "system"},
|
||||||
"lzma": "False",
|
{Key: "lzma", Value: "False"},
|
||||||
"magic_autolink": "False",
|
{Key: "magic_autolink", Value: "False"},
|
||||||
"multithreading": "True",
|
{Key: "multithreading", Value: "True"},
|
||||||
"namespace": "boost",
|
{Key: "namespace", Value: "boost"},
|
||||||
"namespace_alias": "False",
|
{Key: "namespace_alias", Value: "False"},
|
||||||
"numa": "True",
|
{Key: "numa", Value: "True"},
|
||||||
"pch": "True",
|
{Key: "pch", Value: "True"},
|
||||||
"python_executable": "None",
|
{Key: "python_executable", Value: "None"},
|
||||||
"python_version": "None",
|
{Key: "python_version", Value: "None"},
|
||||||
"segmented_stacks": "False",
|
{Key: "segmented_stacks", Value: "False"},
|
||||||
"shared": "False",
|
{Key: "shared", Value: "False"},
|
||||||
"system_no_deprecated": "False",
|
{Key: "system_no_deprecated", Value: "False"},
|
||||||
"system_use_utf8": "False",
|
{Key: "system_use_utf8", Value: "False"},
|
||||||
"visibility": "hidden",
|
{Key: "visibility", Value: "hidden"},
|
||||||
"with_stacktrace_backtrace": "True",
|
{Key: "with_stacktrace_backtrace", Value: "True"},
|
||||||
"without_atomic": "False",
|
{Key: "without_atomic", Value: "False"},
|
||||||
"without_chrono": "False",
|
{Key: "without_chrono", Value: "False"},
|
||||||
"without_container": "False",
|
{Key: "without_container", Value: "False"},
|
||||||
"without_context": "False",
|
{Key: "without_context", Value: "False"},
|
||||||
"without_contract": "False",
|
{Key: "without_contract", Value: "False"},
|
||||||
"without_coroutine": "False",
|
{Key: "without_coroutine", Value: "False"},
|
||||||
"without_date_time": "False",
|
{Key: "without_date_time", Value: "False"},
|
||||||
"without_exception": "False",
|
{Key: "without_exception", Value: "False"},
|
||||||
"without_fiber": "False",
|
{Key: "without_fiber", Value: "False"},
|
||||||
"without_filesystem": "False",
|
{Key: "without_filesystem", Value: "False"},
|
||||||
"without_graph": "False",
|
{Key: "without_graph", Value: "False"},
|
||||||
"without_graph_parallel": "True",
|
{Key: "without_graph_parallel", Value: "True"},
|
||||||
"without_iostreams": "False",
|
{Key: "without_iostreams", Value: "False"},
|
||||||
"without_json": "False",
|
{Key: "without_json", Value: "False"},
|
||||||
"without_locale": "False",
|
{Key: "without_locale", Value: "False"},
|
||||||
"without_log": "False",
|
{Key: "without_log", Value: "False"},
|
||||||
"without_math": "False",
|
{Key: "without_math", Value: "False"},
|
||||||
"without_mpi": "True",
|
{Key: "without_mpi", Value: "True"},
|
||||||
"without_nowide": "False",
|
{Key: "without_nowide", Value: "False"},
|
||||||
"without_program_options": "False",
|
{Key: "without_program_options", Value: "False"},
|
||||||
"without_python": "True",
|
{Key: "without_python", Value: "True"},
|
||||||
"without_random": "False",
|
{Key: "without_random", Value: "False"},
|
||||||
"without_regex": "False",
|
{Key: "without_regex", Value: "False"},
|
||||||
"without_serialization": "False",
|
{Key: "without_serialization", Value: "False"},
|
||||||
"without_stacktrace": "False",
|
{Key: "without_stacktrace", Value: "False"},
|
||||||
"without_system": "False",
|
{Key: "without_system", Value: "False"},
|
||||||
"without_test": "False",
|
{Key: "without_test", Value: "False"},
|
||||||
"without_thread": "False",
|
{Key: "without_thread", Value: "False"},
|
||||||
"without_timer": "False",
|
{Key: "without_timer", Value: "False"},
|
||||||
"without_type_erasure": "False",
|
{Key: "without_type_erasure", Value: "False"},
|
||||||
"without_wave": "False",
|
{Key: "without_wave", Value: "False"},
|
||||||
"zlib": "True",
|
{Key: "zlib", Value: "True"},
|
||||||
"zstd": "False",
|
{Key: "zstd", Value: "False"},
|
||||||
"bzip2:build_executable": "True",
|
{Key: "bzip2:build_executable", Value: "True"},
|
||||||
"bzip2:fPIC": "True",
|
{Key: "bzip2:fPIC", Value: "True"},
|
||||||
"bzip2:shared": "False",
|
{Key: "bzip2:shared", Value: "False"},
|
||||||
"libbacktrace:fPIC": "True",
|
{Key: "libbacktrace:fPIC", Value: "True"},
|
||||||
"libbacktrace:shared": "False",
|
{Key: "libbacktrace:shared", Value: "False"},
|
||||||
"zlib:fPIC": "True",
|
{Key: "zlib:fPIC", Value: "True"},
|
||||||
"zlib:shared": "False",
|
{Key: "zlib:shared", Value: "False"},
|
||||||
},
|
},
|
||||||
Context: "host",
|
Context: "host",
|
||||||
PackageID: "dc8aedd23a0f0a773a5fcdcfe1ae3e89c4205978",
|
PackageID: "dc8aedd23a0f0a773a5fcdcfe1ae3e89c4205978",
|
||||||
@ -198,9 +198,15 @@ func TestParseConanlock(t *testing.T) {
|
|||||||
Type: pkg.ConanPkg,
|
Type: pkg.ConanPkg,
|
||||||
Metadata: pkg.ConanLockEntry{
|
Metadata: pkg.ConanLockEntry{
|
||||||
Ref: "zlib/1.2.12#c67ce17f2e96b972d42393ce50a76a1a",
|
Ref: "zlib/1.2.12#c67ce17f2e96b972d42393ce50a76a1a",
|
||||||
Options: map[string]string{
|
Options: pkg.KeyValues{
|
||||||
"fPIC": "True",
|
{
|
||||||
"shared": "False",
|
Key: "fPIC",
|
||||||
|
Value: "True",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "shared",
|
||||||
|
Value: "False",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Context: "host",
|
Context: "host",
|
||||||
PackageID: "dfbe50feef7f3c6223a476cd5aeadb687084a646",
|
PackageID: "dfbe50feef7f3c6223a476cd5aeadb687084a646",
|
||||||
@ -216,10 +222,19 @@ func TestParseConanlock(t *testing.T) {
|
|||||||
Type: pkg.ConanPkg,
|
Type: pkg.ConanPkg,
|
||||||
Metadata: pkg.ConanLockEntry{
|
Metadata: pkg.ConanLockEntry{
|
||||||
Ref: "bzip2/1.0.8#62a8031289639043797cf53fa876d0ef",
|
Ref: "bzip2/1.0.8#62a8031289639043797cf53fa876d0ef",
|
||||||
Options: map[string]string{
|
Options: []pkg.KeyValue{
|
||||||
"build_executable": "True",
|
{
|
||||||
"fPIC": "True",
|
Key: "build_executable",
|
||||||
"shared": "False",
|
Value: "True",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "fPIC",
|
||||||
|
Value: "True",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "shared",
|
||||||
|
Value: "False",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Context: "host",
|
Context: "host",
|
||||||
PackageID: "c32092bf4d4bb47cf962af898e02823f499b017e",
|
PackageID: "c32092bf4d4bb47cf962af898e02823f499b017e",
|
||||||
@ -235,9 +250,15 @@ func TestParseConanlock(t *testing.T) {
|
|||||||
Type: pkg.ConanPkg,
|
Type: pkg.ConanPkg,
|
||||||
Metadata: pkg.ConanLockEntry{
|
Metadata: pkg.ConanLockEntry{
|
||||||
Ref: "libbacktrace/cci.20210118#76e40b760e0bcd602d46db56b22820ab",
|
Ref: "libbacktrace/cci.20210118#76e40b760e0bcd602d46db56b22820ab",
|
||||||
Options: map[string]string{
|
Options: []pkg.KeyValue{
|
||||||
"fPIC": "True",
|
{
|
||||||
"shared": "False",
|
Key: "fPIC",
|
||||||
|
Value: "True",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "shared",
|
||||||
|
Value: "False",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Context: "host",
|
Context: "host",
|
||||||
PackageID: "dfbe50feef7f3c6223a476cd5aeadb687084a646",
|
PackageID: "dfbe50feef7f3c6223a476cd5aeadb687084a646",
|
||||||
@ -253,9 +274,15 @@ func TestParseConanlock(t *testing.T) {
|
|||||||
Type: pkg.ConanPkg,
|
Type: pkg.ConanPkg,
|
||||||
Metadata: pkg.ConanLockEntry{
|
Metadata: pkg.ConanLockEntry{
|
||||||
Ref: "tinyxml2/9.0.0#9f13a36ebfc222cd55fe531a0a8d94d1",
|
Ref: "tinyxml2/9.0.0#9f13a36ebfc222cd55fe531a0a8d94d1",
|
||||||
Options: map[string]string{
|
Options: []pkg.KeyValue{
|
||||||
"fPIC": "True",
|
{
|
||||||
"shared": "False",
|
Key: "fPIC",
|
||||||
|
Value: "True",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "shared",
|
||||||
|
Value: "False",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Context: "host",
|
Context: "host",
|
||||||
// intentionally remove to test missing PackageID and Prev
|
// intentionally remove to test missing PackageID and Prev
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *goBinaryCataloger) newGoBinaryPackage(resolver file.Resolver, dep *debug.Module, mainModule, goVersion, architecture string, buildSettings map[string]string, cryptoSettings []string, locations ...file.Location) pkg.Package {
|
func (c *goBinaryCataloger) newGoBinaryPackage(resolver file.Resolver, dep *debug.Module, mainModule, goVersion, architecture string, buildSettings pkg.KeyValues, cryptoSettings []string, locations ...file.Location) pkg.Package {
|
||||||
if dep.Replace != nil {
|
if dep.Replace != nil {
|
||||||
dep = dep.Replace
|
dep = dep.Replace
|
||||||
}
|
}
|
||||||
|
|||||||
@ -84,8 +84,8 @@ func (c *goBinaryCataloger) makeGoMainPackage(resolver file.Resolver, mod *exten
|
|||||||
return main
|
return main
|
||||||
}
|
}
|
||||||
|
|
||||||
version, hasVersion := gbs["vcs.revision"]
|
version, hasVersion := gbs.Get("vcs.revision")
|
||||||
timestamp, hasTimestamp := gbs["vcs.time"]
|
timestamp, hasTimestamp := gbs.Get("vcs.time")
|
||||||
|
|
||||||
var ldflags string
|
var ldflags string
|
||||||
if metadata, ok := main.Metadata.(pkg.GolangBinaryBuildinfoEntry); ok {
|
if metadata, ok := main.Metadata.(pkg.GolangBinaryBuildinfoEntry); ok {
|
||||||
@ -95,7 +95,7 @@ func (c *goBinaryCataloger) makeGoMainPackage(resolver file.Resolver, mod *exten
|
|||||||
// there is a matching vcs tag to match that could be referenced. This assumption could
|
// there is a matching vcs tag to match that could be referenced. This assumption could
|
||||||
// be incorrect in terms of the go.mod contents, but is not incorrect in terms of the logical
|
// be incorrect in terms of the go.mod contents, but is not incorrect in terms of the logical
|
||||||
// version of the package.
|
// version of the package.
|
||||||
ldflags = metadata.BuildSettings["-ldflags"]
|
ldflags, _ = metadata.BuildSettings.Get("-ldflags")
|
||||||
}
|
}
|
||||||
|
|
||||||
majorVersion, fullVersion := extractVersionFromLDFlags(ldflags)
|
majorVersion, fullVersion := extractVersionFromLDFlags(ldflags)
|
||||||
@ -207,10 +207,13 @@ func getGOARCHFromBin(r io.ReaderAt) (string, error) {
|
|||||||
return arch, nil
|
return arch, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBuildSettings(settings []debug.BuildSetting) map[string]string {
|
func getBuildSettings(settings []debug.BuildSetting) pkg.KeyValues {
|
||||||
m := make(map[string]string)
|
m := make(pkg.KeyValues, 0)
|
||||||
for _, s := range settings {
|
for _, s := range settings {
|
||||||
m[s.Key] = s.Value
|
m = append(m, pkg.KeyValue{
|
||||||
|
Key: s.Key,
|
||||||
|
Value: s.Value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|||||||
@ -124,10 +124,20 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
goCompiledVersion = "1.18"
|
goCompiledVersion = "1.18"
|
||||||
archDetails = "amd64"
|
archDetails = "amd64"
|
||||||
)
|
)
|
||||||
defaultBuildSettings := map[string]string{
|
|
||||||
"GOARCH": "amd64",
|
defaultBuildSettings := []pkg.KeyValue{
|
||||||
"GOOS": "darwin",
|
{
|
||||||
"GOAMD64": "v1",
|
Key: "GOARCH",
|
||||||
|
Value: "amd64",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "GOOS",
|
||||||
|
Value: "darwin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "GOAMD64",
|
||||||
|
Value: "v1",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
unmodifiedMain := pkg.Package{
|
unmodifiedMain := pkg.Package{
|
||||||
@ -275,10 +285,19 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
H1Digest: "",
|
H1Digest: "",
|
||||||
BuildSettings: map[string]string{
|
BuildSettings: []pkg.KeyValue{
|
||||||
"GOAMD64": "v1",
|
{
|
||||||
"GOARCH": "amd64",
|
Key: "GOARCH",
|
||||||
"GOOS": "darwin",
|
Value: archDetails,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "GOOS",
|
||||||
|
Value: "darwin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "GOAMD64",
|
||||||
|
Value: "v1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
MainModule: "github.com/a/b/c",
|
MainModule: "github.com/a/b/c",
|
||||||
GoCryptoSettings: []string{"boringcrypto + fips"},
|
GoCryptoSettings: []string{"boringcrypto + fips"},
|
||||||
@ -339,13 +358,31 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
BuildSettings: map[string]string{
|
BuildSettings: []pkg.KeyValue{
|
||||||
"GOARCH": archDetails,
|
{
|
||||||
"GOOS": "darwin",
|
Key: "GOARCH",
|
||||||
"GOAMD64": "v1",
|
Value: archDetails,
|
||||||
"vcs.revision": "41bc6bb410352845f22766e27dd48ba93aa825a4",
|
},
|
||||||
"vcs.time": "2022-10-14T19:54:57Z",
|
{
|
||||||
"-ldflags": `build -ldflags="-w -s -extldflags '-static' -X blah=foobar`,
|
Key: "GOOS",
|
||||||
|
Value: "darwin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "GOAMD64",
|
||||||
|
Value: "v1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "vcs.revision",
|
||||||
|
Value: "41bc6bb410352845f22766e27dd48ba93aa825a4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "vcs.time",
|
||||||
|
Value: "2022-10-14T19:54:57Z",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "-ldflags",
|
||||||
|
Value: `build -ldflags="-w -s -extldflags '-static' -X blah=foobar`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
MainModule: "github.com/anchore/syft",
|
MainModule: "github.com/anchore/syft",
|
||||||
},
|
},
|
||||||
@ -388,13 +425,31 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
BuildSettings: map[string]string{
|
BuildSettings: []pkg.KeyValue{
|
||||||
"GOARCH": archDetails,
|
{
|
||||||
"GOOS": "darwin",
|
Key: "GOARCH",
|
||||||
"GOAMD64": "v1",
|
Value: archDetails,
|
||||||
"vcs.revision": "41bc6bb410352845f22766e27dd48ba93aa825a4",
|
},
|
||||||
"vcs.time": "2022-10-14T19:54:57Z",
|
{
|
||||||
"-ldflags": `build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`,
|
Key: "GOOS",
|
||||||
|
Value: "darwin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "GOAMD64",
|
||||||
|
Value: "v1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "vcs.revision",
|
||||||
|
Value: "41bc6bb410352845f22766e27dd48ba93aa825a4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "vcs.time",
|
||||||
|
Value: "2022-10-14T19:54:57Z",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "-ldflags",
|
||||||
|
Value: `build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
MainModule: "github.com/anchore/syft",
|
MainModule: "github.com/anchore/syft",
|
||||||
},
|
},
|
||||||
@ -435,11 +490,23 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
BuildSettings: map[string]string{
|
BuildSettings: []pkg.KeyValue{
|
||||||
"GOARCH": archDetails,
|
{
|
||||||
"GOOS": "darwin",
|
Key: "GOARCH",
|
||||||
"GOAMD64": "v1",
|
Value: archDetails,
|
||||||
"-ldflags": `build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`,
|
},
|
||||||
|
{
|
||||||
|
Key: "GOOS",
|
||||||
|
Value: "darwin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "GOAMD64",
|
||||||
|
Value: "v1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "-ldflags",
|
||||||
|
Value: `build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
MainModule: "github.com/anchore/syft",
|
MainModule: "github.com/anchore/syft",
|
||||||
},
|
},
|
||||||
@ -480,11 +547,23 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
BuildSettings: map[string]string{
|
BuildSettings: []pkg.KeyValue{
|
||||||
"GOARCH": archDetails,
|
{
|
||||||
"GOOS": "darwin",
|
Key: "GOARCH",
|
||||||
"GOAMD64": "v1",
|
Value: archDetails,
|
||||||
"-ldflags": `build -ldflags="-w -s -extldflags '-static' -X main.version=0.79.0`,
|
},
|
||||||
|
{
|
||||||
|
Key: "GOOS",
|
||||||
|
Value: "darwin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "GOAMD64",
|
||||||
|
Value: "v1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "-ldflags",
|
||||||
|
Value: `build -ldflags="-w -s -extldflags '-static' -X main.version=0.79.0`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
MainModule: "github.com/anchore/syft",
|
MainModule: "github.com/anchore/syft",
|
||||||
},
|
},
|
||||||
@ -525,11 +604,23 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
BuildSettings: map[string]string{
|
BuildSettings: []pkg.KeyValue{
|
||||||
"GOARCH": archDetails,
|
{
|
||||||
"GOOS": "darwin",
|
Key: "GOARCH",
|
||||||
"GOAMD64": "v1",
|
Value: archDetails,
|
||||||
"-ldflags": `build -ldflags="-w -s -extldflags '-static' -X main.Version=0.79.0`,
|
},
|
||||||
|
{
|
||||||
|
Key: "GOOS",
|
||||||
|
Value: "darwin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "GOAMD64",
|
||||||
|
Value: "v1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "-ldflags",
|
||||||
|
Value: `build -ldflags="-w -s -extldflags '-static' -X main.Version=0.79.0`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
MainModule: "github.com/anchore/syft",
|
MainModule: "github.com/anchore/syft",
|
||||||
},
|
},
|
||||||
@ -571,12 +662,27 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
BuildSettings: map[string]string{
|
BuildSettings: []pkg.KeyValue{
|
||||||
"GOARCH": archDetails,
|
{
|
||||||
"GOOS": "darwin",
|
Key: "GOARCH",
|
||||||
"GOAMD64": "v1",
|
Value: archDetails,
|
||||||
"vcs.revision": "41bc6bb410352845f22766e27dd48ba93aa825a4",
|
},
|
||||||
"vcs.time": "2022-10-14T19:54:57Z",
|
{
|
||||||
|
Key: "GOOS",
|
||||||
|
Value: "darwin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "GOAMD64",
|
||||||
|
Value: "v1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "vcs.revision",
|
||||||
|
Value: "41bc6bb410352845f22766e27dd48ba93aa825a4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "vcs.time",
|
||||||
|
Value: "2022-10-14T19:54:57Z",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
MainModule: "github.com/anchore/syft",
|
MainModule: "github.com/anchore/syft",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -13,6 +13,17 @@ import (
|
|||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func keyValues(m map[string]string) []pkg.KeyValue {
|
||||||
|
var kvs []pkg.KeyValue
|
||||||
|
for k, v := range m {
|
||||||
|
kvs = append(kvs, pkg.KeyValue{
|
||||||
|
Key: k,
|
||||||
|
Value: v,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return kvs
|
||||||
|
}
|
||||||
|
|
||||||
func TestGeneratePackageCPEs(t *testing.T) {
|
func TestGeneratePackageCPEs(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@ -201,7 +212,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
|||||||
Type: pkg.JavaPkg,
|
Type: pkg.JavaPkg,
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: keyValues(map[string]string{
|
||||||
"Ant-Version": "Apache Ant 1.6.5",
|
"Ant-Version": "Apache Ant 1.6.5",
|
||||||
"Built-By": "tatu",
|
"Built-By": "tatu",
|
||||||
"Created-By": "1.4.2_03-b02 (Sun Microsystems Inc.)",
|
"Created-By": "1.4.2_03-b02 (Sun Microsystems Inc.)",
|
||||||
@ -212,7 +223,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
|||||||
"Specification-Title": "StAX 1.0 API",
|
"Specification-Title": "StAX 1.0 API",
|
||||||
"Specification-Vendor": "http://jcp.org/en/jsr/detail?id=173",
|
"Specification-Vendor": "http://jcp.org/en/jsr/detail?id=173",
|
||||||
"Specification-Version": "1.0",
|
"Specification-Version": "1.0",
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -253,7 +264,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
|||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
VirtualPath: "/opt/jboss/keycloak/modules/system/layers/base/org/apache/cxf/impl/main/cxf-rt-bindings-xml-3.3.10.jar",
|
VirtualPath: "/opt/jboss/keycloak/modules/system/layers/base/org/apache/cxf/impl/main/cxf-rt-bindings-xml-3.3.10.jar",
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: keyValues(map[string]string{
|
||||||
"Automatic-Module-Name": "org.apache.cxf.binding.xml",
|
"Automatic-Module-Name": "org.apache.cxf.binding.xml",
|
||||||
"Bnd-LastModified": "1615836524860",
|
"Bnd-LastModified": "1615836524860",
|
||||||
"Build-Jdk": "1.8.0_261",
|
"Build-Jdk": "1.8.0_261",
|
||||||
@ -278,7 +289,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
|||||||
"Specification-Vendor": "The Apache Software Foundation",
|
"Specification-Vendor": "The Apache Software Foundation",
|
||||||
"Specification-Version": "3.3.10",
|
"Specification-Version": "3.3.10",
|
||||||
"Tool": "Bnd-4.2.0.201903051501",
|
"Tool": "Bnd-4.2.0.201903051501",
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
PomProperties: &pkg.JavaPomProperties{
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
Path: "META-INF/maven/org.apache.cxf/cxf-rt-bindings-xml/pom.properties",
|
Path: "META-INF/maven/org.apache.cxf/cxf-rt-bindings-xml/pom.properties",
|
||||||
@ -558,7 +569,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
|||||||
FoundBy: "java-cataloger",
|
FoundBy: "java-cataloger",
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: keyValues(map[string]string{
|
||||||
"Extension-Name": "handlebars",
|
"Extension-Name": "handlebars",
|
||||||
"Group-Id": "org.jenkins-ci.ui",
|
"Group-Id": "org.jenkins-ci.ui",
|
||||||
"Hudson-Version": "2.204",
|
"Hudson-Version": "2.204",
|
||||||
@ -566,7 +577,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
|||||||
"Implementation-Version": "3.0.8",
|
"Implementation-Version": "3.0.8",
|
||||||
"Plugin-Version": "3.0.8",
|
"Plugin-Version": "3.0.8",
|
||||||
"Short-Name": "handlebars",
|
"Short-Name": "handlebars",
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
PomProperties: &pkg.JavaPomProperties{
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
GroupID: "org.jenkins-ci.ui",
|
GroupID: "org.jenkins-ci.ui",
|
||||||
@ -594,10 +605,10 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
|||||||
Language: pkg.Java,
|
Language: pkg.Java,
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: keyValues(map[string]string{
|
||||||
"Extension-Name": "active-directory",
|
"Extension-Name": "active-directory",
|
||||||
"Group-Id": "org.jenkins-ci.plugins",
|
"Group-Id": "org.jenkins-ci.plugins",
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
PomProperties: &pkg.JavaPomProperties{
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
GroupID: "org.jenkins-ci.plugins",
|
GroupID: "org.jenkins-ci.plugins",
|
||||||
|
|||||||
@ -66,7 +66,7 @@ func vendorsFromJavaManifestNames(p pkg.Package) fieldCandidateSet {
|
|||||||
|
|
||||||
for _, name := range javaManifestNameFields {
|
for _, name := range javaManifestNameFields {
|
||||||
if metadata.Manifest.Main != nil {
|
if metadata.Manifest.Main != nil {
|
||||||
if value, exists := metadata.Manifest.Main[name]; exists {
|
if value, exists := metadata.Manifest.Main.Get(name); exists {
|
||||||
if !startsWithTopLevelDomain(value) {
|
if !startsWithTopLevelDomain(value) {
|
||||||
vendors.add(fieldCandidate{
|
vendors.add(fieldCandidate{
|
||||||
value: normalizePersonName(value),
|
value: normalizePersonName(value),
|
||||||
@ -75,12 +75,12 @@ func vendorsFromJavaManifestNames(p pkg.Package) fieldCandidateSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if metadata.Manifest.NamedSections != nil {
|
if metadata.Manifest.Sections != nil {
|
||||||
for _, section := range metadata.Manifest.NamedSections {
|
for _, section := range metadata.Manifest.Sections {
|
||||||
if section == nil {
|
if section == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if value, exists := section[name]; exists {
|
if value, exists := section.Get(name); exists {
|
||||||
if !startsWithTopLevelDomain(value) {
|
if !startsWithTopLevelDomain(value) {
|
||||||
vendors.add(fieldCandidate{
|
vendors.add(fieldCandidate{
|
||||||
value: normalizePersonName(value),
|
value: normalizePersonName(value),
|
||||||
@ -275,13 +275,13 @@ func GetManifestFieldGroupIDs(manifest *pkg.JavaManifest, fields []string) (grou
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range fields {
|
for _, name := range fields {
|
||||||
if value, exists := manifest.Main[name]; exists {
|
if value, exists := manifest.Main.Get(name); exists {
|
||||||
if startsWithTopLevelDomain(value) {
|
if startsWithTopLevelDomain(value) {
|
||||||
groupIDs = append(groupIDs, cleanGroupID(value))
|
groupIDs = append(groupIDs, cleanGroupID(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, section := range manifest.NamedSections {
|
for _, section := range manifest.Sections {
|
||||||
if value, exists := section[name]; exists {
|
if value, exists := section.Get(name); exists {
|
||||||
if startsWithTopLevelDomain(value) {
|
if startsWithTopLevelDomain(value) {
|
||||||
groupIDs = append(groupIDs, cleanGroupID(value))
|
groupIDs = append(groupIDs, cleanGroupID(value))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -188,8 +188,11 @@ func Test_groupIDsFromJavaPackage(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Extension-Name": "io.jenkins-ci.plugin.thing",
|
{
|
||||||
|
Key: "Extension-Name",
|
||||||
|
Value: "io.jenkins-ci.plugin.thing",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -201,9 +204,16 @@ func Test_groupIDsFromJavaPackage(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
NamedSections: map[string]map[string]string{
|
Sections: []pkg.KeyValues{
|
||||||
"section": {
|
{
|
||||||
"Extension-Name": "io.jenkins-ci.plugin.thing",
|
{
|
||||||
|
Key: "Name",
|
||||||
|
Value: "section",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Extension-Name",
|
||||||
|
Value: "io.jenkins-ci.plugin.thing",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -216,20 +226,20 @@ func Test_groupIDsFromJavaPackage(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
// positive cases
|
// positive cases
|
||||||
// tier 1
|
// tier 1
|
||||||
"Extension-Name": "io.jenkins-ci.plugin.1",
|
{Key: "Extension-Name", Value: "io.jenkins-ci.plugin.1"},
|
||||||
"Specification-Vendor": "io.jenkins-ci.plugin.2",
|
{Key: "Specification-Vendor", Value: "io.jenkins-ci.plugin.2"},
|
||||||
"Implementation-Vendor": "io.jenkins-ci.plugin.3",
|
{Key: "Implementation-Vendor", Value: "io.jenkins-ci.plugin.3"},
|
||||||
"Bundle-SymbolicName": "io.jenkins-ci.plugin.4",
|
{Key: "Bundle-SymbolicName", Value: "io.jenkins-ci.plugin.4"},
|
||||||
"Implementation-Vendor-Id": "io.jenkins-ci.plugin.5",
|
{Key: "Implementation-Vendor-Id", Value: "io.jenkins-ci.plugin.5"},
|
||||||
"Implementation-Title": "io.jenkins-ci.plugin.6",
|
{Key: "Implementation-Title", Value: "io.jenkins-ci.plugin.6"},
|
||||||
"Bundle-Activator": "io.jenkins-ci.plugin.7",
|
{Key: "Bundle-Activator", Value: "io.jenkins-ci.plugin.7"},
|
||||||
// tier 2
|
// tier 2
|
||||||
"Automatic-Module-Name": "io.jenkins-ci.plugin.8",
|
{Key: "Automatic-Module-Name", Value: "io.jenkins-ci.plugin.8"},
|
||||||
"Main-Class": "io.jenkins-ci.plugin.9",
|
{Key: "Main-Class", Value: "io.jenkins-ci.plugin.9"},
|
||||||
"Package": "io.jenkins-ci.plugin.10",
|
{Key: "Package", Value: "io.jenkins-ci.plugin.10"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -249,11 +259,11 @@ func Test_groupIDsFromJavaPackage(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
// positive cases
|
// positive cases
|
||||||
"Automatic-Module-Name": "io.jenkins-ci.plugin.8",
|
{Key: "Automatic-Module-Name", Value: "io.jenkins-ci.plugin.8"},
|
||||||
"Main-Class": "io.jenkins-ci.plugin.9",
|
{Key: "Main-Class", Value: "io.jenkins-ci.plugin.9"},
|
||||||
"Package": "io.jenkins-ci.plugin.10",
|
{Key: "Package", Value: "io.jenkins-ci.plugin.10"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -269,10 +279,10 @@ func Test_groupIDsFromJavaPackage(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
// negative cases
|
// negative cases
|
||||||
"Extension-Name": "not.a-group.id",
|
{Key: "Extension-Name", Value: "not.a-group.id"},
|
||||||
"bogus": "io.jenkins-ci.plugin.please-dont-find-me",
|
{Key: "bogus", Value: "io.jenkins-ci.plugin.please-dont-find-me"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -284,21 +294,55 @@ func Test_groupIDsFromJavaPackage(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
NamedSections: map[string]map[string]string{
|
Sections: []pkg.KeyValues{
|
||||||
"section": {
|
{
|
||||||
|
{
|
||||||
|
Key: "Name",
|
||||||
|
Value: "section",
|
||||||
|
},
|
||||||
// positive cases
|
// positive cases
|
||||||
// tier 1
|
// tier 1
|
||||||
"Extension-Name": "io.jenkins-ci.plugin.1",
|
{
|
||||||
"Specification-Vendor": "io.jenkins-ci.plugin.2",
|
Key: "Extension-Name",
|
||||||
"Implementation-Vendor": "io.jenkins-ci.plugin.3",
|
Value: "io.jenkins-ci.plugin.1",
|
||||||
"Bundle-SymbolicName": "io.jenkins-ci.plugin.4",
|
},
|
||||||
"Implementation-Vendor-Id": "io.jenkins-ci.plugin.5",
|
{
|
||||||
"Implementation-Title": "io.jenkins-ci.plugin.6",
|
Key: "Specification-Vendor",
|
||||||
"Bundle-Activator": "io.jenkins-ci.plugin.7",
|
Value: "io.jenkins-ci.plugin.2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Implementation-Vendor",
|
||||||
|
Value: "io.jenkins-ci.plugin.3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Bundle-SymbolicName",
|
||||||
|
Value: "io.jenkins-ci.plugin.4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Implementation-Vendor-Id",
|
||||||
|
Value: "io.jenkins-ci.plugin.5",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Implementation-Title",
|
||||||
|
Value: "io.jenkins-ci.plugin.6",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Bundle-Activator",
|
||||||
|
Value: "io.jenkins-ci.plugin.7",
|
||||||
|
},
|
||||||
// tier 2
|
// tier 2
|
||||||
"Automatic-Module-Name": "io.jenkins-ci.plugin.8",
|
{
|
||||||
"Main-Class": "io.jenkins-ci.plugin.9",
|
Key: "Automatic-Module-Name",
|
||||||
"Package": "io.jenkins-ci.plugin.10",
|
Value: "io.jenkins-ci.plugin.8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Main-Class",
|
||||||
|
Value: "io.jenkins-ci.plugin.9",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Package",
|
||||||
|
Value: "io.jenkins-ci.plugin.10",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -319,11 +363,20 @@ func Test_groupIDsFromJavaPackage(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
NamedSections: map[string]map[string]string{
|
Sections: []pkg.KeyValues{
|
||||||
"section": {
|
{
|
||||||
// negative cases
|
{
|
||||||
"Extension-Name": "not.a-group.id",
|
Key: "Name",
|
||||||
"bogus": "io.jenkins-ci.plugin.please-dont-find-me",
|
Value: "section",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Extension-Name",
|
||||||
|
Value: "not.a-group.id",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "bogus",
|
||||||
|
Value: "io.jenkins-ci.plugin.please-dont-find-me",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -403,11 +456,21 @@ func Test_vendorsFromJavaManifestNames(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
NamedSections: map[string]map[string]string{
|
Sections: []pkg.KeyValues{
|
||||||
"section": {
|
{
|
||||||
|
{
|
||||||
|
Key: "Name",
|
||||||
|
Value: "section",
|
||||||
|
},
|
||||||
// positive cases
|
// positive cases
|
||||||
"Specification-Vendor": "Alex Goodman",
|
{
|
||||||
"Implementation-Vendor": "William Goodman",
|
Key: "Specification-Vendor",
|
||||||
|
Value: "Alex Goodman",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Implementation-Vendor",
|
||||||
|
Value: "William Goodman",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -420,11 +483,22 @@ func Test_vendorsFromJavaManifestNames(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
NamedSections: map[string]map[string]string{
|
Sections: []pkg.KeyValues{
|
||||||
"section": {
|
{
|
||||||
|
{
|
||||||
|
Key: "Name",
|
||||||
|
Value: "section",
|
||||||
|
},
|
||||||
// negative cases
|
// negative cases
|
||||||
"Specification-Vendor": "io.jenkins-ci.plugin.thing",
|
|
||||||
"Implementation-Vendor-ID": "William Goodman",
|
{
|
||||||
|
Key: "Specification-Vendor",
|
||||||
|
Value: "io.jenkins-ci.plugin.thing",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Implementation-Vendor-ID",
|
||||||
|
Value: "William Goodman",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -459,8 +533,11 @@ func Test_groupIDsFromJavaManifest(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "spring-foo",
|
name: "spring-foo",
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Implementation-Vendor": "org.foo",
|
{
|
||||||
|
Key: "Implementation-Vendor",
|
||||||
|
Value: "org.foo",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []string{"org.foo"},
|
expected: []string{"org.foo"},
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/google/go-cmp/cmp/cmpopts"
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||||||
"github.com/gookit/color"
|
"github.com/gookit/color"
|
||||||
"github.com/scylladb/go-set/strset"
|
"github.com/scylladb/go-set/strset"
|
||||||
@ -197,31 +198,31 @@ func TestParseJar(t *testing.T) {
|
|||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
VirtualPath: "test-fixtures/java-builds/packages/example-jenkins-plugin.hpi",
|
VirtualPath: "test-fixtures/java-builds/packages/example-jenkins-plugin.hpi",
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Manifest-Version": "1.0",
|
{Key: "Manifest-Version", Value: "1.0"},
|
||||||
"Specification-Title": "Example Jenkins Plugin",
|
{Key: "Created-By", Value: "Maven Archiver 3.6.0"},
|
||||||
"Specification-Version": "1.0",
|
{Key: "Build-Jdk-Spec", Value: "18"},
|
||||||
"Implementation-Title": "Example Jenkins Plugin",
|
{Key: "Specification-Title", Value: "Example Jenkins Plugin"},
|
||||||
"Implementation-Version": "1.0-SNAPSHOT",
|
{Key: "Specification-Version", Value: "1.0"},
|
||||||
|
{Key: "Implementation-Title", Value: "Example Jenkins Plugin"},
|
||||||
|
{Key: "Implementation-Version", Value: "1.0-SNAPSHOT"},
|
||||||
|
{Key: "Group-Id", Value: "io.jenkins.plugins"},
|
||||||
|
{Key: "Short-Name", Value: "example-jenkins-plugin"},
|
||||||
|
{Key: "Long-Name", Value: "Example Jenkins Plugin"},
|
||||||
|
{Key: "Hudson-Version", Value: "2.204"},
|
||||||
|
{Key: "Jenkins-Version", Value: "2.204"},
|
||||||
|
{Key: "Plugin-Dependencies", Value: "structs:1.20"},
|
||||||
|
{Key: "Plugin-Developers", Value: ""},
|
||||||
|
{Key: "Plugin-License-Name", Value: "MIT License"},
|
||||||
|
{Key: "Plugin-License-Url", Value: "https://opensource.org/licenses/MIT"},
|
||||||
|
{Key: "Plugin-ScmUrl", Value: "https://github.com/jenkinsci/plugin-pom/example-jenkins-plugin"},
|
||||||
// extra fields...
|
// extra fields...
|
||||||
//"Archiver-Version": "Plexus Archiver",
|
//{Key: "Minimum-Java-Version", Value: "1.8"},
|
||||||
"Plugin-License-Url": "https://opensource.org/licenses/MIT",
|
//{Key: "Archiver-Version", Value: "Plexus Archiver"},
|
||||||
"Plugin-License-Name": "MIT License",
|
//{Key: "Built-By", Value: "?"},
|
||||||
"Created-By": "Maven Archiver 3.6.0",
|
//{Key: "Build-Jdk", Value: "14.0.1"},
|
||||||
//"Built-By": "?",
|
//{Key: "Extension-Name", Value: "example-jenkins-plugin"},
|
||||||
//"Build-Jdk": "14.0.1",
|
//{Key: "Plugin-Version", Value: "1.0-SNAPSHOT (private-07/09/2020 13:30-?)"},
|
||||||
"Build-Jdk-Spec": "18",
|
|
||||||
"Jenkins-Version": "2.204",
|
|
||||||
//"Minimum-Java-Version": "1.8",
|
|
||||||
"Plugin-Developers": "",
|
|
||||||
"Plugin-ScmUrl": "https://github.com/jenkinsci/plugin-pom/example-jenkins-plugin",
|
|
||||||
//"Extension-Name": "example-jenkins-plugin",
|
|
||||||
"Short-Name": "example-jenkins-plugin",
|
|
||||||
"Group-Id": "io.jenkins.plugins",
|
|
||||||
"Plugin-Dependencies": "structs:1.20",
|
|
||||||
//"Plugin-Version": "1.0-SNAPSHOT (private-07/09/2020 13:30-?)",
|
|
||||||
"Hudson-Version": "2.204",
|
|
||||||
"Long-Name": "Example Jenkins Plugin",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PomProperties: &pkg.JavaPomProperties{
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
@ -255,9 +256,15 @@ func TestParseJar(t *testing.T) {
|
|||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-gradle-0.1.0.jar",
|
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-gradle-0.1.0.jar",
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Manifest-Version": "1.0",
|
{
|
||||||
"Main-Class": "hello.HelloWorld",
|
Key: "Manifest-Version",
|
||||||
|
Value: "1.0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Main-Class",
|
||||||
|
Value: "hello.HelloWorld",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -326,14 +333,32 @@ func TestParseJar(t *testing.T) {
|
|||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar",
|
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar",
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Manifest-Version": "1.0",
|
{
|
||||||
|
Key: "Manifest-Version",
|
||||||
|
Value: "1.0",
|
||||||
|
},
|
||||||
// extra fields...
|
// extra fields...
|
||||||
"Archiver-Version": "Plexus Archiver",
|
{
|
||||||
"Created-By": "Apache Maven 3.8.6",
|
Key: "Archiver-Version",
|
||||||
//"Built-By": "?",
|
Value: "Plexus Archiver",
|
||||||
//"Build-Jdk": "14.0.1",
|
},
|
||||||
"Main-Class": "hello.HelloWorld",
|
{
|
||||||
|
Key: "Created-By",
|
||||||
|
Value: "Apache Maven 3.8.6",
|
||||||
|
},
|
||||||
|
//{
|
||||||
|
// Key: "Built-By",
|
||||||
|
// Value: "?",
|
||||||
|
//},
|
||||||
|
//{
|
||||||
|
// Key: "Build-Jdk",
|
||||||
|
// Value: "14.0.1",
|
||||||
|
//},
|
||||||
|
{
|
||||||
|
Key: "Main-Class",
|
||||||
|
Value: "hello.HelloWorld",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PomProperties: &pkg.JavaPomProperties{
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
@ -455,7 +480,14 @@ func TestParseJar(t *testing.T) {
|
|||||||
// ignore select fields (only works for the main section)
|
// ignore select fields (only works for the main section)
|
||||||
for _, field := range test.ignoreExtras {
|
for _, field := range test.ignoreExtras {
|
||||||
if metadata.Manifest != nil && metadata.Manifest.Main != nil {
|
if metadata.Manifest != nil && metadata.Manifest.Main != nil {
|
||||||
delete(metadata.Manifest.Main, field)
|
newMain := make(pkg.KeyValues, 0)
|
||||||
|
for i, kv := range metadata.Manifest.Main {
|
||||||
|
if kv.Key == field {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newMain = append(newMain, metadata.Manifest.Main[i])
|
||||||
|
}
|
||||||
|
metadata.Manifest.Main = newMain
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,32 +1190,32 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
|||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
VirtualPath: "test-fixtures/jar-metadata/cache/jackson-core-2.15.2.jar",
|
VirtualPath: "test-fixtures/jar-metadata/cache/jackson-core-2.15.2.jar",
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Build-Jdk-Spec": "1.8",
|
{Key: "Manifest-Version", Value: "1.0"},
|
||||||
"Bundle-Description": "Core Jackson processing abstractions",
|
{Key: "Bundle-License", Value: "https://www.apache.org/licenses/LICENSE-2.0.txt"},
|
||||||
"Bundle-DocURL": "https://github.com/FasterXML/jackson-core",
|
{Key: "Bundle-SymbolicName", Value: "com.fasterxml.jackson.core.jackson-core"},
|
||||||
"Bundle-License": "https://www.apache.org/licenses/LICENSE-2.0.txt",
|
{Key: "Implementation-Vendor-Id", Value: "com.fasterxml.jackson.core"},
|
||||||
"Bundle-ManifestVersion": "2",
|
{Key: "Specification-Title", Value: "Jackson-core"},
|
||||||
"Bundle-Name": "Jackson-core",
|
{Key: "Bundle-DocURL", Value: "https://github.com/FasterXML/jackson-core"},
|
||||||
"Bundle-SymbolicName": "com.fasterxml.jackson.core.jackson-core",
|
{Key: "Import-Package", Value: "com.fasterxml.jackson.core;version=...snip"},
|
||||||
"Bundle-Vendor": "FasterXML",
|
{Key: "Require-Capability", Value: `osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"`},
|
||||||
"Bundle-Version": "2.15.2",
|
{Key: "Export-Package", Value: "com.fasterxml.jackson.core;version...snip"},
|
||||||
"Created-By": "Apache Maven Bundle Plugin 5.1.8",
|
{Key: "Bundle-Name", Value: "Jackson-core"},
|
||||||
"Export-Package": "com.fasterxml.jackson.core;version...snip",
|
{Key: "Multi-Release", Value: "true"},
|
||||||
"Implementation-Title": "Jackson-core",
|
{Key: "Build-Jdk-Spec", Value: "1.8"},
|
||||||
"Implementation-Vendor": "FasterXML",
|
{Key: "Bundle-Description", Value: "Core Jackson processing abstractions"},
|
||||||
"Implementation-Vendor-Id": "com.fasterxml.jackson.core",
|
{Key: "Implementation-Title", Value: "Jackson-core"},
|
||||||
"Implementation-Version": "2.15.2",
|
{Key: "Implementation-Version", Value: "2.15.2"},
|
||||||
"Import-Package": "com.fasterxml.jackson.core;version=...snip",
|
{Key: "Bundle-ManifestVersion", Value: "2"},
|
||||||
"Manifest-Version": "1.0",
|
{Key: "Specification-Vendor", Value: "FasterXML"},
|
||||||
"Multi-Release": "true",
|
{Key: "Bundle-Vendor", Value: "FasterXML"},
|
||||||
"Require-Capability": `osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"`,
|
{Key: "Tool", Value: "Bnd-6.3.1.202206071316"},
|
||||||
"Specification-Title": "Jackson-core",
|
{Key: "Implementation-Vendor", Value: "FasterXML"},
|
||||||
"Specification-Vendor": "FasterXML",
|
{Key: "Bundle-Version", Value: "2.15.2"},
|
||||||
"Specification-Version": "2.15.2",
|
{Key: "X-Compile-Target-JDK", Value: "1.8"},
|
||||||
"Tool": "Bnd-6.3.1.202206071316",
|
{Key: "X-Compile-Source-JDK", Value: "1.8"},
|
||||||
"X-Compile-Source-JDK": "1.8",
|
{Key: "Created-By", Value: "Apache Maven Bundle Plugin 5.1.8"},
|
||||||
"X-Compile-Target-JDK": "1.8",
|
{Key: "Specification-Version", Value: "2.15.2"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// not under test
|
// not under test
|
||||||
@ -1212,32 +1244,32 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
|||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
VirtualPath: "test-fixtures/jar-metadata/cache/com.fasterxml.jackson.core.jackson-core-2.15.2.jar",
|
VirtualPath: "test-fixtures/jar-metadata/cache/com.fasterxml.jackson.core.jackson-core-2.15.2.jar",
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Build-Jdk-Spec": "1.8",
|
{Key: "Manifest-Version", Value: "1.0"},
|
||||||
"Bundle-Description": "Core Jackson processing abstractions",
|
{Key: "Bundle-License", Value: "https://www.apache.org/licenses/LICENSE-2.0.txt"},
|
||||||
"Bundle-DocURL": "https://github.com/FasterXML/jackson-core",
|
{Key: "Bundle-SymbolicName", Value: "com.fasterxml.jackson.core.jackson-core"},
|
||||||
"Bundle-License": "https://www.apache.org/licenses/LICENSE-2.0.txt",
|
{Key: "Implementation-Vendor-Id", Value: "com.fasterxml.jackson.core"},
|
||||||
"Bundle-ManifestVersion": "2",
|
{Key: "Specification-Title", Value: "Jackson-core"},
|
||||||
"Bundle-Name": "Jackson-core",
|
{Key: "Bundle-DocURL", Value: "https://github.com/FasterXML/jackson-core"},
|
||||||
"Bundle-SymbolicName": "com.fasterxml.jackson.core.jackson-core",
|
{Key: "Import-Package", Value: "com.fasterxml.jackson.core;version=...snip"},
|
||||||
"Bundle-Vendor": "FasterXML",
|
{Key: "Require-Capability", Value: `osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"`},
|
||||||
"Bundle-Version": "2.15.2",
|
{Key: "Export-Package", Value: "com.fasterxml.jackson.core;version...snip"},
|
||||||
"Created-By": "Apache Maven Bundle Plugin 5.1.8",
|
{Key: "Bundle-Name", Value: "Jackson-core"},
|
||||||
"Export-Package": "com.fasterxml.jackson.core;version...snip",
|
{Key: "Multi-Release", Value: "true"},
|
||||||
"Implementation-Title": "Jackson-core",
|
{Key: "Build-Jdk-Spec", Value: "1.8"},
|
||||||
"Implementation-Vendor": "FasterXML",
|
{Key: "Bundle-Description", Value: "Core Jackson processing abstractions"},
|
||||||
"Implementation-Vendor-Id": "com.fasterxml.jackson.core",
|
{Key: "Implementation-Title", Value: "Jackson-core"},
|
||||||
"Implementation-Version": "2.15.2",
|
{Key: "Implementation-Version", Value: "2.15.2"},
|
||||||
"Import-Package": "com.fasterxml.jackson.core;version=...snip",
|
{Key: "Bundle-ManifestVersion", Value: "2"},
|
||||||
"Manifest-Version": "1.0",
|
{Key: "Specification-Vendor", Value: "FasterXML"},
|
||||||
"Multi-Release": "true",
|
{Key: "Bundle-Vendor", Value: "FasterXML"},
|
||||||
"Require-Capability": `osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"`,
|
{Key: "Tool", Value: "Bnd-6.3.1.202206071316"},
|
||||||
"Specification-Title": "Jackson-core",
|
{Key: "Implementation-Vendor", Value: "FasterXML"},
|
||||||
"Specification-Vendor": "FasterXML",
|
{Key: "Bundle-Version", Value: "2.15.2"},
|
||||||
"Specification-Version": "2.15.2",
|
{Key: "X-Compile-Target-JDK", Value: "1.8"},
|
||||||
"Tool": "Bnd-6.3.1.202206071316",
|
{Key: "X-Compile-Source-JDK", Value: "1.8"},
|
||||||
"X-Compile-Source-JDK": "1.8",
|
{Key: "Created-By", Value: "Apache Maven Bundle Plugin 5.1.8"},
|
||||||
"X-Compile-Target-JDK": "1.8",
|
{Key: "Specification-Version", Value: "2.15.2"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// not under test
|
// not under test
|
||||||
@ -1261,11 +1293,23 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
|||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
VirtualPath: "test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar",
|
VirtualPath: "test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar",
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Build-Jdk": "1.8.0_191",
|
{
|
||||||
"Built-By": "elecharny",
|
Key: "Manifest-Version",
|
||||||
"Created-By": "Apache Maven 3.6.0",
|
Value: "1.0",
|
||||||
"Manifest-Version": "1.0",
|
},
|
||||||
|
{
|
||||||
|
Key: "Built-By",
|
||||||
|
Value: "elecharny",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Created-By",
|
||||||
|
Value: "Apache Maven 3.6.0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Build-Jdk",
|
||||||
|
Value: "1.8.0_191",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PomProperties: &pkg.JavaPomProperties{
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
@ -1314,10 +1358,25 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
|||||||
if tt.assignParent {
|
if tt.assignParent {
|
||||||
assignParent(&tt.expectedPkgs[0], tt.expectedPkgs[1:]...)
|
assignParent(&tt.expectedPkgs[0], tt.expectedPkgs[1:]...)
|
||||||
}
|
}
|
||||||
|
for i := range tt.expectedPkgs {
|
||||||
|
tt.expectedPkgs[i].SetID()
|
||||||
|
}
|
||||||
pkgtest.NewCatalogTester().
|
pkgtest.NewCatalogTester().
|
||||||
FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName)).
|
FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName)).
|
||||||
Expects(tt.expectedPkgs, tt.expectedRelationships).
|
Expects(tt.expectedPkgs, tt.expectedRelationships).
|
||||||
WithCompareOptions(cmpopts.IgnoreFields(pkg.JavaArchive{}, "ArchiveDigests")).
|
WithCompareOptions(
|
||||||
|
cmpopts.IgnoreFields(pkg.JavaArchive{}, "ArchiveDigests"),
|
||||||
|
cmp.Comparer(func(x, y pkg.KeyValue) bool {
|
||||||
|
if x.Key != y.Key {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if x.Value != y.Value {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}),
|
||||||
|
).
|
||||||
TestParser(t, gap.parseJavaArchive)
|
TestParser(t, gap.parseJavaArchive)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,8 +24,11 @@ func Test_packageURL(t *testing.T) {
|
|||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar",
|
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar",
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Manifest-Version": "1.0",
|
{
|
||||||
|
Key: "Manifest-Version",
|
||||||
|
Value: "1.0",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PomProperties: &pkg.JavaPomProperties{
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
@ -49,8 +52,11 @@ func Test_packageURL(t *testing.T) {
|
|||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar",
|
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar",
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Manifest-Version": "1.0",
|
{
|
||||||
|
Key: "Manifest-Version",
|
||||||
|
Value: "1.0",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PomProperties: &pkg.JavaPomProperties{
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
@ -74,8 +80,11 @@ func Test_packageURL(t *testing.T) {
|
|||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar",
|
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar",
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Manifest-Version": "1.0",
|
{
|
||||||
|
Key: "Manifest-Version",
|
||||||
|
Value: "1.0",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PomProperties: &pkg.JavaPomProperties{
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
@ -101,8 +110,11 @@ func Test_packageURL(t *testing.T) {
|
|||||||
Metadata: pkg.JavaArchive{
|
Metadata: pkg.JavaArchive{
|
||||||
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar",
|
VirtualPath: "test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar",
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Manifest-Version": "1.0",
|
{
|
||||||
|
Key: "Manifest-Version",
|
||||||
|
Value: "1.0",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
PomProperties: &pkg.JavaPomProperties{
|
PomProperties: &pkg.JavaPomProperties{
|
||||||
@ -163,8 +175,11 @@ func Test_groupIDFromJavaMetadata(t *testing.T) {
|
|||||||
name: "java manifest",
|
name: "java manifest",
|
||||||
metadata: pkg.JavaArchive{
|
metadata: pkg.JavaArchive{
|
||||||
Manifest: &pkg.JavaManifest{
|
Manifest: &pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Implementation-Vendor": "org.anchore",
|
{
|
||||||
|
Key: "Implementation-Vendor",
|
||||||
|
Value: "org.anchore",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
@ -20,7 +19,7 @@ const manifestGlob = "/META-INF/MANIFEST.MF"
|
|||||||
//nolint:funlen
|
//nolint:funlen
|
||||||
func parseJavaManifest(path string, reader io.Reader) (*pkg.JavaManifest, error) {
|
func parseJavaManifest(path string, reader io.Reader) (*pkg.JavaManifest, error) {
|
||||||
var manifest pkg.JavaManifest
|
var manifest pkg.JavaManifest
|
||||||
var sections []map[string]string
|
sections := make([]pkg.KeyValues, 0)
|
||||||
|
|
||||||
currentSection := func() int {
|
currentSection := func() int {
|
||||||
return len(sections) - 1
|
return len(sections) - 1
|
||||||
@ -51,7 +50,9 @@ func parseJavaManifest(path string, reader io.Reader) (*pkg.JavaManifest, error)
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
sections[currentSection()][lastKey] += strings.TrimSpace(line)
|
lastSection := sections[currentSection()]
|
||||||
|
|
||||||
|
sections[currentSection()][len(lastSection)-1].Value += strings.TrimSpace(line)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -73,10 +74,13 @@ func parseJavaManifest(path string, reader io.Reader) (*pkg.JavaManifest, error)
|
|||||||
|
|
||||||
if lastKey == "" {
|
if lastKey == "" {
|
||||||
// we're entering a new section
|
// we're entering a new section
|
||||||
sections = append(sections, make(map[string]string))
|
sections = append(sections, make(pkg.KeyValues, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
sections[currentSection()][key] = value
|
sections[currentSection()] = append(sections[currentSection()], pkg.KeyValue{
|
||||||
|
Key: key,
|
||||||
|
Value: value,
|
||||||
|
})
|
||||||
|
|
||||||
// keep track of key for potential future continuations
|
// keep track of key for potential future continuations
|
||||||
lastKey = key
|
lastKey = key
|
||||||
@ -89,20 +93,7 @@ func parseJavaManifest(path string, reader io.Reader) (*pkg.JavaManifest, error)
|
|||||||
if len(sections) > 0 {
|
if len(sections) > 0 {
|
||||||
manifest.Main = sections[0]
|
manifest.Main = sections[0]
|
||||||
if len(sections) > 1 {
|
if len(sections) > 1 {
|
||||||
manifest.NamedSections = make(map[string]map[string]string)
|
manifest.Sections = sections[1:]
|
||||||
for i, s := range sections[1:] {
|
|
||||||
name, ok := s["Name"]
|
|
||||||
if !ok {
|
|
||||||
// per the manifest spec (https://docs.oracle.com/en/java/javase/11/docs/specs/jar/jar.html#jar-manifest)
|
|
||||||
// this should never happen. If it does, we want to know about it, but not necessarily stop
|
|
||||||
// cataloging entirely... for this reason we only log.
|
|
||||||
log.Debugf("java manifest section found without a name: %s", path)
|
|
||||||
name = strconv.Itoa(i)
|
|
||||||
} else {
|
|
||||||
delete(s, "Name")
|
|
||||||
}
|
|
||||||
manifest.NamedSections[name] = s
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,12 +118,12 @@ func extractNameFromApacheMavenBundlePlugin(manifest *pkg.JavaManifest) string {
|
|||||||
// The computed symbolic name is also stored in the $(maven-symbolicname) property in case you want to add attributes or directives to it.
|
// The computed symbolic name is also stored in the $(maven-symbolicname) property in case you want to add attributes or directives to it.
|
||||||
//
|
//
|
||||||
if manifest != nil {
|
if manifest != nil {
|
||||||
if strings.Contains(manifest.Main["Created-By"], "Apache Maven Bundle Plugin") {
|
if strings.Contains(manifest.Main.MustGet("Created-By"), "Apache Maven Bundle Plugin") {
|
||||||
if symbolicName := manifest.Main["Bundle-SymbolicName"]; symbolicName != "" {
|
if symbolicName := manifest.Main.MustGet("Bundle-SymbolicName"); symbolicName != "" {
|
||||||
// It is possible that `Bundle-SymbolicName` is just the groupID (like in the case of
|
// It is possible that `Bundle-SymbolicName` is just the groupID (like in the case of
|
||||||
// https://repo1.maven.org/maven2/com/google/oauth-client/google-oauth-client/1.25.0/google-oauth-client-1.25.0.jar),
|
// https://repo1.maven.org/maven2/com/google/oauth-client/google-oauth-client/1.25.0/google-oauth-client-1.25.0.jar),
|
||||||
// so if `Implementation-Vendor-Id` is equal to `Bundle-SymbolicName`, bail on this logic
|
// so if `Implementation-Vendor-Id` is equal to `Bundle-SymbolicName`, bail on this logic
|
||||||
if vendorID := manifest.Main["Implementation-Vendor-Id"]; vendorID != "" && vendorID == symbolicName {
|
if vendorID := manifest.Main.MustGet("Implementation-Vendor-Id"); vendorID != "" && vendorID == symbolicName {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,21 +203,21 @@ func selectName(manifest *pkg.JavaManifest, filenameObj archiveFilename) string
|
|||||||
// remaining fields in the manifest is a bit of a free-for-all depending on the build tooling used and package maintainer preferences
|
// remaining fields in the manifest is a bit of a free-for-all depending on the build tooling used and package maintainer preferences
|
||||||
if manifest != nil {
|
if manifest != nil {
|
||||||
switch {
|
switch {
|
||||||
case manifest.Main["Name"] != "":
|
case manifest.Main.MustGet("Name") != "":
|
||||||
// Manifest original spec...
|
// Manifest original spec...
|
||||||
return manifest.Main["Name"]
|
return manifest.Main.MustGet("Name")
|
||||||
case manifest.Main["Bundle-Name"] != "":
|
case manifest.Main.MustGet("Bundle-Name") != "":
|
||||||
// BND tooling... TODO: this does not seem accurate (I don't see a reference in the BND tooling docs for this)
|
// BND tooling... TODO: this does not seem accurate (I don't see a reference in the BND tooling docs for this)
|
||||||
return manifest.Main["Bundle-Name"]
|
return manifest.Main.MustGet("Bundle-Name")
|
||||||
case manifest.Main["Short-Name"] != "":
|
case manifest.Main.MustGet("Short-Name") != "":
|
||||||
// Jenkins...
|
// Jenkins...
|
||||||
return manifest.Main["Short-Name"]
|
return manifest.Main.MustGet("Short-Name")
|
||||||
case manifest.Main["Extension-Name"] != "":
|
case manifest.Main.MustGet("Extension-Name") != "":
|
||||||
// Jenkins...
|
// Jenkins...
|
||||||
return manifest.Main["Extension-Name"]
|
return manifest.Main.MustGet("Extension-Name")
|
||||||
case manifest.Main["Implementation-Title"] != "":
|
case manifest.Main.MustGet("Implementation-Title") != "":
|
||||||
// last ditch effort...
|
// last ditch effort...
|
||||||
return manifest.Main["Implementation-Title"]
|
return manifest.Main.MustGet("Implementation-Title")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
@ -278,12 +269,12 @@ func selectLicenses(manifest *pkg.JavaManifest) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fieldValueFromManifest(manifest pkg.JavaManifest, fieldName string) string {
|
func fieldValueFromManifest(manifest pkg.JavaManifest, fieldName string) string {
|
||||||
if value := manifest.Main[fieldName]; value != "" {
|
if value := manifest.Main.MustGet(fieldName); value != "" {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, section := range manifest.NamedSections {
|
for _, section := range manifest.Sections {
|
||||||
if value := section[fieldName]; value != "" {
|
if value := section.MustGet(fieldName); value != "" {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,41 +19,63 @@ func TestParseJavaManifest(t *testing.T) {
|
|||||||
{
|
{
|
||||||
fixture: "test-fixtures/manifest/small",
|
fixture: "test-fixtures/manifest/small",
|
||||||
expected: pkg.JavaManifest{
|
expected: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Manifest-Version": "1.0",
|
{Key: "Manifest-Version", Value: "1.0"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fixture: "test-fixtures/manifest/standard-info",
|
fixture: "test-fixtures/manifest/standard-info",
|
||||||
expected: pkg.JavaManifest{
|
expected: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Name": "the-best-name",
|
{Key: "Manifest-Version", Value: "1.0"},
|
||||||
"Manifest-Version": "1.0",
|
{Key: "Name", Value: "the-best-name"},
|
||||||
"Specification-Title": "the-spec-title",
|
{Key: "Specification-Title", Value: "the-spec-title"},
|
||||||
"Specification-Version": "the-spec-version",
|
{Key: "Specification-Vendor", Value: "the-spec-vendor"},
|
||||||
"Specification-Vendor": "the-spec-vendor",
|
{Key: "Specification-Version", Value: "the-spec-version"},
|
||||||
"Implementation-Title": "the-impl-title",
|
{Key: "Implementation-Title", Value: "the-impl-title"},
|
||||||
"Implementation-Version": "the-impl-version",
|
{Key: "Implementation-Vendor", Value: "the-impl-vendor"},
|
||||||
"Implementation-Vendor": "the-impl-vendor",
|
{Key: "Implementation-Version", Value: "the-impl-version"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fixture: "test-fixtures/manifest/extra-info",
|
fixture: "test-fixtures/manifest/extra-info",
|
||||||
expected: pkg.JavaManifest{
|
expected: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Manifest-Version": "1.0",
|
{
|
||||||
"Archiver-Version": "Plexus Archiver",
|
Key: "Manifest-Version",
|
||||||
"Created-By": "Apache Maven 3.6.3",
|
Value: "1.0",
|
||||||
},
|
|
||||||
NamedSections: map[string]map[string]string{
|
|
||||||
"thing-1": {
|
|
||||||
"Built-By": "?",
|
|
||||||
},
|
},
|
||||||
"1": {
|
{
|
||||||
"Build-Jdk": "14.0.1",
|
Key: "Archiver-Version",
|
||||||
"Main-Class": "hello.HelloWorld",
|
Value: "Plexus Archiver",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Created-By",
|
||||||
|
Value: "Apache Maven 3.6.3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Sections: []pkg.KeyValues{
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: "Name",
|
||||||
|
Value: "thing-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Built-By",
|
||||||
|
Value: "?",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: "Build-Jdk",
|
||||||
|
Value: "14.0.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Main-Class",
|
||||||
|
Value: "hello.HelloWorld",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -61,23 +83,34 @@ func TestParseJavaManifest(t *testing.T) {
|
|||||||
{
|
{
|
||||||
fixture: "test-fixtures/manifest/extra-empty-lines",
|
fixture: "test-fixtures/manifest/extra-empty-lines",
|
||||||
expected: pkg.JavaManifest{
|
expected: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Manifest-Version": "1.0",
|
{
|
||||||
"Archiver-Version": "Plexus Archiver",
|
Key: "Manifest-Version",
|
||||||
"Created-By": "Apache Maven 3.6.3",
|
Value: "1.0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Archiver-Version",
|
||||||
|
Value: "Plexus Archiver",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Created-By",
|
||||||
|
Value: "Apache Maven 3.6.3",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
NamedSections: map[string]map[string]string{
|
Sections: []pkg.KeyValues{
|
||||||
"thing-1": {
|
{
|
||||||
"Built-By": "?",
|
{Key: "Name", Value: "thing-1"},
|
||||||
|
{Key: "Built-By", Value: "?"},
|
||||||
},
|
},
|
||||||
"thing-2": {
|
{
|
||||||
"Built-By": "someone!",
|
{Key: "Name", Value: "thing-2"},
|
||||||
|
{Key: "Built-By", Value: "someone!"},
|
||||||
},
|
},
|
||||||
"2": {
|
{
|
||||||
"Other": "things",
|
{Key: "Other", Value: "things"},
|
||||||
},
|
},
|
||||||
"3": {
|
{
|
||||||
"Last": "item",
|
{Key: "Last", Value: "item"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -85,9 +118,15 @@ func TestParseJavaManifest(t *testing.T) {
|
|||||||
{
|
{
|
||||||
fixture: "test-fixtures/manifest/continuation",
|
fixture: "test-fixtures/manifest/continuation",
|
||||||
expected: pkg.JavaManifest{
|
expected: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Manifest-Version": "1.0",
|
{
|
||||||
"Plugin-ScmUrl": "https://github.com/jenkinsci/plugin-pom/example-jenkins-plugin",
|
Key: "Manifest-Version",
|
||||||
|
Value: "1.0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Plugin-ScmUrl",
|
||||||
|
Value: "https://github.com/jenkinsci/plugin-pom/example-jenkins-plugin",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -95,9 +134,15 @@ func TestParseJavaManifest(t *testing.T) {
|
|||||||
// regression test, we should always keep the full version
|
// regression test, we should always keep the full version
|
||||||
fixture: "test-fixtures/manifest/version-with-date",
|
fixture: "test-fixtures/manifest/version-with-date",
|
||||||
expected: pkg.JavaManifest{
|
expected: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Manifest-Version": "1.0",
|
{
|
||||||
"Implementation-Version": "1.3 2244 October 5 2005",
|
Key: "Manifest-Version",
|
||||||
|
Value: "1.0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Implementation-Version",
|
||||||
|
Value: "1.3 2244 October 5 2005",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -106,9 +151,15 @@ func TestParseJavaManifest(t *testing.T) {
|
|||||||
// https://github.com/anchore/syft/issues/2179
|
// https://github.com/anchore/syft/issues/2179
|
||||||
fixture: "test-fixtures/manifest/leading-space",
|
fixture: "test-fixtures/manifest/leading-space",
|
||||||
expected: pkg.JavaManifest{
|
expected: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Key-keykeykey": "initialconfig:com$ # aka not empty line",
|
{
|
||||||
"should": "parse",
|
Key: "Key-keykeykey",
|
||||||
|
Value: "initialconfig:com$ # aka not empty line",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "should",
|
||||||
|
Value: "parse",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -154,8 +205,11 @@ func TestSelectName(t *testing.T) {
|
|||||||
desc: "Get name from Implementation-Title",
|
desc: "Get name from Implementation-Title",
|
||||||
archive: archiveFilename{},
|
archive: archiveFilename{},
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Implementation-Title": "maven-wrapper",
|
{
|
||||||
|
Key: "Implementation-Title",
|
||||||
|
Value: "maven-wrapper",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: "maven-wrapper",
|
expected: "maven-wrapper",
|
||||||
@ -163,9 +217,15 @@ func TestSelectName(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "Implementation-Title does not override name from filename",
|
desc: "Implementation-Title does not override name from filename",
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Name": "foo",
|
{
|
||||||
"Implementation-Title": "maven-wrapper",
|
Key: "Name",
|
||||||
|
Value: "foo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Implementation-Title",
|
||||||
|
Value: "maven-wrapper",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
archive: newJavaArchiveFilename("/something/omg.jar"),
|
archive: newJavaArchiveFilename("/something/omg.jar"),
|
||||||
@ -174,11 +234,11 @@ func TestSelectName(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "Use the artifact ID baked by the Apache Maven Bundle Plugin",
|
desc: "Use the artifact ID baked by the Apache Maven Bundle Plugin",
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Created-By": "Apache Maven Bundle Plugin",
|
{Key: "Created-By", Value: "Apache Maven Bundle Plugin"},
|
||||||
"Bundle-SymbolicName": "com.atlassian.gadgets.atlassian-gadgets-api",
|
{Key: "Bundle-SymbolicName", Value: "com.atlassian.gadgets.atlassian-gadgets-api"},
|
||||||
"Name": "foo",
|
{Key: "Name", Value: "foo"},
|
||||||
"Implementation-Title": "maven-wrapper",
|
{Key: "Implementation-Title", Value: "maven-wrapper"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
archive: newJavaArchiveFilename("/something/omg.jar"),
|
archive: newJavaArchiveFilename("/something/omg.jar"),
|
||||||
@ -188,11 +248,11 @@ func TestSelectName(t *testing.T) {
|
|||||||
// example: pkg:maven/org.apache.servicemix.bundles/org.apache.servicemix.bundles.spring-beans@5.3.26_1
|
// example: pkg:maven/org.apache.servicemix.bundles/org.apache.servicemix.bundles.spring-beans@5.3.26_1
|
||||||
desc: "Apache Maven Bundle Plugin might bake a version in the created-by field",
|
desc: "Apache Maven Bundle Plugin might bake a version in the created-by field",
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Created-By": "Apache Maven Bundle Plugin 5.1.6",
|
{Key: "Created-By", Value: "Apache Maven Bundle Plugin 5.1.6"},
|
||||||
"Bundle-SymbolicName": "com.atlassian.gadgets.atlassian-gadgets-api",
|
{Key: "Bundle-SymbolicName", Value: "com.atlassian.gadgets.atlassian-gadgets-api"},
|
||||||
"Name": "foo",
|
{Key: "Name", Value: "foo"},
|
||||||
"Implementation-Title": "maven-wrapper",
|
{Key: "Implementation-Title", Value: "maven-wrapper"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
archive: newJavaArchiveFilename("/something/omg.jar"),
|
archive: newJavaArchiveFilename("/something/omg.jar"),
|
||||||
@ -201,9 +261,15 @@ func TestSelectName(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "Filename looks like a groupid + artifact id",
|
desc: "Filename looks like a groupid + artifact id",
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Name": "foo",
|
{
|
||||||
"Implementation-Title": "maven-wrapper",
|
Key: "Name",
|
||||||
|
Value: "foo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Implementation-Title",
|
||||||
|
Value: "maven-wrapper",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
archive: newJavaArchiveFilename("/something/com.atlassian.gadgets.atlassian-gadgets-api.jar"),
|
archive: newJavaArchiveFilename("/something/com.atlassian.gadgets.atlassian-gadgets-api.jar"),
|
||||||
@ -228,8 +294,11 @@ func TestSelectName(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "Skip stripping groupId prefix from archive filename for org.eclipse",
|
desc: "Skip stripping groupId prefix from archive filename for org.eclipse",
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Automatic-Module-Name": "org.eclipse.ant.core",
|
{
|
||||||
|
Key: "Automatic-Module-Name",
|
||||||
|
Value: "org.eclipse.ant.core",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
archive: newJavaArchiveFilename("/something/org.eclipse.ant.core-3.7.0.jar"),
|
archive: newJavaArchiveFilename("/something/org.eclipse.ant.core-3.7.0.jar"),
|
||||||
@ -239,21 +308,21 @@ func TestSelectName(t *testing.T) {
|
|||||||
// example: pkg:maven/com.google.oauth-client/google-oauth-client@1.25.0
|
// example: pkg:maven/com.google.oauth-client/google-oauth-client@1.25.0
|
||||||
desc: "skip Apache Maven Bundle Plugin logic if symbolic name is same as vendor id",
|
desc: "skip Apache Maven Bundle Plugin logic if symbolic name is same as vendor id",
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Bundle-DocURL": "http://www.google.com/",
|
{Key: "Bundle-DocURL", Value: "http://www.google.com/"},
|
||||||
"Bundle-License": "http://www.apache.org/licenses/LICENSE-2.0.txt",
|
{Key: "Bundle-License", Value: "http://www.apache.org/licenses/LICENSE-2.0.txt"},
|
||||||
"Bundle-ManifestVersion": "2",
|
{Key: "Bundle-ManifestVersion", Value: "2"},
|
||||||
"Bundle-Name": "Google OAuth Client Library for Java",
|
{Key: "Bundle-Name", Value: "Google OAuth Client Library for Java"},
|
||||||
"Bundle-RequiredExecutionEnvironment": "JavaSE-1.6",
|
{Key: "Bundle-RequiredExecutionEnvironment", Value: "JavaSE-1.6"},
|
||||||
"Bundle-SymbolicName": "com.google.oauth-client",
|
{Key: "Bundle-SymbolicName", Value: "com.google.oauth-client"},
|
||||||
"Bundle-Vendor": "Google",
|
{Key: "Bundle-Vendor", Value: "Google"},
|
||||||
"Bundle-Version": "1.25.0",
|
{Key: "Bundle-Version", Value: "1.25.0"},
|
||||||
"Created-By": "Apache Maven Bundle Plugin",
|
{Key: "Created-By", Value: "Apache Maven Bundle Plugin"},
|
||||||
"Export-Package": "com.google.api.client.auth.openidconnect;uses:=\"com.google.api.client.auth.oauth2,com.google.api.client.json,com.google.api.client.json.webtoken,com.google.api.client.util\";version=\"1.25.0\",com.google.api.client.auth.oauth;uses:=\"com.google.api.client.http,com.google.api.client.util\";version=\"1.25.0\",com.google.api.client.auth.oauth2;uses:=\"com.google.api.client.http,com.google.api.client.json,com.google.api.client.util,com.google.api.client.util.store\";version=\"1.25.0\"",
|
{Key: "Export-Package", Value: "com.google.api.client.auth.openidconnect;uses:=\"com.google.api.client.auth.oauth2,com.google.api.client.json,com.google.api.client.json.webtoken,com.google.api.client.util\";version=\"1.25.0\",com.google.api.client.auth.oauth;uses:=\"com.google.api.client.http,com.google.api.client.util\";version=\"1.25.0\",com.google.api.client.auth.oauth2;uses:=\"com.google.api.client.http,com.google.api.client.json,com.google.api.client.util,com.google.api.client.util.store\";version=\"1.25.0\""},
|
||||||
"Implementation-Title": "Google OAuth Client Library for Java",
|
{Key: "Implementation-Title", Value: "Google OAuth Client Library for Java"},
|
||||||
"Implementation-Vendor": "Google",
|
{Key: "Implementation-Vendor", Value: "Google"},
|
||||||
"Implementation-Vendor-Id": "com.google.oauth-client",
|
{Key: "Implementation-Vendor-Id", Value: "com.google.oauth-client"},
|
||||||
"Implementation-Version": "1.25.0",
|
{Key: "Implementation-Version", Value: "1.25.0"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
archive: newJavaArchiveFilename("/something/google-oauth-client-1.25.0.jar"),
|
archive: newJavaArchiveFilename("/something/google-oauth-client-1.25.0.jar"),
|
||||||
@ -283,8 +352,11 @@ func TestSelectVersion(t *testing.T) {
|
|||||||
name: "Get name from Implementation-Version",
|
name: "Get name from Implementation-Version",
|
||||||
archive: archiveFilename{},
|
archive: archiveFilename{},
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Implementation-Version": "1.8.2",
|
{
|
||||||
|
Key: "Implementation-Version",
|
||||||
|
Value: "1.8.2",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: "1.8.2",
|
expected: "1.8.2",
|
||||||
@ -292,9 +364,15 @@ func TestSelectVersion(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Implementation-Version takes precedence over Specification-Version",
|
name: "Implementation-Version takes precedence over Specification-Version",
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Implementation-Version": "1.8.2",
|
{
|
||||||
"Specification-Version": "1.0",
|
Key: "Implementation-Version",
|
||||||
|
Value: "1.8.2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Specification-Version",
|
||||||
|
Value: "1.0",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: "1.8.2",
|
expected: "1.8.2",
|
||||||
@ -302,14 +380,15 @@ func TestSelectVersion(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Implementation-Version found outside the main section",
|
name: "Implementation-Version found outside the main section",
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Manifest-Version": "1.0",
|
{Key: "Manifest-Version", Value: "1.0"},
|
||||||
"Ant-Version": "Apache Ant 1.8.2",
|
{Key: "Ant-Version", Value: "Apache Ant 1.8.2"},
|
||||||
"Created-By": "1.5.0_22-b03 (Sun Microsystems Inc.)",
|
{Key: "Created-By", Value: "1.5.0_22-b03 (Sun Microsystems Inc.)"},
|
||||||
},
|
},
|
||||||
NamedSections: map[string]map[string]string{
|
Sections: []pkg.KeyValues{
|
||||||
"org/apache/tools/ant/taskdefs/optional/": {
|
{
|
||||||
"Implementation-Version": "1.8.2",
|
{Key: "Name", Value: "org/apache/tools/ant/taskdefs/optional/"},
|
||||||
|
{Key: "Implementation-Version", Value: "1.8.2"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -318,34 +397,53 @@ func TestSelectVersion(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Implementation-Version takes precedence over Specification-Version in subsequent section",
|
name: "Implementation-Version takes precedence over Specification-Version in subsequent section",
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: pkg.KeyValues{
|
||||||
"Manifest-Version": "1.0",
|
{Key: "Manifest-Version", Value: "1.0"},
|
||||||
"Ant-Version": "Apache Ant 1.8.2",
|
{Key: "Ant-Version", Value: "Apache Ant 1.8.2"},
|
||||||
"Created-By": "1.5.0_22-b03 (Sun Microsystems Inc.)",
|
{Key: "Created-By", Value: "1.5.0_22-b03 (Sun Microsystems Inc.)"},
|
||||||
"Specification-Version": "2.0",
|
{Key: "Specification-Version", Value: "2.0"},
|
||||||
},
|
},
|
||||||
NamedSections: map[string]map[string]string{
|
Sections: []pkg.KeyValues{
|
||||||
"org/apache/tools/ant/taskdefs/optional/": {
|
{
|
||||||
"Specification-Version": "1.8",
|
{Key: "Name", Value: "org/apache/tools/ant/taskdefs/optional/"},
|
||||||
|
{Key: "Specification-Version", Value: "1.8"},
|
||||||
},
|
},
|
||||||
"some-other-section": {
|
{
|
||||||
"Implementation-Version": "1.8.2",
|
{Key: "Name", Value: "some-other-section"},
|
||||||
|
{Key: "Implementation-Version", Value: "1.8.2"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
expected: "1.8.2",
|
expected: "1.8.2",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Implementation-Version takes precedence over Specification-Version in subsequent section",
|
name: "Implementation-Version takes precedence over Specification-Version in subsequent section",
|
||||||
manifest: pkg.JavaManifest{
|
manifest: pkg.JavaManifest{
|
||||||
Main: map[string]string{
|
Main: []pkg.KeyValue{
|
||||||
"Manifest-Version": "1.0",
|
{
|
||||||
"Ant-Version": "Apache Ant 1.8.2",
|
Key: "Manifest-Version",
|
||||||
"Created-By": "1.5.0_22-b03 (Sun Microsystems Inc.)",
|
Value: "1.0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Ant-Version",
|
||||||
|
Value: "Apache Ant 1.8.2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Created-By",
|
||||||
|
Value: "1.5.0_22-b03 (Sun Microsystems Inc.)",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
NamedSections: map[string]map[string]string{
|
Sections: []pkg.KeyValues{
|
||||||
"some-other-section": {
|
{
|
||||||
"Bundle-Version": "1.11.28",
|
{
|
||||||
|
Key: "Name",
|
||||||
|
Value: "some-other-section",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "Bundle-Version",
|
||||||
|
Value: "1.11.28",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2,15 +2,15 @@ package pkg
|
|||||||
|
|
||||||
// ConanLockEntry represents a single "node" entry from a conan.lock file.
|
// ConanLockEntry represents a single "node" entry from a conan.lock file.
|
||||||
type ConanLockEntry struct {
|
type ConanLockEntry struct {
|
||||||
Ref string `json:"ref"`
|
Ref string `json:"ref"`
|
||||||
PackageID string `json:"package_id,omitempty"`
|
PackageID string `json:"package_id,omitempty"`
|
||||||
Prev string `json:"prev,omitempty"`
|
Prev string `json:"prev,omitempty"`
|
||||||
Requires []string `json:"requires,omitempty"`
|
Requires []string `json:"requires,omitempty"`
|
||||||
BuildRequires []string `json:"build_requires,omitempty"`
|
BuildRequires []string `json:"build_requires,omitempty"`
|
||||||
PythonRequires []string `json:"py_requires,omitempty"`
|
PythonRequires []string `json:"py_requires,omitempty"`
|
||||||
Options map[string]string `json:"options,omitempty"`
|
Options KeyValues `json:"options,omitempty"`
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
Context string `json:"context,omitempty"`
|
Context string `json:"context,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConanfileEntry represents a single "Requires" entry from a conanfile.txt.
|
// ConanfileEntry represents a single "Requires" entry from a conanfile.txt.
|
||||||
|
|||||||
@ -2,12 +2,12 @@ package pkg
|
|||||||
|
|
||||||
// GolangBinaryBuildinfoEntry represents all captured data for a Golang binary
|
// GolangBinaryBuildinfoEntry represents all captured data for a Golang binary
|
||||||
type GolangBinaryBuildinfoEntry struct {
|
type GolangBinaryBuildinfoEntry struct {
|
||||||
BuildSettings map[string]string `json:"goBuildSettings,omitempty" cyclonedx:"goBuildSettings"`
|
BuildSettings KeyValues `json:"goBuildSettings,omitempty" cyclonedx:"goBuildSettings"`
|
||||||
GoCompiledVersion string `json:"goCompiledVersion" cyclonedx:"goCompiledVersion"`
|
GoCompiledVersion string `json:"goCompiledVersion" cyclonedx:"goCompiledVersion"`
|
||||||
Architecture string `json:"architecture" cyclonedx:"architecture"`
|
Architecture string `json:"architecture" cyclonedx:"architecture"`
|
||||||
H1Digest string `json:"h1Digest,omitempty" cyclonedx:"h1Digest"`
|
H1Digest string `json:"h1Digest,omitempty" cyclonedx:"h1Digest"`
|
||||||
MainModule string `json:"mainModule,omitempty" cyclonedx:"mainModule"`
|
MainModule string `json:"mainModule,omitempty" cyclonedx:"mainModule"`
|
||||||
GoCryptoSettings []string `json:"goCryptoSettings,omitempty" cyclonedx:"goCryptoSettings"`
|
GoCryptoSettings []string `json:"goCryptoSettings,omitempty" cyclonedx:"goCryptoSettings"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GolangModuleEntry represents all captured data for a Golang source scan with go.mod/go.sum
|
// GolangModuleEntry represents all captured data for a Golang source scan with go.mod/go.sum
|
||||||
|
|||||||
@ -66,6 +66,15 @@ func (p JavaPomProperties) PkgTypeIndicated() Type {
|
|||||||
|
|
||||||
// JavaManifest represents the fields of interest extracted from a Java archive's META-INF/MANIFEST.MF file.
|
// JavaManifest represents the fields of interest extracted from a Java archive's META-INF/MANIFEST.MF file.
|
||||||
type JavaManifest struct {
|
type JavaManifest struct {
|
||||||
Main map[string]string `json:"main,omitempty"`
|
Main KeyValues `json:"main,omitempty"`
|
||||||
NamedSections map[string]map[string]string `json:"namedSections,omitempty"`
|
Sections []KeyValues `json:"sections,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m JavaManifest) Section(name string) KeyValues {
|
||||||
|
for _, section := range m.Sections {
|
||||||
|
if sectionName, ok := section.Get("Name"); ok && sectionName == name {
|
||||||
|
return section
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
28
syft/pkg/key_value.go
Normal file
28
syft/pkg/key_value.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package pkg
|
||||||
|
|
||||||
|
type KeyValue struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeyValues []KeyValue
|
||||||
|
|
||||||
|
func (k KeyValues) Get(key string) (string, bool) {
|
||||||
|
for _, kv := range k {
|
||||||
|
if kv.Key == key {
|
||||||
|
return kv.Value, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k KeyValues) MustGet(key string) string {
|
||||||
|
for _, kv := range k {
|
||||||
|
if kv.Key == key {
|
||||||
|
return kv.Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user