mirror of
https://github.com/anchore/syft
synced 2024-09-19 21:51:56 +00:00
Add the Ocaml ecosystem (#3112)
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
This commit is contained in:
parent
dafc6ad034
commit
9c2799e379
30 changed files with 3454 additions and 3 deletions
|
@ -410,6 +410,14 @@ var dirOnlyTestCases = []testCase{
|
||||||
"octo-org/this-repo/.github/workflows/workflow-1.yml": "172239021f7ba04fe7327647b213799853a9eb89",
|
"octo-org/this-repo/.github/workflows/workflow-1.yml": "172239021f7ba04fe7327647b213799853a9eb89",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "find opam package",
|
||||||
|
pkgType: pkg.OpamPkg,
|
||||||
|
pkgLanguage: pkg.OCaml,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"ocaml-base-compiler": "4.14.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var commonTestCases = []testCase{
|
var commonTestCases = []testCase{
|
||||||
|
|
|
@ -52,6 +52,7 @@ func TestPkgCoverageImage(t *testing.T) {
|
||||||
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.Swipl.String())
|
||||||
|
definedLanguages.Remove(pkg.OCaml.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())
|
||||||
|
@ -78,6 +79,7 @@ func TestPkgCoverageImage(t *testing.T) {
|
||||||
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.SwiplPackPkg))
|
||||||
|
definedPkgs.Remove(string(pkg.OpamPkg))
|
||||||
definedPkgs.Remove(string(pkg.GithubActionPkg))
|
definedPkgs.Remove(string(pkg.GithubActionPkg))
|
||||||
definedPkgs.Remove(string(pkg.GithubActionWorkflowPkg))
|
definedPkgs.Remove(string(pkg.GithubActionWorkflowPkg))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
opam-version: "2.0"
|
||||||
|
synopsis: "Official release 4.14.0"
|
||||||
|
maintainer: [
|
||||||
|
"David Allsopp <david@tarides.com>"
|
||||||
|
"Florian Angeletti <florian.angeletti@inria.fr>"
|
||||||
|
]
|
||||||
|
authors: "Xavier Leroy and many contributors"
|
||||||
|
license: "LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception"
|
||||||
|
homepage: "https://ocaml.org"
|
||||||
|
bug-reports: "https://github.com/ocaml/opam-repository/issues"
|
||||||
|
depends: [
|
||||||
|
"ocaml" {= "4.14.0" & post}
|
||||||
|
"base-unix" {post}
|
||||||
|
"base-bigarray" {post}
|
||||||
|
"base-threads" {post}
|
||||||
|
"host-arch-arm32" {arch = "arm32" & post}
|
||||||
|
"host-arch-arm64" {arch = "arm64" & post}
|
||||||
|
"host-arch-ppc64" {arch = "ppc64" & post}
|
||||||
|
"host-arch-riscv64" {arch = "riscv64" & post}
|
||||||
|
"host-arch-s390x" {arch = "s390x" & post}
|
||||||
|
"host-arch-x86_32" {os != "win32" & arch = "x86_32" & post}
|
||||||
|
"host-arch-x86_64" {os != "win32" & arch = "x86_64" & post}
|
||||||
|
"host-arch-unknown"
|
||||||
|
{os != "win32" & arch != "arm32" & arch != "arm64" & arch != "ppc64" &
|
||||||
|
arch != "riscv64" &
|
||||||
|
arch != "s390x" &
|
||||||
|
arch != "x86_32" &
|
||||||
|
arch != "x86_64" &
|
||||||
|
post}
|
||||||
|
(("arch-x86_64" {os = "win32" & arch = "x86_64"} &
|
||||||
|
(("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & post}) |
|
||||||
|
"system-msvc")) |
|
||||||
|
("arch-x86_32" {os = "win32"} &
|
||||||
|
(("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & post}) |
|
||||||
|
"system-msvc")) |
|
||||||
|
"host-system-other" {os != "win32" & post})
|
||||||
|
"ocaml-options-vanilla" {post}
|
||||||
|
"flexdll" {>= "0.36" & os = "win32"}
|
||||||
|
]
|
||||||
|
conflict-class: "ocaml-core-compiler"
|
||||||
|
flags: compiler
|
||||||
|
setenv: CAML_LD_LIBRARY_PATH = "%{lib}%/stublibs"
|
||||||
|
build: [
|
||||||
|
[
|
||||||
|
"./configure"
|
||||||
|
"--host=x86_64-pc-windows"
|
||||||
|
{system-msvc:installed & arch-x86_64:installed}
|
||||||
|
"--host=x86_64-w64-mingw32"
|
||||||
|
{os-distribution = "cygwin" & system-mingw:installed &
|
||||||
|
arch-x86_64:installed}
|
||||||
|
"--host=i686-pc-windows" {system-msvc:installed & arch-x86_32:installed}
|
||||||
|
"--host=i686-w64-mingw32"
|
||||||
|
{os-distribution = "cygwin" & system-mingw:installed &
|
||||||
|
arch-x86_32:installed}
|
||||||
|
"--prefix=%{prefix}%"
|
||||||
|
"--docdir=%{doc}%/ocaml"
|
||||||
|
"--with-flexdll=%{flexdll:share}%" {os = "win32" & flexdll:installed}
|
||||||
|
"-C"
|
||||||
|
"CC=cc" {os = "openbsd" | os = "macos"}
|
||||||
|
"ASPP=cc -c" {os = "openbsd" | os = "macos"}
|
||||||
|
]
|
||||||
|
[make "-j%{jobs}%"]
|
||||||
|
]
|
||||||
|
install: [make "install"]
|
||||||
|
build-env: MSYS2_ARG_CONV_EXCL = "*"
|
||||||
|
post-messages: [
|
||||||
|
"""\
|
||||||
|
A failure in the middle of the build may be caused by build parallelism
|
||||||
|
(enabled by default).
|
||||||
|
Please file a bug report at https://github.com/ocaml/opam-repository/issues"""
|
||||||
|
{failure & jobs > "1"}
|
||||||
|
"""\
|
||||||
|
You can try installing again including --jobs=1
|
||||||
|
to force a sequential build instead."""
|
||||||
|
{failure & jobs > "1" & opam-version >= "2.0.5"}
|
||||||
|
]
|
||||||
|
dev-repo: "git+https://github.com/ocaml/ocaml#4.14"
|
||||||
|
url {
|
||||||
|
src: "https://github.com/ocaml/ocaml/archive/4.14.0.tar.gz"
|
||||||
|
checksum:
|
||||||
|
"sha256=39f44260382f28d1054c5f9d8bf4753cb7ad64027da792f7938344544da155e8"
|
||||||
|
}
|
||||||
|
extra-source "ocaml-base-compiler.install" {
|
||||||
|
src:
|
||||||
|
"https://raw.githubusercontent.com/ocaml/opam-source-archives/main/patches/ocaml-base-compiler/ocaml-base-compiler.install"
|
||||||
|
checksum: [
|
||||||
|
"sha256=79f2a1a5044a91350a0eb6ce12e261a72a2855c094c425cddf3860e58c486678"
|
||||||
|
"md5=3e969b841df1f51ca448e6e6295cb451"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
x-env-path-rewrite: [
|
||||||
|
[CAML_LD_LIBRARY_PATH (";" {os = "win32"} ":" {os != "win32"}) "target"]
|
||||||
|
]
|
|
@ -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.15"
|
JSONSchemaVersion = "16.0.16"
|
||||||
)
|
)
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/kernel"
|
"github.com/anchore/syft/syft/pkg/cataloger/kernel"
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/lua"
|
"github.com/anchore/syft/syft/pkg/cataloger/lua"
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/nix"
|
"github.com/anchore/syft/syft/pkg/cataloger/nix"
|
||||||
|
"github.com/anchore/syft/syft/pkg/cataloger/ocaml"
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/php"
|
"github.com/anchore/syft/syft/pkg/cataloger/php"
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/python"
|
"github.com/anchore/syft/syft/pkg/cataloger/python"
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/r"
|
"github.com/anchore/syft/syft/pkg/cataloger/r"
|
||||||
|
@ -95,6 +96,7 @@ func DefaultPackageTaskFactories() PackageTaskFactories {
|
||||||
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"),
|
newSimplePackageTaskFactory(swipl.NewSwiplPackCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swipl", "pack"),
|
||||||
|
newSimplePackageTaskFactory(ocaml.NewOpamPackageManagerCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "ocaml", "opam"),
|
||||||
|
|
||||||
// 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"),
|
||||||
|
|
2629
schema/json/schema-16.0.16.json
Normal file
2629
schema/json/schema-16.0.16.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.15/document",
|
"$id": "anchore.io/schema/syft/json/16.0.16/document",
|
||||||
"$ref": "#/$defs/Document",
|
"$ref": "#/$defs/Document",
|
||||||
"$defs": {
|
"$defs": {
|
||||||
"AlpmDbEntry": {
|
"AlpmDbEntry": {
|
||||||
|
@ -1436,6 +1436,50 @@
|
||||||
"files"
|
"files"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"OpamPackage": {
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"licenses": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"checksum": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"homepage": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"version",
|
||||||
|
"licenses",
|
||||||
|
"url",
|
||||||
|
"checksum",
|
||||||
|
"homepage",
|
||||||
|
"dependencies"
|
||||||
|
]
|
||||||
|
},
|
||||||
"Package": {
|
"Package": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
|
@ -1563,6 +1607,9 @@
|
||||||
{
|
{
|
||||||
"$ref": "#/$defs/NixStoreEntry"
|
"$ref": "#/$defs/NixStoreEntry"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/OpamPackage"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"$ref": "#/$defs/PhpComposerInstalledEntry"
|
"$ref": "#/$defs/PhpComposerInstalledEntry"
|
||||||
},
|
},
|
||||||
|
|
|
@ -505,6 +505,14 @@ func toPackageChecksums(p pkg.Package) ([]spdx.Checksum, bool) {
|
||||||
Algorithm: spdx.ChecksumAlgorithm(algo),
|
Algorithm: spdx.ChecksumAlgorithm(algo),
|
||||||
Value: hexStr,
|
Value: hexStr,
|
||||||
})
|
})
|
||||||
|
case pkg.OpamPackage:
|
||||||
|
for _, checksum := range meta.Checksums {
|
||||||
|
parts := strings.Split(checksum, "=")
|
||||||
|
checksums = append(checksums, spdx.Checksum{
|
||||||
|
Algorithm: spdx.ChecksumAlgorithm(strings.ToUpper(parts[0])),
|
||||||
|
Value: parts[1],
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return checksums, filesAnalyzed
|
return checksums, filesAnalyzed
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,6 +335,31 @@ func Test_toPackageChecksums(t *testing.T) {
|
||||||
},
|
},
|
||||||
filesAnalyzed: false,
|
filesAnalyzed: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Opam Package",
|
||||||
|
pkg: pkg.Package{
|
||||||
|
Name: "test",
|
||||||
|
Version: "1.0.0",
|
||||||
|
Language: pkg.Go,
|
||||||
|
Metadata: pkg.OpamPackage{
|
||||||
|
Checksums: []string{
|
||||||
|
"sha256=f5f1c0b4ad2e0dfa6f79eaaaa3586411925c16f61702208ddd4bad2fc17dc47c",
|
||||||
|
"sha512=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []spdx.Checksum{
|
||||||
|
{
|
||||||
|
Algorithm: "SHA256",
|
||||||
|
Value: "f5f1c0b4ad2e0dfa6f79eaaaa3586411925c16f61702208ddd4bad2fc17dc47c",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Algorithm: "SHA512",
|
||||||
|
Value: "05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filesAnalyzed: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Package with no metadata type",
|
name: "Package with no metadata type",
|
||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
|
|
|
@ -26,6 +26,8 @@ func DownloadLocation(p pkg.Package) string {
|
||||||
return NoneIfEmpty(metadata.Dist.URL)
|
return NoneIfEmpty(metadata.Dist.URL)
|
||||||
case pkg.PhpComposerInstalledEntry:
|
case pkg.PhpComposerInstalledEntry:
|
||||||
return NoneIfEmpty(metadata.Dist.URL)
|
return NoneIfEmpty(metadata.Dist.URL)
|
||||||
|
case pkg.OpamPackage:
|
||||||
|
return NoneIfEmpty(metadata.URL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NOASSERTION
|
return NOASSERTION
|
||||||
|
|
|
@ -41,6 +41,7 @@ func Test_OriginatorSupplier(t *testing.T) {
|
||||||
pkg.RustCargoLockEntry{},
|
pkg.RustCargoLockEntry{},
|
||||||
pkg.SwiftPackageManagerResolvedEntry{},
|
pkg.SwiftPackageManagerResolvedEntry{},
|
||||||
pkg.SwiplPackEntry{},
|
pkg.SwiplPackEntry{},
|
||||||
|
pkg.OpamPackage{},
|
||||||
pkg.YarnLockEntry{},
|
pkg.YarnLockEntry{},
|
||||||
)
|
)
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -350,6 +351,14 @@ func Test_OriginatorSupplier(t *testing.T) {
|
||||||
originator: "Person: auth (auth@auth.gov)",
|
originator: "Person: auth (auth@auth.gov)",
|
||||||
supplier: "Person: me (me@auth.com)",
|
supplier: "Person: me (me@auth.com)",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "from ocaml opam",
|
||||||
|
input: pkg.Package{
|
||||||
|
Metadata: pkg.OpamPackage{},
|
||||||
|
},
|
||||||
|
originator: "",
|
||||||
|
supplier: "",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
|
|
@ -64,6 +64,8 @@ func SourceInfo(p pkg.Package) string {
|
||||||
answer = "acquired package info from resolved Swift package manifest"
|
answer = "acquired package info from resolved Swift package manifest"
|
||||||
case pkg.SwiplPackPkg:
|
case pkg.SwiplPackPkg:
|
||||||
answer = "acquired package info from SWI Prolo pack package file"
|
answer = "acquired package info from SWI Prolo pack package file"
|
||||||
|
case pkg.OpamPkg:
|
||||||
|
answer = "acquired package info from OCaml opam 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:
|
||||||
|
|
|
@ -271,6 +271,14 @@ func Test_SourceInfo(t *testing.T) {
|
||||||
"acquired package info from SWI Prolo pack package file",
|
"acquired package info from SWI Prolo pack package file",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
input: pkg.Package{
|
||||||
|
Type: pkg.OpamPkg,
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
"acquired package info from OCaml opam package file",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
input: pkg.Package{
|
input: pkg.Package{
|
||||||
Type: pkg.GithubActionPkg,
|
Type: pkg.GithubActionPkg,
|
||||||
|
|
|
@ -34,6 +34,7 @@ func AllTypes() []any {
|
||||||
pkg.NixStoreEntry{},
|
pkg.NixStoreEntry{},
|
||||||
pkg.NpmPackage{},
|
pkg.NpmPackage{},
|
||||||
pkg.NpmPackageLockEntry{},
|
pkg.NpmPackageLockEntry{},
|
||||||
|
pkg.OpamPackage{},
|
||||||
pkg.PhpComposerInstalledEntry{},
|
pkg.PhpComposerInstalledEntry{},
|
||||||
pkg.PhpComposerLockEntry{},
|
pkg.PhpComposerLockEntry{},
|
||||||
pkg.PhpPeclEntry{},
|
pkg.PhpPeclEntry{},
|
||||||
|
|
|
@ -103,6 +103,7 @@ var jsonTypes = makeJSONTypes(
|
||||||
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.SwiplPackEntry{}, "swiplpack-package"),
|
||||||
|
jsonNames(pkg.OpamPackage{}, "opam-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"),
|
||||||
|
|
15
syft/pkg/cataloger/ocaml/cataloger.go
Normal file
15
syft/pkg/cataloger/ocaml/cataloger.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
Package ocaml provides a concrete Cataloger implementation for packages relating to the OCaml language ecosystem.
|
||||||
|
*/
|
||||||
|
package ocaml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/anchore/syft/syft/pkg"
|
||||||
|
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewOpamPackageManagerCataloger returns a new cataloger object for OCaml opam.
|
||||||
|
func NewOpamPackageManagerCataloger() pkg.Cataloger {
|
||||||
|
return generic.NewCataloger("opam-cataloger").
|
||||||
|
WithParserByGlobs(parseOpamPackage, "*opam")
|
||||||
|
}
|
33
syft/pkg/cataloger/ocaml/cataloger_test.go
Normal file
33
syft/pkg/cataloger/ocaml/cataloger_test.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package ocaml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_PackageCataloger_Globs(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fixture string
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "obtain package files",
|
||||||
|
fixture: "test-fixtures/glob-paths",
|
||||||
|
expected: []string{
|
||||||
|
"opam/alcotest.opam",
|
||||||
|
"opam/ocaml-base-compiler.4.14.0/opam",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
pkgtest.NewCatalogTester().
|
||||||
|
FromDirectory(t, test.fixture).
|
||||||
|
ExpectsResolverContentQueries(test.expected).
|
||||||
|
TestCataloger(t, NewOpamPackageManagerCataloger())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
37
syft/pkg/cataloger/ocaml/package.go
Normal file
37
syft/pkg/cataloger/ocaml/package.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package ocaml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/anchore/packageurl-go"
|
||||||
|
"github.com/anchore/syft/syft/file"
|
||||||
|
"github.com/anchore/syft/syft/pkg"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newOpamPackage(m pkg.OpamPackage, fileLocation file.Location) pkg.Package {
|
||||||
|
p := pkg.Package{
|
||||||
|
Name: m.Name,
|
||||||
|
Version: m.Version,
|
||||||
|
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(fileLocation, m.Licenses...)...),
|
||||||
|
PURL: opamPackageURL(m.Name, m.Version),
|
||||||
|
Locations: file.NewLocationSet(fileLocation),
|
||||||
|
Type: pkg.OpamPkg,
|
||||||
|
Language: pkg.OCaml,
|
||||||
|
Metadata: m,
|
||||||
|
}
|
||||||
|
|
||||||
|
p.SetID()
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func opamPackageURL(name, version string) string {
|
||||||
|
var qualifiers packageurl.Qualifiers
|
||||||
|
|
||||||
|
return packageurl.NewPackageURL(
|
||||||
|
"opam",
|
||||||
|
"",
|
||||||
|
name,
|
||||||
|
version,
|
||||||
|
qualifiers,
|
||||||
|
"",
|
||||||
|
).ToString()
|
||||||
|
}
|
34
syft/pkg/cataloger/ocaml/package_test.go
Normal file
34
syft/pkg/cataloger/ocaml/package_test.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package ocaml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_packageURL(t *testing.T) {
|
||||||
|
|
||||||
|
type args struct {
|
||||||
|
name string
|
||||||
|
version string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "go case",
|
||||||
|
args: args{
|
||||||
|
name: "ocaml-base-compiler",
|
||||||
|
version: "5.2.0",
|
||||||
|
},
|
||||||
|
want: "pkg:opam/ocaml-base-compiler@5.2.0",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
assert.Equal(t, tt.want, opamPackageURL(tt.args.name, tt.args.version))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
150
syft/pkg/cataloger/ocaml/parse_opam.go
Normal file
150
syft/pkg/cataloger/ocaml/parse_opam.go
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
package ocaml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"path"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:funlen
|
||||||
|
func parseOpamPackage(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||||
|
var pkgs []pkg.Package
|
||||||
|
|
||||||
|
opamVersionRe := regexp.MustCompile(`(?m)opam-version:\s*"[0-9]+\.[0-9]+"`)
|
||||||
|
versionRe := regexp.MustCompile(`(?m)^version:\s*"(?P<version>[^"]*)"`)
|
||||||
|
licenseRe := regexp.MustCompile(`(?m)^license:\s*(?P<license>(?:"[^"]*")|(?:\[[^\]]*\]))`)
|
||||||
|
homepageRe := regexp.MustCompile(`(?m)homepage:\s*"(?P<url>[^"]+)"`)
|
||||||
|
urlRe := regexp.MustCompile(`(?m)url\s*{(?P<url>[^}]+)}`)
|
||||||
|
|
||||||
|
data, err := io.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields("error", err).Trace("unable to read opam package")
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if opamVersionRe.FindSubmatch(data) == nil {
|
||||||
|
log.WithFields("warning", err).Trace("opam version not found")
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If name is inferred from file name/path
|
||||||
|
var name, version string
|
||||||
|
var licenses []string
|
||||||
|
loc := reader.Location.LocationData.AccessPath
|
||||||
|
dir, file := path.Split(loc)
|
||||||
|
|
||||||
|
if file == "opam" {
|
||||||
|
// folder name is the package name and version
|
||||||
|
s := strings.SplitN(path.Base(dir), ".", 2)
|
||||||
|
name = s[0]
|
||||||
|
|
||||||
|
if len(s) > 1 {
|
||||||
|
version = s[1]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// filename is the package name and version is in the content
|
||||||
|
name = strings.Replace(file, ".opam", "", 1)
|
||||||
|
|
||||||
|
m := versionRe.FindSubmatch(data)
|
||||||
|
|
||||||
|
if m != nil {
|
||||||
|
version = string(m[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := pkg.OpamPackage{
|
||||||
|
Name: name,
|
||||||
|
Version: version,
|
||||||
|
}
|
||||||
|
|
||||||
|
licenseMatch := licenseRe.FindSubmatch(data)
|
||||||
|
if licenseMatch != nil {
|
||||||
|
licenses = parseLicenses(string(licenseMatch[1]))
|
||||||
|
|
||||||
|
entry.Licenses = licenses
|
||||||
|
}
|
||||||
|
|
||||||
|
urlMatch := urlRe.FindSubmatch(data)
|
||||||
|
if urlMatch != nil {
|
||||||
|
url, checksums := parseURL(urlMatch[1])
|
||||||
|
|
||||||
|
if url != "" {
|
||||||
|
entry.URL = url
|
||||||
|
}
|
||||||
|
|
||||||
|
if checksums != nil {
|
||||||
|
entry.Checksums = checksums
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
homepageMatch := homepageRe.FindSubmatch(data)
|
||||||
|
if homepageMatch != nil {
|
||||||
|
entry.Homepage = string(homepageMatch[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgs = append(
|
||||||
|
pkgs,
|
||||||
|
newOpamPackage(
|
||||||
|
entry,
|
||||||
|
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return pkgs, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseLicenses(licensesStr string) []string {
|
||||||
|
licenses := []string{}
|
||||||
|
|
||||||
|
if licensesStr[:1] == `"` {
|
||||||
|
content := licensesStr[1 : len(licensesStr)-1]
|
||||||
|
licenses = append(licenses, content)
|
||||||
|
} else {
|
||||||
|
var d []string
|
||||||
|
err := json.Unmarshal([]byte(licensesStr), &d)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
licenses = append(licenses, d...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return licenses
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseURL(data []byte) (string, []string) {
|
||||||
|
urlRe := regexp.MustCompile(`(?m)src:\s*"(?P<url>.*)"`)
|
||||||
|
checksumsRe := regexp.MustCompile(`(?m)checksum:\s*("[^"]*"|\[\s*((?:"[^"]*"\s*)+)\])`)
|
||||||
|
|
||||||
|
urlMatch := urlRe.FindSubmatch(data)
|
||||||
|
if urlMatch == nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
url := urlMatch[1]
|
||||||
|
|
||||||
|
var checksum []string
|
||||||
|
checksumMatch := checksumsRe.FindSubmatch(data)
|
||||||
|
if checksumMatch != nil {
|
||||||
|
var fields []string
|
||||||
|
if checksumMatch[2] != nil {
|
||||||
|
fields = strings.Fields(string(checksumMatch[2]))
|
||||||
|
} else {
|
||||||
|
fields = strings.Fields(string(checksumMatch[1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range fields {
|
||||||
|
checksum = append(checksum, strings.ReplaceAll(f, `"`, ""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(url), checksum
|
||||||
|
}
|
166
syft/pkg/cataloger/ocaml/parse_opam_test.go
Normal file
166
syft/pkg/cataloger/ocaml/parse_opam_test.go
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
package ocaml
|
||||||
|
|
||||||
|
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"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseOpamPackage(t *testing.T) {
|
||||||
|
fixture1 := "test-fixtures/ocaml-base-compiler.4.14.0/opam"
|
||||||
|
location1 := file.NewLocation(fixture1)
|
||||||
|
|
||||||
|
fixture2 := "test-fixtures/alcotest.opam"
|
||||||
|
location2 := file.NewLocation(fixture2)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
fixture string
|
||||||
|
want []pkg.Package
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
fixture: fixture1,
|
||||||
|
want: []pkg.Package{
|
||||||
|
{
|
||||||
|
Name: "ocaml-base-compiler",
|
||||||
|
Version: "4.14.0",
|
||||||
|
PURL: "pkg:opam/ocaml-base-compiler@4.14.0",
|
||||||
|
Locations: file.NewLocationSet(location1),
|
||||||
|
Licenses: pkg.NewLicenseSet(
|
||||||
|
pkg.NewLicensesFromLocation(
|
||||||
|
location1,
|
||||||
|
"LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception",
|
||||||
|
)...,
|
||||||
|
),
|
||||||
|
Language: pkg.OCaml,
|
||||||
|
Type: pkg.OpamPkg,
|
||||||
|
Metadata: pkg.OpamPackage{
|
||||||
|
Name: "ocaml-base-compiler",
|
||||||
|
Version: "4.14.0",
|
||||||
|
Licenses: []string{"LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception"},
|
||||||
|
URL: "https://github.com/ocaml/ocaml/archive/4.14.0.tar.gz",
|
||||||
|
Checksums: []string{
|
||||||
|
"sha256=39f44260382f28d1054c5f9d8bf4753cb7ad64027da792f7938344544da155e8",
|
||||||
|
},
|
||||||
|
Homepage: "https://ocaml.org",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fixture: fixture2,
|
||||||
|
want: []pkg.Package{
|
||||||
|
{
|
||||||
|
Name: "alcotest",
|
||||||
|
Version: "1.5.0",
|
||||||
|
PURL: "pkg:opam/alcotest@1.5.0",
|
||||||
|
Locations: file.NewLocationSet(location2),
|
||||||
|
Licenses: pkg.NewLicenseSet(
|
||||||
|
pkg.NewLicensesFromLocation(
|
||||||
|
location2,
|
||||||
|
"ISC",
|
||||||
|
)...,
|
||||||
|
),
|
||||||
|
Language: pkg.OCaml,
|
||||||
|
Type: pkg.OpamPkg,
|
||||||
|
Metadata: pkg.OpamPackage{
|
||||||
|
Name: "alcotest",
|
||||||
|
Version: "1.5.0",
|
||||||
|
Licenses: []string{"ISC"},
|
||||||
|
Homepage: "https://github.com/mirage/alcotest",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.fixture, func(t *testing.T) {
|
||||||
|
// TODO: no relationships are under test yet
|
||||||
|
var expectedRelationships []artifact.Relationship
|
||||||
|
|
||||||
|
pkgtest.TestFileParser(t, tt.fixture, parseOpamPackage, tt.want, expectedRelationships)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseLicense(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "single license",
|
||||||
|
input: `"MIT"`,
|
||||||
|
want: []string{
|
||||||
|
"MIT",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple license",
|
||||||
|
input: `[
|
||||||
|
"MIT", "IST"
|
||||||
|
]`,
|
||||||
|
want: []string{
|
||||||
|
"MIT",
|
||||||
|
"IST",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
assert.Equal(t, tt.want, parseLicenses(tt.input))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseUrl(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
wantUrl string
|
||||||
|
wantChecksums []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "single checksums",
|
||||||
|
input: `
|
||||||
|
src:
|
||||||
|
"https://github.com/mirage/mirage-clock/releases/download/v4.2.0/mirage-clock-4.2.0.tbz"
|
||||||
|
checksum:
|
||||||
|
"sha256=fa17d15d5be23c79ba741f5f7cb88ed7112de16a4410cea81c71b98086889847"
|
||||||
|
`,
|
||||||
|
wantUrl: "https://github.com/mirage/mirage-clock/releases/download/v4.2.0/mirage-clock-4.2.0.tbz",
|
||||||
|
wantChecksums: []string{
|
||||||
|
"sha256=fa17d15d5be23c79ba741f5f7cb88ed7112de16a4410cea81c71b98086889847",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple checksums",
|
||||||
|
input: `
|
||||||
|
src:
|
||||||
|
"https://github.com/mirage/mirage-clock/releases/download/v4.2.0/mirage-clock-4.2.0.tbz"
|
||||||
|
checksum: [
|
||||||
|
"sha256=fa17d15d5be23c79ba741f5f7cb88ed7112de16a4410cea81c71b98086889847"
|
||||||
|
"sha512=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b"
|
||||||
|
"sha1024=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b"
|
||||||
|
]
|
||||||
|
`,
|
||||||
|
wantUrl: "https://github.com/mirage/mirage-clock/releases/download/v4.2.0/mirage-clock-4.2.0.tbz",
|
||||||
|
wantChecksums: []string{
|
||||||
|
"sha256=fa17d15d5be23c79ba741f5f7cb88ed7112de16a4410cea81c71b98086889847",
|
||||||
|
"sha512=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b",
|
||||||
|
"sha1024=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
url, checksums := parseURL([]byte(tt.input))
|
||||||
|
assert.Equal(t, tt.wantUrl, url)
|
||||||
|
assert.Equal(t, tt.wantChecksums, checksums)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
51
syft/pkg/cataloger/ocaml/test-fixtures/alcotest.opam
Normal file
51
syft/pkg/cataloger/ocaml/test-fixtures/alcotest.opam
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
version: "1.5.0"
|
||||||
|
# This file is generated by dune, edit dune-project instead
|
||||||
|
opam-version: "2.0"
|
||||||
|
synopsis: "Alcotest is a lightweight and colourful test framework"
|
||||||
|
description: """
|
||||||
|
Alcotest exposes simple interface to perform unit tests. It exposes
|
||||||
|
a simple TESTABLE module type, a check function to assert test
|
||||||
|
predicates and a run function to perform a list of unit -> unit
|
||||||
|
test callbacks.
|
||||||
|
|
||||||
|
Alcotest provides a quiet and colorful output where only faulty runs
|
||||||
|
are fully displayed at the end of the run (with the full logs ready to
|
||||||
|
inspect), with a simple (yet expressive) query language to select the
|
||||||
|
tests to run.
|
||||||
|
"""
|
||||||
|
maintainer: ["thomas@gazagnaire.org"]
|
||||||
|
authors: ["Thomas Gazagnaire"]
|
||||||
|
license: "ISC"
|
||||||
|
homepage: "https://github.com/mirage/alcotest"
|
||||||
|
doc: "https://mirage.github.io/alcotest"
|
||||||
|
bug-reports: "https://github.com/mirage/alcotest/issues"
|
||||||
|
depends: [
|
||||||
|
"dune" {>= "2.8"}
|
||||||
|
"ocaml" {>= "4.03.0"}
|
||||||
|
"fmt" {>= "0.8.7"}
|
||||||
|
"astring"
|
||||||
|
"cmdliner" {>= "1.0.0"}
|
||||||
|
"re"
|
||||||
|
"stdlib-shims"
|
||||||
|
"uutf"
|
||||||
|
"ocaml-syntax-shims"
|
||||||
|
"odoc" {with-doc}
|
||||||
|
]
|
||||||
|
conflicts: [
|
||||||
|
"result" {< "1.5"}
|
||||||
|
]
|
||||||
|
build: [
|
||||||
|
["dune" "subst"] {dev}
|
||||||
|
[
|
||||||
|
"dune"
|
||||||
|
"build"
|
||||||
|
"-p"
|
||||||
|
name
|
||||||
|
"-j"
|
||||||
|
jobs
|
||||||
|
"@install"
|
||||||
|
"@runtest" {with-test}
|
||||||
|
"@doc" {with-doc}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
dev-repo: "git+https://github.com/mirage/alcotest.git"
|
|
@ -0,0 +1 @@
|
||||||
|
bogus
|
|
@ -0,0 +1 @@
|
||||||
|
bogus
|
|
@ -0,0 +1,93 @@
|
||||||
|
opam-version: "2.0"
|
||||||
|
synopsis: "Official release 4.14.0"
|
||||||
|
maintainer: [
|
||||||
|
"David Allsopp <david@tarides.com>"
|
||||||
|
"Florian Angeletti <florian.angeletti@inria.fr>"
|
||||||
|
]
|
||||||
|
authors: "Xavier Leroy and many contributors"
|
||||||
|
license: "LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception"
|
||||||
|
homepage: "https://ocaml.org"
|
||||||
|
bug-reports: "https://github.com/ocaml/opam-repository/issues"
|
||||||
|
depends: [
|
||||||
|
"ocaml" {= "4.14.0" & post}
|
||||||
|
"base-unix" {post}
|
||||||
|
"base-bigarray" {post}
|
||||||
|
"base-threads" {post}
|
||||||
|
"host-arch-arm32" {arch = "arm32" & post}
|
||||||
|
"host-arch-arm64" {arch = "arm64" & post}
|
||||||
|
"host-arch-ppc64" {arch = "ppc64" & post}
|
||||||
|
"host-arch-riscv64" {arch = "riscv64" & post}
|
||||||
|
"host-arch-s390x" {arch = "s390x" & post}
|
||||||
|
"host-arch-x86_32" {os != "win32" & arch = "x86_32" & post}
|
||||||
|
"host-arch-x86_64" {os != "win32" & arch = "x86_64" & post}
|
||||||
|
"host-arch-unknown"
|
||||||
|
{os != "win32" & arch != "arm32" & arch != "arm64" & arch != "ppc64" &
|
||||||
|
arch != "riscv64" &
|
||||||
|
arch != "s390x" &
|
||||||
|
arch != "x86_32" &
|
||||||
|
arch != "x86_64" &
|
||||||
|
post}
|
||||||
|
(("arch-x86_64" {os = "win32" & arch = "x86_64"} &
|
||||||
|
(("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & post}) |
|
||||||
|
"system-msvc")) |
|
||||||
|
("arch-x86_32" {os = "win32"} &
|
||||||
|
(("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & post}) |
|
||||||
|
"system-msvc")) |
|
||||||
|
"host-system-other" {os != "win32" & post})
|
||||||
|
"ocaml-options-vanilla" {post}
|
||||||
|
"flexdll" {>= "0.36" & os = "win32"}
|
||||||
|
]
|
||||||
|
conflict-class: "ocaml-core-compiler"
|
||||||
|
flags: compiler
|
||||||
|
setenv: CAML_LD_LIBRARY_PATH = "%{lib}%/stublibs"
|
||||||
|
build: [
|
||||||
|
[
|
||||||
|
"./configure"
|
||||||
|
"--host=x86_64-pc-windows"
|
||||||
|
{system-msvc:installed & arch-x86_64:installed}
|
||||||
|
"--host=x86_64-w64-mingw32"
|
||||||
|
{os-distribution = "cygwin" & system-mingw:installed &
|
||||||
|
arch-x86_64:installed}
|
||||||
|
"--host=i686-pc-windows" {system-msvc:installed & arch-x86_32:installed}
|
||||||
|
"--host=i686-w64-mingw32"
|
||||||
|
{os-distribution = "cygwin" & system-mingw:installed &
|
||||||
|
arch-x86_32:installed}
|
||||||
|
"--prefix=%{prefix}%"
|
||||||
|
"--docdir=%{doc}%/ocaml"
|
||||||
|
"--with-flexdll=%{flexdll:share}%" {os = "win32" & flexdll:installed}
|
||||||
|
"-C"
|
||||||
|
"CC=cc" {os = "openbsd" | os = "macos"}
|
||||||
|
"ASPP=cc -c" {os = "openbsd" | os = "macos"}
|
||||||
|
]
|
||||||
|
[make "-j%{jobs}%"]
|
||||||
|
]
|
||||||
|
install: [make "install"]
|
||||||
|
build-env: MSYS2_ARG_CONV_EXCL = "*"
|
||||||
|
post-messages: [
|
||||||
|
"""\
|
||||||
|
A failure in the middle of the build may be caused by build parallelism
|
||||||
|
(enabled by default).
|
||||||
|
Please file a bug report at https://github.com/ocaml/opam-repository/issues"""
|
||||||
|
{failure & jobs > "1"}
|
||||||
|
"""\
|
||||||
|
You can try installing again including --jobs=1
|
||||||
|
to force a sequential build instead."""
|
||||||
|
{failure & jobs > "1" & opam-version >= "2.0.5"}
|
||||||
|
]
|
||||||
|
dev-repo: "git+https://github.com/ocaml/ocaml#4.14"
|
||||||
|
url {
|
||||||
|
src: "https://github.com/ocaml/ocaml/archive/4.14.0.tar.gz"
|
||||||
|
checksum:
|
||||||
|
"sha256=39f44260382f28d1054c5f9d8bf4753cb7ad64027da792f7938344544da155e8"
|
||||||
|
}
|
||||||
|
extra-source "ocaml-base-compiler.install" {
|
||||||
|
src:
|
||||||
|
"https://raw.githubusercontent.com/ocaml/opam-source-archives/main/patches/ocaml-base-compiler/ocaml-base-compiler.install"
|
||||||
|
checksum: [
|
||||||
|
"sha256=79f2a1a5044a91350a0eb6ce12e261a72a2855c094c425cddf3860e58c486678"
|
||||||
|
"md5=3e969b841df1f51ca448e6e6295cb451"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
x-env-path-rewrite: [
|
||||||
|
[CAML_LD_LIBRARY_PATH (";" {os = "win32"} ":" {os != "win32"}) "target"]
|
||||||
|
]
|
|
@ -22,6 +22,7 @@ const (
|
||||||
Java Language = "java"
|
Java Language = "java"
|
||||||
JavaScript Language = "javascript"
|
JavaScript Language = "javascript"
|
||||||
Lua Language = "lua"
|
Lua Language = "lua"
|
||||||
|
OCaml Language = "ocaml"
|
||||||
PHP Language = "php"
|
PHP Language = "php"
|
||||||
Python Language = "python"
|
Python Language = "python"
|
||||||
R Language = "R"
|
R Language = "R"
|
||||||
|
@ -43,6 +44,7 @@ var AllLanguages = []Language{
|
||||||
Java,
|
Java,
|
||||||
JavaScript,
|
JavaScript,
|
||||||
Lua,
|
Lua,
|
||||||
|
OCaml,
|
||||||
PHP,
|
PHP,
|
||||||
Python,
|
Python,
|
||||||
R,
|
R,
|
||||||
|
@ -92,6 +94,8 @@ func LanguageByName(name string) Language {
|
||||||
return Swift
|
return Swift
|
||||||
case "swipl", string(SwiplPackPkg):
|
case "swipl", string(SwiplPackPkg):
|
||||||
return Swipl
|
return Swipl
|
||||||
|
case "ocaml", string(OpamPkg):
|
||||||
|
return OCaml
|
||||||
case packageurl.TypeConan, string(CPP):
|
case packageurl.TypeConan, string(CPP):
|
||||||
return CPP
|
return CPP
|
||||||
case packageurl.TypeHackage, string(Haskell):
|
case packageurl.TypeHackage, string(Haskell):
|
||||||
|
|
|
@ -86,6 +86,10 @@ func TestLanguageFromPURL(t *testing.T) {
|
||||||
purl: "pkg:luarocks/kong@3.7.0",
|
purl: "pkg:luarocks/kong@3.7.0",
|
||||||
want: Lua,
|
want: Lua,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
purl: "pkg:opam/ocaml-base-compiler@ 5.2.0",
|
||||||
|
want: OCaml,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var languages = strset.New()
|
var languages = strset.New()
|
||||||
|
@ -227,6 +231,10 @@ func TestLanguageByName(t *testing.T) {
|
||||||
name: "swiplpack",
|
name: "swiplpack",
|
||||||
language: Swipl,
|
language: Swipl,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "opam",
|
||||||
|
language: OCaml,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "pod",
|
name: "pod",
|
||||||
language: Swift,
|
language: Swift,
|
||||||
|
|
11
syft/pkg/ocaml.go
Normal file
11
syft/pkg/ocaml.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package pkg
|
||||||
|
|
||||||
|
type OpamPackage struct {
|
||||||
|
Name string `toml:"name" json:"name"`
|
||||||
|
Version string `toml:"version" json:"version"`
|
||||||
|
Licenses []string `mapstructure:"licenses" json:"licenses"`
|
||||||
|
URL string `mapstructure:"url" json:"url"`
|
||||||
|
Checksums []string `mapstructure:"checksums" json:"checksum"`
|
||||||
|
Homepage string `json:"homepage"`
|
||||||
|
Dependencies []string `toml:"dependencies" json:"dependencies"`
|
||||||
|
}
|
|
@ -43,6 +43,7 @@ const (
|
||||||
RustPkg Type = "rust-crate"
|
RustPkg Type = "rust-crate"
|
||||||
SwiftPkg Type = "swift"
|
SwiftPkg Type = "swift"
|
||||||
SwiplPackPkg Type = "swiplpack"
|
SwiplPackPkg Type = "swiplpack"
|
||||||
|
OpamPkg Type = "opam"
|
||||||
WordpressPluginPkg Type = "wordpress-plugin"
|
WordpressPluginPkg Type = "wordpress-plugin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -80,12 +81,13 @@ var AllPkgs = []Type{
|
||||||
RustPkg,
|
RustPkg,
|
||||||
SwiftPkg,
|
SwiftPkg,
|
||||||
SwiplPackPkg,
|
SwiplPackPkg,
|
||||||
|
OpamPkg,
|
||||||
WordpressPluginPkg,
|
WordpressPluginPkg,
|
||||||
}
|
}
|
||||||
|
|
||||||
// PackageURLType returns the PURL package type for the current package.
|
// PackageURLType returns the PURL package type for the current package.
|
||||||
//
|
//
|
||||||
//nolint:funlen
|
//nolint:funlen, gocyclo
|
||||||
func (t Type) PackageURLType() string {
|
func (t Type) PackageURLType() string {
|
||||||
switch t {
|
switch t {
|
||||||
case AlpmPkg:
|
case AlpmPkg:
|
||||||
|
@ -145,6 +147,8 @@ func (t Type) PackageURLType() string {
|
||||||
return packageurl.TypeSwift
|
return packageurl.TypeSwift
|
||||||
case SwiplPackPkg:
|
case SwiplPackPkg:
|
||||||
return "swiplpack"
|
return "swiplpack"
|
||||||
|
case OpamPkg:
|
||||||
|
return "opam"
|
||||||
case WordpressPluginPkg:
|
case WordpressPluginPkg:
|
||||||
return "wordpress-plugin"
|
return "wordpress-plugin"
|
||||||
default:
|
default:
|
||||||
|
@ -223,6 +227,8 @@ func TypeByName(name string) Type {
|
||||||
return SwiftPkg
|
return SwiftPkg
|
||||||
case "swiplpack":
|
case "swiplpack":
|
||||||
return SwiplPackPkg
|
return SwiplPackPkg
|
||||||
|
case "opam":
|
||||||
|
return OpamPkg
|
||||||
case "wordpress-plugin":
|
case "wordpress-plugin":
|
||||||
return WordpressPluginPkg
|
return WordpressPluginPkg
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -115,6 +115,10 @@ func TestTypeFromPURL(t *testing.T) {
|
||||||
purl: "pkg:swiplpack/condition@0.1.1",
|
purl: "pkg:swiplpack/condition@0.1.1",
|
||||||
expected: SwiplPackPkg,
|
expected: SwiplPackPkg,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
purl: "pkg:opam/ocaml-base-compiler@5.2.0",
|
||||||
|
expected: OpamPkg,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var pkgTypes []string
|
var pkgTypes []string
|
||||||
|
|
Loading…
Reference in a new issue