mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
port php cataloger to new generic cataloger pattern (#1315)
Signed-off-by: Alex Goodman <alex.goodman@anchore.com> Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
bc9740d50a
commit
891f2c576b
@ -4,23 +4,17 @@ Package php provides a concrete Cataloger implementation for PHP ecosystem files
|
||||
package php
|
||||
|
||||
import (
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/common"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
)
|
||||
|
||||
// NewPHPComposerInstalledCataloger returns a new cataloger for PHP installed.json files.
|
||||
func NewPHPComposerInstalledCataloger() *common.GenericCataloger {
|
||||
globParsers := map[string]common.ParserFn{
|
||||
"**/installed.json": parseInstalledJSON,
|
||||
}
|
||||
|
||||
return common.NewGenericCataloger(nil, globParsers, "php-composer-installed-cataloger")
|
||||
func NewPHPComposerInstalledCataloger() *generic.Cataloger {
|
||||
return generic.NewCataloger("php-composer-installed-cataloger").
|
||||
WithParserByGlobs(parseInstalledJSON, "**/installed.json")
|
||||
}
|
||||
|
||||
// NewPHPComposerLockCataloger returns a new cataloger for PHP composer.lock files.
|
||||
func NewPHPComposerLockCataloger() *common.GenericCataloger {
|
||||
globParsers := map[string]common.ParserFn{
|
||||
"**/composer.lock": parseComposerLock,
|
||||
}
|
||||
|
||||
return common.NewGenericCataloger(nil, globParsers, "php-composer-lock-cataloger")
|
||||
func NewPHPComposerLockCataloger() *generic.Cataloger {
|
||||
return generic.NewCataloger("php-composer-lock-cataloger").
|
||||
WithParserByGlobs(parseComposerLock, "**/composer.lock")
|
||||
}
|
||||
|
||||
51
syft/pkg/cataloger/php/package.go
Normal file
51
syft/pkg/cataloger/php/package.go
Normal file
@ -0,0 +1,51 @@
|
||||
package php
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
func newComposerLockPackage(m pkg.PhpComposerJSONMetadata, location ...source.Location) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: m.Name,
|
||||
Version: m.Version,
|
||||
Locations: source.NewLocationSet(location...),
|
||||
PURL: packageURL(m),
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: m,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
return p
|
||||
}
|
||||
|
||||
func packageURL(m pkg.PhpComposerJSONMetadata) string {
|
||||
var name, vendor string
|
||||
fields := strings.Split(m.Name, "/")
|
||||
switch len(fields) {
|
||||
case 0:
|
||||
return ""
|
||||
case 1:
|
||||
name = m.Name
|
||||
case 2:
|
||||
vendor = fields[0]
|
||||
name = fields[1]
|
||||
default:
|
||||
vendor = fields[0]
|
||||
name = strings.Join(fields[1:], "-")
|
||||
}
|
||||
|
||||
pURL := packageurl.NewPackageURL(
|
||||
packageurl.TypeComposer,
|
||||
vendor,
|
||||
name,
|
||||
m.Version,
|
||||
nil,
|
||||
"")
|
||||
return pURL.ToString()
|
||||
}
|
||||
53
syft/pkg/cataloger/php/package_test.go
Normal file
53
syft/pkg/cataloger/php/package_test.go
Normal file
@ -0,0 +1,53 @@
|
||||
package php
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/sergi/go-diff/diffmatchpatch"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func Test_packageURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
metadata pkg.PhpComposerJSONMetadata
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "with extractable vendor",
|
||||
metadata: pkg.PhpComposerJSONMetadata{
|
||||
Name: "ven/name",
|
||||
Version: "1.0.1",
|
||||
},
|
||||
expected: "pkg:composer/ven/name@1.0.1",
|
||||
},
|
||||
{
|
||||
name: "name with slashes (invalid)",
|
||||
metadata: pkg.PhpComposerJSONMetadata{
|
||||
Name: "ven/name/component",
|
||||
Version: "1.0.1",
|
||||
},
|
||||
expected: "pkg:composer/ven/name-component@1.0.1",
|
||||
},
|
||||
{
|
||||
name: "unknown vendor",
|
||||
metadata: pkg.PhpComposerJSONMetadata{
|
||||
Name: "name",
|
||||
Version: "1.0.1",
|
||||
},
|
||||
expected: "pkg:composer/name@1.0.1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
actual := packageURL(test.metadata)
|
||||
if actual != test.expected {
|
||||
dmp := diffmatchpatch.New()
|
||||
diffs := dmp.DiffMain(test.expected, actual, true)
|
||||
t.Errorf("diff: %s", dmp.DiffPrettyText(diffs))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -7,16 +7,20 @@ import (
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
var _ generic.Parser = parseComposerLock
|
||||
|
||||
type composerLock struct {
|
||||
Packages []pkg.PhpComposerJSONMetadata `json:"packages"`
|
||||
PackageDev []pkg.PhpComposerJSONMetadata `json:"packages-dev"`
|
||||
}
|
||||
|
||||
// parseComposerLock is a parser function for Composer.lock contents, returning "Default" php packages discovered.
|
||||
func parseComposerLock(_ string, reader io.Reader) ([]*pkg.Package, []artifact.Relationship, error) {
|
||||
packages := make([]*pkg.Package, 0)
|
||||
func parseComposerLock(_ source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
pkgs := make([]pkg.Package, 0)
|
||||
dec := json.NewDecoder(reader)
|
||||
|
||||
for {
|
||||
@ -26,19 +30,10 @@ func parseComposerLock(_ string, reader io.Reader) ([]*pkg.Package, []artifact.R
|
||||
} else if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to parse composer.lock file: %w", err)
|
||||
}
|
||||
for _, pkgMeta := range lock.Packages {
|
||||
version := pkgMeta.Version
|
||||
name := pkgMeta.Name
|
||||
packages = append(packages, &pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkgMeta,
|
||||
})
|
||||
for _, m := range lock.Packages {
|
||||
pkgs = append(pkgs, newComposerLockPackage(m, reader.Location))
|
||||
}
|
||||
}
|
||||
|
||||
return packages, nil, nil
|
||||
return pkgs, nil, nil
|
||||
}
|
||||
|
||||
@ -1,19 +1,24 @@
|
||||
package php
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/go-test/deep"
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
func TestParseComposerFileLock(t *testing.T) {
|
||||
expected := []*pkg.Package{
|
||||
var expectedRelationships []artifact.Relationship
|
||||
fixture := "test-fixtures/composer.lock"
|
||||
locations := source.NewLocationSet(source.NewLocation(fixture))
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "adoy/fastcgi-client",
|
||||
Version: "1.0.2",
|
||||
PURL: "pkg:composer/adoy/fastcgi-client@1.0.2",
|
||||
Locations: locations,
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
@ -52,6 +57,8 @@ func TestParseComposerFileLock(t *testing.T) {
|
||||
{
|
||||
Name: "alcaeus/mongo-php-adapter",
|
||||
Version: "1.1.11",
|
||||
Locations: locations,
|
||||
PURL: "pkg:composer/alcaeus/mongo-php-adapter@1.1.11",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
@ -106,18 +113,5 @@ func TestParseComposerFileLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
fixture, err := os.Open("test-fixtures/composer.lock")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open fixture: %+v", err)
|
||||
}
|
||||
|
||||
// TODO: no relationships are under test yet
|
||||
actual, _, err := parseComposerLock(fixture.Name(), fixture)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse requirements: %+v", err)
|
||||
}
|
||||
|
||||
for _, d := range deep.Equal(expected, actual) {
|
||||
t.Errorf("diff: %+v", d)
|
||||
}
|
||||
pkgtest.TestFileParser(t, fixture, parseComposerLock, expectedPkgs, expectedRelationships)
|
||||
}
|
||||
|
||||
@ -7,9 +7,12 @@ import (
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/common"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
var _ generic.Parser = parseComposerLock
|
||||
|
||||
// Note: composer version 2 introduced a new structure for the installed.json file, so we support both
|
||||
type installedJSONComposerV2 struct {
|
||||
Packages []pkg.PhpComposerJSONMetadata `json:"packages"`
|
||||
@ -36,12 +39,9 @@ func (w *installedJSONComposerV2) UnmarshalJSON(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// integrity check
|
||||
var _ common.ParserFn = parseComposerLock
|
||||
|
||||
// parseComposerLock is a parser function for Composer.lock contents, returning "Default" php packages discovered.
|
||||
func parseInstalledJSON(_ string, reader io.Reader) ([]*pkg.Package, []artifact.Relationship, error) {
|
||||
packages := make([]*pkg.Package, 0)
|
||||
// parseInstalledJSON is a parser function for Composer.lock contents, returning "Default" php packages discovered.
|
||||
func parseInstalledJSON(_ source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
var pkgs []pkg.Package
|
||||
dec := json.NewDecoder(reader)
|
||||
|
||||
for {
|
||||
@ -49,21 +49,12 @@ func parseInstalledJSON(_ string, reader io.Reader) ([]*pkg.Package, []artifact.
|
||||
if err := dec.Decode(&lock); err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to parse composer.lock file: %w", err)
|
||||
return nil, nil, fmt.Errorf("failed to parse installed.json file: %w", err)
|
||||
}
|
||||
for _, pkgMeta := range lock.Packages {
|
||||
version := pkgMeta.Version
|
||||
name := pkgMeta.Name
|
||||
packages = append(packages, &pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkgMeta,
|
||||
})
|
||||
pkgs = append(pkgs, newComposerLockPackage(pkgMeta, reader.Location))
|
||||
}
|
||||
}
|
||||
|
||||
return packages, nil, nil
|
||||
return pkgs, nil, nil
|
||||
}
|
||||
|
||||
@ -1,156 +1,141 @@
|
||||
package php
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/go-test/deep"
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
var expectedInstalledJsonPackages = []*pkg.Package{
|
||||
{
|
||||
Name: "asm89/stack-cors",
|
||||
Version: "1.3.0",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkg.PhpComposerJSONMetadata{
|
||||
Name: "asm89/stack-cors",
|
||||
Version: "1.3.0",
|
||||
Source: pkg.PhpComposerExternalReference{
|
||||
Type: "git",
|
||||
URL: "https://github.com/asm89/stack-cors.git",
|
||||
Reference: "b9c31def6a83f84b4d4a40d35996d375755f0e08",
|
||||
},
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
Type: "zip",
|
||||
URL: "https://api.github.com/repos/asm89/stack-cors/zipball/b9c31def6a83f84b4d4a40d35996d375755f0e08",
|
||||
Reference: "b9c31def6a83f84b4d4a40d35996d375755f0e08",
|
||||
},
|
||||
Require: map[string]string{
|
||||
"php": ">=5.5.9",
|
||||
"symfony/http-foundation": "~2.7|~3.0|~4.0|~5.0",
|
||||
"symfony/http-kernel": "~2.7|~3.0|~4.0|~5.0",
|
||||
},
|
||||
RequireDev: map[string]string{
|
||||
"phpunit/phpunit": "^5.0 || ^4.8.10",
|
||||
"squizlabs/php_codesniffer": "^2.3",
|
||||
},
|
||||
Time: "2019-12-24T22:41:47+00:00",
|
||||
Type: "library",
|
||||
NotificationURL: "https://packagist.org/downloads/",
|
||||
License: []string{
|
||||
"MIT",
|
||||
},
|
||||
Authors: []pkg.PhpComposerAuthors{
|
||||
{
|
||||
Name: "Alexander",
|
||||
Email: "iam.asm89@gmail.com",
|
||||
},
|
||||
},
|
||||
|
||||
Description: "Cross-origin resource sharing library and stack middleware",
|
||||
Homepage: "https://github.com/asm89/stack-cors",
|
||||
Keywords: []string{
|
||||
"cors",
|
||||
"stack",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "behat/mink",
|
||||
Version: "v1.8.1",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkg.PhpComposerJSONMetadata{
|
||||
Name: "behat/mink",
|
||||
Version: "v1.8.1",
|
||||
Source: pkg.PhpComposerExternalReference{
|
||||
Type: "git",
|
||||
URL: "https://github.com/minkphp/Mink.git",
|
||||
Reference: "07c6a9fe3fa98c2de074b25d9ed26c22904e3887",
|
||||
},
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
Type: "zip",
|
||||
URL: "https://api.github.com/repos/minkphp/Mink/zipball/07c6a9fe3fa98c2de074b25d9ed26c22904e3887",
|
||||
Reference: "07c6a9fe3fa98c2de074b25d9ed26c22904e3887",
|
||||
},
|
||||
Require: map[string]string{
|
||||
"php": ">=5.3.1",
|
||||
"symfony/css-selector": "^2.7|^3.0|^4.0|^5.0",
|
||||
},
|
||||
RequireDev: map[string]string{
|
||||
"phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20",
|
||||
"symfony/debug": "^2.7|^3.0|^4.0",
|
||||
"symfony/phpunit-bridge": "^3.4.38 || ^5.0.5",
|
||||
},
|
||||
Suggest: map[string]string{
|
||||
"behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)",
|
||||
"behat/mink-goutte-driver": "fast headless driver for any app without JS emulation",
|
||||
"behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)",
|
||||
"behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)",
|
||||
"dmore/chrome-mink-driver": "fast and JS-enabled driver for any app (requires chromium or google chrome)",
|
||||
},
|
||||
Time: "2020-03-11T15:45:53+00:00",
|
||||
Type: "library",
|
||||
NotificationURL: "https://packagist.org/downloads/",
|
||||
License: []string{
|
||||
"MIT",
|
||||
},
|
||||
Authors: []pkg.PhpComposerAuthors{
|
||||
{
|
||||
Name: "Konstantin Kudryashov",
|
||||
Email: "ever.zet@gmail.com",
|
||||
Homepage: "http://everzet.com",
|
||||
},
|
||||
},
|
||||
|
||||
Description: "Browser controller/emulator abstraction for PHP",
|
||||
Homepage: "http://mink.behat.org/",
|
||||
Keywords: []string{
|
||||
"browser",
|
||||
"testing",
|
||||
"web",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestParseInstalledJsonComposerV1(t *testing.T) {
|
||||
|
||||
fixture, err := os.Open("test-fixtures/vendor/composer_1/installed.json")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open fixture: %+v", err)
|
||||
fixtures := []string{
|
||||
"test-fixtures/vendor/composer_1/installed.json",
|
||||
"test-fixtures/vendor/composer_2/installed.json",
|
||||
}
|
||||
|
||||
// TODO: no relationships are under test yet
|
||||
actual, _, err := parseInstalledJSON(fixture.Name(), fixture)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse requirements: %+v", err)
|
||||
}
|
||||
differences := deep.Equal(expectedInstalledJsonPackages, actual)
|
||||
if differences != nil {
|
||||
t.Errorf("returned package list differed from expectation: %+v", differences)
|
||||
}
|
||||
}
|
||||
var expectedRelationships []artifact.Relationship
|
||||
var expectedPkgs = []pkg.Package{
|
||||
{
|
||||
Name: "asm89/stack-cors",
|
||||
Version: "1.3.0",
|
||||
PURL: "pkg:composer/asm89/stack-cors@1.3.0",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkg.PhpComposerJSONMetadata{
|
||||
Name: "asm89/stack-cors",
|
||||
Version: "1.3.0",
|
||||
Source: pkg.PhpComposerExternalReference{
|
||||
Type: "git",
|
||||
URL: "https://github.com/asm89/stack-cors.git",
|
||||
Reference: "b9c31def6a83f84b4d4a40d35996d375755f0e08",
|
||||
},
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
Type: "zip",
|
||||
URL: "https://api.github.com/repos/asm89/stack-cors/zipball/b9c31def6a83f84b4d4a40d35996d375755f0e08",
|
||||
Reference: "b9c31def6a83f84b4d4a40d35996d375755f0e08",
|
||||
},
|
||||
Require: map[string]string{
|
||||
"php": ">=5.5.9",
|
||||
"symfony/http-foundation": "~2.7|~3.0|~4.0|~5.0",
|
||||
"symfony/http-kernel": "~2.7|~3.0|~4.0|~5.0",
|
||||
},
|
||||
RequireDev: map[string]string{
|
||||
"phpunit/phpunit": "^5.0 || ^4.8.10",
|
||||
"squizlabs/php_codesniffer": "^2.3",
|
||||
},
|
||||
Time: "2019-12-24T22:41:47+00:00",
|
||||
Type: "library",
|
||||
NotificationURL: "https://packagist.org/downloads/",
|
||||
License: []string{
|
||||
"MIT",
|
||||
},
|
||||
Authors: []pkg.PhpComposerAuthors{
|
||||
{
|
||||
Name: "Alexander",
|
||||
Email: "iam.asm89@gmail.com",
|
||||
},
|
||||
},
|
||||
|
||||
func TestParseInstalledJsonComposerV2(t *testing.T) {
|
||||
fixture, err := os.Open("test-fixtures/vendor/composer_2/installed.json")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open fixture: %+v", err)
|
||||
Description: "Cross-origin resource sharing library and stack middleware",
|
||||
Homepage: "https://github.com/asm89/stack-cors",
|
||||
Keywords: []string{
|
||||
"cors",
|
||||
"stack",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "behat/mink",
|
||||
Version: "v1.8.1",
|
||||
PURL: "pkg:composer/behat/mink@v1.8.1",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkg.PhpComposerJSONMetadata{
|
||||
Name: "behat/mink",
|
||||
Version: "v1.8.1",
|
||||
Source: pkg.PhpComposerExternalReference{
|
||||
Type: "git",
|
||||
URL: "https://github.com/minkphp/Mink.git",
|
||||
Reference: "07c6a9fe3fa98c2de074b25d9ed26c22904e3887",
|
||||
},
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
Type: "zip",
|
||||
URL: "https://api.github.com/repos/minkphp/Mink/zipball/07c6a9fe3fa98c2de074b25d9ed26c22904e3887",
|
||||
Reference: "07c6a9fe3fa98c2de074b25d9ed26c22904e3887",
|
||||
},
|
||||
Require: map[string]string{
|
||||
"php": ">=5.3.1",
|
||||
"symfony/css-selector": "^2.7|^3.0|^4.0|^5.0",
|
||||
},
|
||||
RequireDev: map[string]string{
|
||||
"phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20",
|
||||
"symfony/debug": "^2.7|^3.0|^4.0",
|
||||
"symfony/phpunit-bridge": "^3.4.38 || ^5.0.5",
|
||||
},
|
||||
Suggest: map[string]string{
|
||||
"behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)",
|
||||
"behat/mink-goutte-driver": "fast headless driver for any app without JS emulation",
|
||||
"behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)",
|
||||
"behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)",
|
||||
"dmore/chrome-mink-driver": "fast and JS-enabled driver for any app (requires chromium or google chrome)",
|
||||
},
|
||||
Time: "2020-03-11T15:45:53+00:00",
|
||||
Type: "library",
|
||||
NotificationURL: "https://packagist.org/downloads/",
|
||||
License: []string{
|
||||
"MIT",
|
||||
},
|
||||
Authors: []pkg.PhpComposerAuthors{
|
||||
{
|
||||
Name: "Konstantin Kudryashov",
|
||||
Email: "ever.zet@gmail.com",
|
||||
Homepage: "http://everzet.com",
|
||||
},
|
||||
},
|
||||
|
||||
Description: "Browser controller/emulator abstraction for PHP",
|
||||
Homepage: "http://mink.behat.org/",
|
||||
Keywords: []string{
|
||||
"browser",
|
||||
"testing",
|
||||
"web",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// TODO: no relationships are under test yet
|
||||
actual, _, err := parseInstalledJSON(fixture.Name(), fixture)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse requirements: %+v", err)
|
||||
}
|
||||
differences := deep.Equal(expectedInstalledJsonPackages, actual)
|
||||
if differences != nil {
|
||||
t.Errorf("returned package list differed from expectation: %+v", differences)
|
||||
for _, fixture := range fixtures {
|
||||
t.Run(fixture, func(t *testing.T) {
|
||||
locations := source.NewLocationSet(source.NewLocation(fixture))
|
||||
for i := range expectedPkgs {
|
||||
expectedPkgs[i].Locations = locations
|
||||
}
|
||||
pkgtest.TestFileParser(t, fixture, parseInstalledJSON, expectedPkgs, expectedRelationships)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -77,19 +77,6 @@ func TestPackageURL(t *testing.T) {
|
||||
},
|
||||
expected: "pkg:cargo/name@v0.1.0",
|
||||
},
|
||||
{
|
||||
name: "php-composer",
|
||||
pkg: Package{
|
||||
Name: "bad-name",
|
||||
Version: "bad-v0.1.0",
|
||||
Type: PhpComposerPkg,
|
||||
Metadata: PhpComposerJSONMetadata{
|
||||
Name: "vendor/name",
|
||||
Version: "2.0.1",
|
||||
},
|
||||
},
|
||||
expected: "pkg:composer/vendor/name@2.0.1",
|
||||
},
|
||||
{
|
||||
name: "java",
|
||||
pkg: Package{
|
||||
@ -152,6 +139,7 @@ func TestPackageURL(t *testing.T) {
|
||||
expectedTypes.Remove(string(GoModulePkg))
|
||||
expectedTypes.Remove(string(HackagePkg))
|
||||
expectedTypes.Remove(string(BinaryPkg))
|
||||
expectedTypes.Remove(string(PhpComposerPkg))
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user