mirror of
https://github.com/anchore/syft
synced 2024-11-10 06:14:16 +00:00
Added the SWI Prolog (swipl) ecosystem (#3076)
* Add binary classifier for swipl Signed-off-by: Laurent Goderre <laurent.goderre@docker.com> * Added cataloger for SWI Prolog Pack packages Signed-off-by: Laurent Goderre <laurent.goderre@docker.com> --------- Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
This commit is contained in:
parent
a4b5dcd0df
commit
92d63df6f5
32 changed files with 2992 additions and 8 deletions
|
@ -388,6 +388,14 @@ var dirOnlyTestCases = []testCase{
|
||||||
"swift-numerics": "1.0.2",
|
"swift-numerics": "1.0.2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "find swipl pack package manager packages",
|
||||||
|
pkgType: pkg.SwiplPackPkg,
|
||||||
|
pkgLanguage: pkg.Swipl,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"hdt": "0.5.2",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "find github action packages (from usage in workflow files and composite actions)",
|
name: "find github action packages (from usage in workflow files and composite actions)",
|
||||||
pkgType: pkg.GithubActionPkg,
|
pkgType: pkg.GithubActionPkg,
|
||||||
|
|
|
@ -51,6 +51,7 @@ func TestPkgCoverageImage(t *testing.T) {
|
||||||
definedLanguages.Remove(pkg.Rust.String())
|
definedLanguages.Remove(pkg.Rust.String())
|
||||||
definedLanguages.Remove(pkg.Dart.String())
|
definedLanguages.Remove(pkg.Dart.String())
|
||||||
definedLanguages.Remove(pkg.Swift.String())
|
definedLanguages.Remove(pkg.Swift.String())
|
||||||
|
definedLanguages.Remove(pkg.Swipl.String())
|
||||||
definedLanguages.Remove(pkg.CPP.String())
|
definedLanguages.Remove(pkg.CPP.String())
|
||||||
definedLanguages.Remove(pkg.Haskell.String())
|
definedLanguages.Remove(pkg.Haskell.String())
|
||||||
definedLanguages.Remove(pkg.Elixir.String())
|
definedLanguages.Remove(pkg.Elixir.String())
|
||||||
|
@ -76,6 +77,7 @@ func TestPkgCoverageImage(t *testing.T) {
|
||||||
definedPkgs.Remove(string(pkg.LinuxKernelPkg))
|
definedPkgs.Remove(string(pkg.LinuxKernelPkg))
|
||||||
definedPkgs.Remove(string(pkg.LinuxKernelModulePkg))
|
definedPkgs.Remove(string(pkg.LinuxKernelModulePkg))
|
||||||
definedPkgs.Remove(string(pkg.SwiftPkg))
|
definedPkgs.Remove(string(pkg.SwiftPkg))
|
||||||
|
definedPkgs.Remove(string(pkg.SwiplPackPkg))
|
||||||
definedPkgs.Remove(string(pkg.GithubActionPkg))
|
definedPkgs.Remove(string(pkg.GithubActionPkg))
|
||||||
definedPkgs.Remove(string(pkg.GithubActionWorkflowPkg))
|
definedPkgs.Remove(string(pkg.GithubActionWorkflowPkg))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
name(hdt).
|
||||||
|
version('0.5.2').
|
||||||
|
% TODO: swipl_version([90121]).
|
||||||
|
title('Access RDF HDT files').
|
||||||
|
keywords(['RDF']).
|
||||||
|
author( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ).
|
||||||
|
packager( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ).
|
||||||
|
maintainer( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ).
|
||||||
|
home( 'https://github.com/JanWielemaker/hdt' ).
|
||||||
|
download( 'https://github.com/JanWielemaker/hdt/archive/V*.zip' ).
|
|
@ -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 = "16.0.14"
|
JSONSchemaVersion = "16.0.15"
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/rust"
|
"github.com/anchore/syft/syft/pkg/cataloger/rust"
|
||||||
sbomCataloger "github.com/anchore/syft/syft/pkg/cataloger/sbom"
|
sbomCataloger "github.com/anchore/syft/syft/pkg/cataloger/sbom"
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/swift"
|
"github.com/anchore/syft/syft/pkg/cataloger/swift"
|
||||||
|
"github.com/anchore/syft/syft/pkg/cataloger/swipl"
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/wordpress"
|
"github.com/anchore/syft/syft/pkg/cataloger/wordpress"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -93,6 +94,7 @@ func DefaultPackageTaskFactories() PackageTaskFactories {
|
||||||
newSimplePackageTaskFactory(rust.NewCargoLockCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "rust", "cargo"),
|
newSimplePackageTaskFactory(rust.NewCargoLockCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "rust", "cargo"),
|
||||||
newSimplePackageTaskFactory(swift.NewCocoapodsCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swift", "cocoapods"),
|
newSimplePackageTaskFactory(swift.NewCocoapodsCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swift", "cocoapods"),
|
||||||
newSimplePackageTaskFactory(swift.NewSwiftPackageManagerCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swift", "spm"),
|
newSimplePackageTaskFactory(swift.NewSwiftPackageManagerCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swift", "spm"),
|
||||||
|
newSimplePackageTaskFactory(swipl.NewSwiplPackCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swipl", "pack"),
|
||||||
|
|
||||||
// language-specific package for both image and directory scans (but not necessarily declared) ////////////////////////////////////////
|
// language-specific package for both image and directory scans (but not necessarily declared) ////////////////////////////////////////
|
||||||
newSimplePackageTaskFactory(dotnet.NewDotnetPortableExecutableCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "dotnet", "c#", "binary"),
|
newSimplePackageTaskFactory(dotnet.NewDotnetPortableExecutableCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "dotnet", "c#", "binary"),
|
||||||
|
|
2582
schema/json/schema-16.0.15.json
Normal file
2582
schema/json/schema-16.0.15.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
"$id": "anchore.io/schema/syft/json/16.0.14/document",
|
"$id": "anchore.io/schema/syft/json/16.0.15/document",
|
||||||
"$ref": "#/$defs/Document",
|
"$ref": "#/$defs/Document",
|
||||||
"$defs": {
|
"$defs": {
|
||||||
"AlpmDbEntry": {
|
"AlpmDbEntry": {
|
||||||
|
@ -1608,6 +1608,9 @@
|
||||||
{
|
{
|
||||||
"$ref": "#/$defs/SwiftPackageManagerLockEntry"
|
"$ref": "#/$defs/SwiftPackageManagerLockEntry"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/SwiplpackPackage"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"$ref": "#/$defs/WordpressPluginEntry"
|
"$ref": "#/$defs/WordpressPluginEntry"
|
||||||
}
|
}
|
||||||
|
@ -2504,6 +2507,48 @@
|
||||||
"revision"
|
"revision"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"SwiplpackPackage": {
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"author": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"authorEmail": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"packager": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"packagerEmail": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"homepage": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"version",
|
||||||
|
"author",
|
||||||
|
"authorEmail",
|
||||||
|
"packager",
|
||||||
|
"packagerEmail",
|
||||||
|
"homepage",
|
||||||
|
"dependencies"
|
||||||
|
]
|
||||||
|
},
|
||||||
"WordpressPluginEntry": {
|
"WordpressPluginEntry": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"pluginInstallDirectory": {
|
"pluginInstallDirectory": {
|
||||||
|
|
|
@ -103,6 +103,8 @@ func Originator(p pkg.Package) (typ string, author string) { // nolint: funlen
|
||||||
// it seems that the vast majority of the time the author is an org, not a person
|
// it seems that the vast majority of the time the author is an org, not a person
|
||||||
typ = orgType
|
typ = orgType
|
||||||
author = metadata.Author
|
author = metadata.Author
|
||||||
|
case pkg.SwiplPackEntry:
|
||||||
|
author = formatPersonOrOrg(metadata.Author, metadata.AuthorEmail)
|
||||||
}
|
}
|
||||||
|
|
||||||
if typ == "" && author != "" {
|
if typ == "" && author != "" {
|
||||||
|
@ -144,6 +146,10 @@ func Supplier(p pkg.Package) (typ string, author string) {
|
||||||
author = metadata.Packager
|
author = metadata.Packager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if metadata, ok := p.Metadata.(pkg.SwiplPackEntry); ok {
|
||||||
|
author = formatPersonOrOrg(metadata.Packager, metadata.PackagerEmail)
|
||||||
|
}
|
||||||
|
|
||||||
if author == "" {
|
if author == "" {
|
||||||
// TODO: this uses the Originator function for now until a better distinction can be made for supplier
|
// TODO: this uses the Originator function for now until a better distinction can be made for supplier
|
||||||
return Originator(p)
|
return Originator(p)
|
||||||
|
|
|
@ -40,6 +40,7 @@ func Test_OriginatorSupplier(t *testing.T) {
|
||||||
pkg.RustBinaryAuditEntry{},
|
pkg.RustBinaryAuditEntry{},
|
||||||
pkg.RustCargoLockEntry{},
|
pkg.RustCargoLockEntry{},
|
||||||
pkg.SwiftPackageManagerResolvedEntry{},
|
pkg.SwiftPackageManagerResolvedEntry{},
|
||||||
|
pkg.SwiplPackEntry{},
|
||||||
pkg.YarnLockEntry{},
|
pkg.YarnLockEntry{},
|
||||||
)
|
)
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -336,6 +337,19 @@ func Test_OriginatorSupplier(t *testing.T) {
|
||||||
originator: "Organization: auth",
|
originator: "Organization: auth",
|
||||||
supplier: "Organization: auth",
|
supplier: "Organization: auth",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "from swipl pack",
|
||||||
|
input: pkg.Package{
|
||||||
|
Metadata: pkg.SwiplPackEntry{
|
||||||
|
Author: "auth",
|
||||||
|
AuthorEmail: "auth@auth.gov",
|
||||||
|
Packager: "me",
|
||||||
|
PackagerEmail: "me@auth.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
originator: "Person: auth (auth@auth.gov)",
|
||||||
|
supplier: "Person: me (me@auth.com)",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
|
|
@ -62,6 +62,8 @@ func SourceInfo(p pkg.Package) string {
|
||||||
answer = "acquired package info from Rockspec package file"
|
answer = "acquired package info from Rockspec package file"
|
||||||
case pkg.SwiftPkg:
|
case pkg.SwiftPkg:
|
||||||
answer = "acquired package info from resolved Swift package manifest"
|
answer = "acquired package info from resolved Swift package manifest"
|
||||||
|
case pkg.SwiplPackPkg:
|
||||||
|
answer = "acquired package info from SWI Prolo pack package file"
|
||||||
case pkg.GithubActionPkg, pkg.GithubActionWorkflowPkg:
|
case pkg.GithubActionPkg, pkg.GithubActionWorkflowPkg:
|
||||||
answer = "acquired package info from GitHub Actions workflow file or composite action file"
|
answer = "acquired package info from GitHub Actions workflow file or composite action file"
|
||||||
case pkg.WordpressPluginPkg:
|
case pkg.WordpressPluginPkg:
|
||||||
|
|
|
@ -263,6 +263,14 @@ func Test_SourceInfo(t *testing.T) {
|
||||||
"from resolved Swift package manifest",
|
"from resolved Swift package manifest",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
input: pkg.Package{
|
||||||
|
Type: pkg.SwiplPackPkg,
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
"acquired package info from SWI Prolo pack package file",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
input: pkg.Package{
|
input: pkg.Package{
|
||||||
Type: pkg.GithubActionPkg,
|
Type: pkg.GithubActionPkg,
|
||||||
|
|
|
@ -49,6 +49,7 @@ func AllTypes() []any {
|
||||||
pkg.RustBinaryAuditEntry{},
|
pkg.RustBinaryAuditEntry{},
|
||||||
pkg.RustCargoLockEntry{},
|
pkg.RustCargoLockEntry{},
|
||||||
pkg.SwiftPackageManagerResolvedEntry{},
|
pkg.SwiftPackageManagerResolvedEntry{},
|
||||||
|
pkg.SwiplPackEntry{},
|
||||||
pkg.WordpressPluginEntry{},
|
pkg.WordpressPluginEntry{},
|
||||||
pkg.YarnLockEntry{},
|
pkg.YarnLockEntry{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,7 @@ var jsonTypes = makeJSONTypes(
|
||||||
jsonNames(pkg.RpmDBEntry{}, "rpm-db-entry", "RpmMetadata", "RpmdbMetadata"),
|
jsonNames(pkg.RpmDBEntry{}, "rpm-db-entry", "RpmMetadata", "RpmdbMetadata"),
|
||||||
jsonNamesWithoutLookup(pkg.RpmArchive{}, "rpm-archive", "RpmMetadata"), // the legacy value is split into two types, where the other is preferred
|
jsonNamesWithoutLookup(pkg.RpmArchive{}, "rpm-archive", "RpmMetadata"), // the legacy value is split into two types, where the other is preferred
|
||||||
jsonNames(pkg.SwiftPackageManagerResolvedEntry{}, "swift-package-manager-lock-entry", "SwiftPackageManagerMetadata"),
|
jsonNames(pkg.SwiftPackageManagerResolvedEntry{}, "swift-package-manager-lock-entry", "SwiftPackageManagerMetadata"),
|
||||||
|
jsonNames(pkg.SwiplPackEntry{}, "swiplpack-package"),
|
||||||
jsonNames(pkg.RustCargoLockEntry{}, "rust-cargo-lock-entry", "RustCargoPackageMetadata"),
|
jsonNames(pkg.RustCargoLockEntry{}, "rust-cargo-lock-entry", "RustCargoPackageMetadata"),
|
||||||
jsonNamesWithoutLookup(pkg.RustBinaryAuditEntry{}, "rust-cargo-audit-entry", "RustCargoPackageMetadata"), // the legacy value is split into two types, where the other is preferred
|
jsonNamesWithoutLookup(pkg.RustBinaryAuditEntry{}, "rust-cargo-audit-entry", "RustCargoPackageMetadata"), // the legacy value is split into two types, where the other is preferred
|
||||||
jsonNames(pkg.WordpressPluginEntry{}, "wordpress-plugin-entry", "WordpressMetadata"),
|
jsonNames(pkg.WordpressPluginEntry{}, "wordpress-plugin-entry", "WordpressMetadata"),
|
||||||
|
|
|
@ -473,12 +473,6 @@ func Test_JSONName_JSONLegacyName(t *testing.T) {
|
||||||
expectedJSONName: "rpm-archive",
|
expectedJSONName: "rpm-archive",
|
||||||
expectedLegacyName: "RpmMetadata", // note: conflicts with <=v11.x schema for "rpm-db-entry" metadata type
|
expectedLegacyName: "RpmMetadata", // note: conflicts with <=v11.x schema for "rpm-db-entry" metadata type
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "SwiftPackageManagerMetadata",
|
|
||||||
metadata: pkg.SwiftPackageManagerResolvedEntry{},
|
|
||||||
expectedJSONName: "swift-package-manager-lock-entry",
|
|
||||||
expectedLegacyName: "SwiftPackageManagerMetadata",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "CargoPackageMetadata",
|
name: "CargoPackageMetadata",
|
||||||
metadata: pkg.RustCargoLockEntry{},
|
metadata: pkg.RustCargoLockEntry{},
|
||||||
|
|
|
@ -929,6 +929,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||||
Metadata: metadata("erlang-alpine-binary"),
|
Metadata: metadata("erlang-alpine-binary"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
logicalFixture: "swipl/9.3.8/linux-amd64",
|
||||||
|
expected: pkg.Package{
|
||||||
|
Name: "swipl",
|
||||||
|
Version: "9.3.8",
|
||||||
|
Type: "binary",
|
||||||
|
PURL: "pkg:generic/swipl@9.3.8",
|
||||||
|
Locations: locations("swipl"),
|
||||||
|
Metadata: metadata("swipl-binary"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
logicalFixture: "nginx/1.25.1/linux-amd64",
|
logicalFixture: "nginx/1.25.1/linux-amd64",
|
||||||
expected: pkg.Package{
|
expected: pkg.Package{
|
||||||
|
|
|
@ -428,6 +428,16 @@ func DefaultClassifiers() []Classifier {
|
||||||
PURL: mustPURL("pkg:generic/erlang@version"),
|
PURL: mustPURL("pkg:generic/erlang@version"),
|
||||||
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"),
|
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Class: "swipl-binary",
|
||||||
|
FileGlob: "**/swipl",
|
||||||
|
EvidenceMatcher: FileContentsVersionMatcher(
|
||||||
|
`(?m)swipl-(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\/`,
|
||||||
|
),
|
||||||
|
Package: "swipl",
|
||||||
|
PURL: mustPURL("pkg:generic/swipl@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Class: "consul-binary",
|
Class: "consul-binary",
|
||||||
FileGlob: "**/consul",
|
FileGlob: "**/consul",
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
name: beam.smp
|
||||||
|
offset: 6378906
|
||||||
|
length: 140
|
||||||
|
snippetSha256: 186c882decc4160bfcfbdddaee08e8364675c795d3e85697422fbd7218452ee2
|
||||||
|
fileSha256: f84f0ffc2e397abcf5f081b865e241017b1793c2ec38f5136bff4e5e21ffdad7
|
||||||
|
|
||||||
|
### byte snippet to follow ###
|
||||||
|
ied by configure */
|
||||||
|
#define ERTS_EMU_CMDLINE_FLAGS " -fno-strict-aliasing -fno-common -g -O2 -I/usr/src/otp_src_27.0/erts/x86_64-pc-linux-mu
|
Binary file not shown.
|
@ -71,6 +71,13 @@ from-images:
|
||||||
paths:
|
paths:
|
||||||
- /usr/local/lib/erlang/erts-15.0/bin/beam.smp
|
- /usr/local/lib/erlang/erts-15.0/bin/beam.smp
|
||||||
|
|
||||||
|
- version: 9.3.8
|
||||||
|
images:
|
||||||
|
- ref: swipl:9.3.8@sha256:6a15e6a03afe943228924a5502ba763e653ff28d9b3391e2b3e1fc3e991f37d4
|
||||||
|
platform: linux/amd64
|
||||||
|
paths:
|
||||||
|
- /usr/lib/swipl/bin/x86_64-linux/swipl
|
||||||
|
|
||||||
- version: 1.21.3
|
- version: 1.21.3
|
||||||
images:
|
images:
|
||||||
- ref: golang:1.21.3@sha256:3ce8313c3513515040870c55e0c041a2b94f3576a58cfd3948633604214aa811
|
- ref: golang:1.21.3@sha256:3ce8313c3513515040870c55e0c041a2b94f3576a58cfd3948633604214aa811
|
||||||
|
|
15
syft/pkg/cataloger/swipl/cataloger.go
Normal file
15
syft/pkg/cataloger/swipl/cataloger.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
Package swipl provides a Cataloger implementation relating to packages within the SWI Prolog language ecosystem.
|
||||||
|
*/
|
||||||
|
package swipl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/anchore/syft/syft/pkg"
|
||||||
|
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewSwiplPackCataloger returns a new SWI Prolog Pack package manager cataloger object.
|
||||||
|
func NewSwiplPackCataloger() pkg.Cataloger {
|
||||||
|
return generic.NewCataloger("swipl-pack-cataloger").
|
||||||
|
WithParserByGlobs(parsePackPackage, "**/pack.pl")
|
||||||
|
}
|
32
syft/pkg/cataloger/swipl/cataloger_test.go
Normal file
32
syft/pkg/cataloger/swipl/cataloger_test.go
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
package swipl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_Cataloger_Globs(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fixture string
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "obtain swipl pack files",
|
||||||
|
fixture: "test-fixtures/glob-paths",
|
||||||
|
expected: []string{
|
||||||
|
"pack.pl",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
pkgtest.NewCatalogTester().
|
||||||
|
FromDirectory(t, test.fixture).
|
||||||
|
ExpectsResolverContentQueries(test.expected).
|
||||||
|
TestCataloger(t, NewSwiplPackCataloger())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
38
syft/pkg/cataloger/swipl/package.go
Normal file
38
syft/pkg/cataloger/swipl/package.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package swipl
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "strings"
|
||||||
|
|
||||||
|
"github.com/anchore/packageurl-go"
|
||||||
|
"github.com/anchore/syft/syft/file"
|
||||||
|
"github.com/anchore/syft/syft/pkg"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newSwiplPackPackage(m pkg.SwiplPackEntry, locations ...file.Location) pkg.Package {
|
||||||
|
p := pkg.Package{
|
||||||
|
Name: m.Name,
|
||||||
|
Version: m.Version,
|
||||||
|
PURL: swiplpackPackageURL(m.Name, m.Version),
|
||||||
|
Locations: file.NewLocationSet(locations...),
|
||||||
|
Type: pkg.SwiplPackPkg,
|
||||||
|
Language: pkg.Swipl,
|
||||||
|
Metadata: m,
|
||||||
|
}
|
||||||
|
|
||||||
|
p.SetID()
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func swiplpackPackageURL(name, version string) string {
|
||||||
|
var qualifiers packageurl.Qualifiers
|
||||||
|
|
||||||
|
return packageurl.NewPackageURL(
|
||||||
|
"swiplpack",
|
||||||
|
"",
|
||||||
|
name,
|
||||||
|
version,
|
||||||
|
qualifiers,
|
||||||
|
"",
|
||||||
|
).ToString()
|
||||||
|
}
|
33
syft/pkg/cataloger/swipl/package_test.go
Normal file
33
syft/pkg/cataloger/swipl/package_test.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package swipl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_swiplpackPackageURL(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
name string
|
||||||
|
version string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "go case",
|
||||||
|
args: args{
|
||||||
|
name: "name",
|
||||||
|
version: "v0.1.0",
|
||||||
|
},
|
||||||
|
want: "pkg:swiplpack/name@v0.1.0",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
assert.Equal(t, tt.want, swiplpackPackageURL(tt.args.name, tt.args.version))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
70
syft/pkg/cataloger/swipl/parse_pack.go
Normal file
70
syft/pkg/cataloger/swipl/parse_pack.go
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package swipl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/internal/log"
|
||||||
|
"github.com/anchore/syft/syft/artifact"
|
||||||
|
"github.com/anchore/syft/syft/file"
|
||||||
|
"github.com/anchore/syft/syft/pkg"
|
||||||
|
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parsePackPackage(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||||
|
var pkgs []pkg.Package
|
||||||
|
|
||||||
|
nameRe := regexp.MustCompile(`name\(\s*'?([^')]+)'?\s*\)`)
|
||||||
|
versionRe := regexp.MustCompile(`version\('([^']+)'\)`)
|
||||||
|
homeRe := regexp.MustCompile(`home\(\s*'([^']+)'\s*\)`)
|
||||||
|
authorRe := regexp.MustCompile(`(author|packager)\(\s*'([^']+)'\s*(?:,\s*'([^']+)'\s*)?\)`)
|
||||||
|
|
||||||
|
data, err := io.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields("error", err).Trace("unable to parse Rockspec app")
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
name := nameRe.FindSubmatch(data)
|
||||||
|
version := versionRe.FindSubmatch(data)
|
||||||
|
|
||||||
|
if name == nil || version == nil {
|
||||||
|
log.Debugf("encountered pack.pl file without a name and/or version field, ignoring (path=%q)", reader.Path())
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := pkg.SwiplPackEntry{
|
||||||
|
Name: string(name[1]),
|
||||||
|
Version: string(version[1]),
|
||||||
|
}
|
||||||
|
|
||||||
|
home := homeRe.FindSubmatch(data)
|
||||||
|
|
||||||
|
if home != nil {
|
||||||
|
entry.Homepage = string(home[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
authors := authorRe.FindAllSubmatch(data, -1)
|
||||||
|
|
||||||
|
for _, a := range authors {
|
||||||
|
switch string(a[1]) {
|
||||||
|
case "author":
|
||||||
|
entry.Author = string(a[2])
|
||||||
|
entry.AuthorEmail = string(a[3])
|
||||||
|
case "packager":
|
||||||
|
entry.Packager = string(a[2])
|
||||||
|
entry.PackagerEmail = string(a[3])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgs = append(
|
||||||
|
pkgs,
|
||||||
|
newSwiplPackPackage(
|
||||||
|
entry,
|
||||||
|
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return pkgs, nil, nil
|
||||||
|
}
|
39
syft/pkg/cataloger/swipl/parse_pack_test.go
Normal file
39
syft/pkg/cataloger/swipl/parse_pack_test.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package swipl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/syft/artifact"
|
||||||
|
"github.com/anchore/syft/syft/file"
|
||||||
|
"github.com/anchore/syft/syft/pkg"
|
||||||
|
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParsePackPackage(t *testing.T) {
|
||||||
|
fixture := "test-fixtures/pack.pl"
|
||||||
|
locations := file.NewLocationSet(file.NewLocation(fixture))
|
||||||
|
expectedPkgs := []pkg.Package{
|
||||||
|
{
|
||||||
|
Name: "hdt",
|
||||||
|
Version: "0.5.2",
|
||||||
|
PURL: "pkg:swiplpack/hdt@0.5.2",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Swipl,
|
||||||
|
Type: pkg.SwiplPackPkg,
|
||||||
|
Metadata: pkg.SwiplPackEntry{
|
||||||
|
Name: "hdt",
|
||||||
|
Version: "0.5.2",
|
||||||
|
Author: "Jan Wielemaker",
|
||||||
|
AuthorEmail: "J.Wielemaker@vu.nl",
|
||||||
|
Packager: "Jan Wielemaker",
|
||||||
|
PackagerEmail: "J.Wielemaker@vu.nl",
|
||||||
|
Homepage: "https://github.com/JanWielemaker/hdt",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: no relationships are under test yet
|
||||||
|
var expectedRelationships []artifact.Relationship
|
||||||
|
|
||||||
|
pkgtest.TestFileParser(t, fixture, parsePackPackage, expectedPkgs, expectedRelationships)
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
bogus
|
10
syft/pkg/cataloger/swipl/test-fixtures/pack.pl
Normal file
10
syft/pkg/cataloger/swipl/test-fixtures/pack.pl
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
name(hdt).
|
||||||
|
version('0.5.2').
|
||||||
|
% TODO: swipl_version([90121]).
|
||||||
|
title('Access RDF HDT files').
|
||||||
|
keywords(['RDF']).
|
||||||
|
author( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ).
|
||||||
|
packager( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ).
|
||||||
|
maintainer( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ).
|
||||||
|
home( 'https://github.com/JanWielemaker/hdt' ).
|
||||||
|
download( 'https://github.com/JanWielemaker/hdt/archive/V*.zip' ).
|
|
@ -28,6 +28,7 @@ const (
|
||||||
Ruby Language = "ruby"
|
Ruby Language = "ruby"
|
||||||
Rust Language = "rust"
|
Rust Language = "rust"
|
||||||
Swift Language = "swift"
|
Swift Language = "swift"
|
||||||
|
Swipl Language = "swipl"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AllLanguages is a set of all programming languages detected by syft.
|
// AllLanguages is a set of all programming languages detected by syft.
|
||||||
|
@ -48,6 +49,7 @@ var AllLanguages = []Language{
|
||||||
Ruby,
|
Ruby,
|
||||||
Rust,
|
Rust,
|
||||||
Swift,
|
Swift,
|
||||||
|
Swipl,
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string representation of the language.
|
// String returns the string representation of the language.
|
||||||
|
@ -88,6 +90,8 @@ func LanguageByName(name string) Language {
|
||||||
return Dotnet
|
return Dotnet
|
||||||
case packageurl.TypeCocoapods, packageurl.TypeSwift, string(CocoapodsPkg):
|
case packageurl.TypeCocoapods, packageurl.TypeSwift, string(CocoapodsPkg):
|
||||||
return Swift
|
return Swift
|
||||||
|
case "swipl", string(SwiplPackPkg):
|
||||||
|
return Swipl
|
||||||
case packageurl.TypeConan, string(CPP):
|
case packageurl.TypeConan, string(CPP):
|
||||||
return CPP
|
return CPP
|
||||||
case packageurl.TypeHackage, string(Haskell):
|
case packageurl.TypeHackage, string(Haskell):
|
||||||
|
|
|
@ -78,6 +78,10 @@ func TestLanguageFromPURL(t *testing.T) {
|
||||||
purl: "pkg:swift/github.com/apple/swift-numerics/swift-numerics@1.0.2",
|
purl: "pkg:swift/github.com/apple/swift-numerics/swift-numerics@1.0.2",
|
||||||
want: Swift,
|
want: Swift,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
purl: "pkg:swiplpack/conditon@0.1.1",
|
||||||
|
want: Swipl,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
purl: "pkg:luarocks/kong@3.7.0",
|
purl: "pkg:luarocks/kong@3.7.0",
|
||||||
want: Lua,
|
want: Lua,
|
||||||
|
@ -219,6 +223,10 @@ func TestLanguageByName(t *testing.T) {
|
||||||
name: "swift",
|
name: "swift",
|
||||||
language: Swift,
|
language: Swift,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "swiplpack",
|
||||||
|
language: Swipl,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "pod",
|
name: "pod",
|
||||||
language: Swift,
|
language: Swift,
|
||||||
|
|
12
syft/pkg/swipl.go
Normal file
12
syft/pkg/swipl.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package pkg
|
||||||
|
|
||||||
|
type SwiplPackEntry struct {
|
||||||
|
Name string `toml:"name" json:"name"`
|
||||||
|
Version string `toml:"version" json:"version"`
|
||||||
|
Author string `json:"author" mapstruct:"Author"`
|
||||||
|
AuthorEmail string `json:"authorEmail" mapstruct:"Authoremail"`
|
||||||
|
Packager string `json:"packager" mapstructure:"Packager"`
|
||||||
|
PackagerEmail string `json:"packagerEmail" mapstruct:"Packageremail"`
|
||||||
|
Homepage string `json:"homepage"`
|
||||||
|
Dependencies []string `toml:"dependencies" json:"dependencies"`
|
||||||
|
}
|
|
@ -42,6 +42,7 @@ const (
|
||||||
RpmPkg Type = "rpm"
|
RpmPkg Type = "rpm"
|
||||||
RustPkg Type = "rust-crate"
|
RustPkg Type = "rust-crate"
|
||||||
SwiftPkg Type = "swift"
|
SwiftPkg Type = "swift"
|
||||||
|
SwiplPackPkg Type = "swiplpack"
|
||||||
WordpressPluginPkg Type = "wordpress-plugin"
|
WordpressPluginPkg Type = "wordpress-plugin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -78,6 +79,7 @@ var AllPkgs = []Type{
|
||||||
RpmPkg,
|
RpmPkg,
|
||||||
RustPkg,
|
RustPkg,
|
||||||
SwiftPkg,
|
SwiftPkg,
|
||||||
|
SwiplPackPkg,
|
||||||
WordpressPluginPkg,
|
WordpressPluginPkg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +143,8 @@ func (t Type) PackageURLType() string {
|
||||||
return "cargo"
|
return "cargo"
|
||||||
case SwiftPkg:
|
case SwiftPkg:
|
||||||
return packageurl.TypeSwift
|
return packageurl.TypeSwift
|
||||||
|
case SwiplPackPkg:
|
||||||
|
return "swiplpack"
|
||||||
case WordpressPluginPkg:
|
case WordpressPluginPkg:
|
||||||
return "wordpress-plugin"
|
return "wordpress-plugin"
|
||||||
default:
|
default:
|
||||||
|
@ -217,6 +221,8 @@ func TypeByName(name string) Type {
|
||||||
return Rpkg
|
return Rpkg
|
||||||
case packageurl.TypeSwift:
|
case packageurl.TypeSwift:
|
||||||
return SwiftPkg
|
return SwiftPkg
|
||||||
|
case "swiplpack":
|
||||||
|
return SwiplPackPkg
|
||||||
case "wordpress-plugin":
|
case "wordpress-plugin":
|
||||||
return WordpressPluginPkg
|
return WordpressPluginPkg
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -111,6 +111,10 @@ func TestTypeFromPURL(t *testing.T) {
|
||||||
purl: "pkg:swift/github.com/apple/swift-numerics/swift-numerics@1.0.2",
|
purl: "pkg:swift/github.com/apple/swift-numerics/swift-numerics@1.0.2",
|
||||||
expected: SwiftPkg,
|
expected: SwiftPkg,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
purl: "pkg:swiplpack/condition@0.1.1",
|
||||||
|
expected: SwiplPackPkg,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var pkgTypes []string
|
var pkgTypes []string
|
||||||
|
|
Loading…
Reference in a new issue