mirror of
https://github.com/anchore/syft.git
synced 2026-11-03 16:06:36 +01:00
migrate syft/cataloger to syft/pkg/cataloger
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
Package golang provides a concrete Cataloger implementation for go.mod files.
|
||||
*/
|
||||
package golang
|
||||
|
||||
import (
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/common"
|
||||
)
|
||||
|
||||
// NewGoModCataloger returns a new Go module cataloger object.
|
||||
func NewGoModCataloger() *common.GenericCataloger {
|
||||
globParsers := map[string]common.ParserFn{
|
||||
"**/go.mod": parseGoMod,
|
||||
}
|
||||
|
||||
return common.NewGenericCataloger(nil, globParsers, "go-cataloger")
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package golang
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"sort"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"golang.org/x/mod/modfile"
|
||||
)
|
||||
|
||||
// parseGoMod takes a go.mod and lists all packages discovered.
|
||||
func parseGoMod(path string, reader io.Reader) ([]pkg.Package, error) {
|
||||
packages := make(map[string]pkg.Package)
|
||||
|
||||
contents, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read go module: %w", err)
|
||||
}
|
||||
|
||||
file, err := modfile.Parse(path, contents, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse go module: %w", err)
|
||||
}
|
||||
|
||||
for _, m := range file.Require {
|
||||
packages[m.Mod.Path] = pkg.Package{
|
||||
Name: m.Mod.Path,
|
||||
Version: m.Mod.Version,
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
}
|
||||
}
|
||||
|
||||
// remove any old packages and replace with new ones...
|
||||
for _, m := range file.Replace {
|
||||
packages[m.New.Path] = pkg.Package{
|
||||
Name: m.New.Path,
|
||||
Version: m.New.Version,
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
}
|
||||
}
|
||||
|
||||
// remove any packages from the exclude fields
|
||||
for _, m := range file.Exclude {
|
||||
delete(packages, m.Mod.Path)
|
||||
}
|
||||
|
||||
pkgsSlice := make([]pkg.Package, len(packages))
|
||||
idx := 0
|
||||
for _, p := range packages {
|
||||
pkgsSlice[idx] = p
|
||||
idx++
|
||||
}
|
||||
|
||||
sort.SliceStable(pkgsSlice, func(i, j int) bool {
|
||||
return pkgsSlice[i].Name < pkgsSlice[j].Name
|
||||
})
|
||||
|
||||
return pkgsSlice, nil
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package golang
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/go-test/deep"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func TestParseGoMod(t *testing.T) {
|
||||
tests := []struct {
|
||||
fixture string
|
||||
expected map[string]pkg.Package
|
||||
}{
|
||||
{
|
||||
fixture: "test-fixtures/one-package",
|
||||
expected: map[string]pkg.Package{
|
||||
"github.com/bmatcuk/doublestar": {
|
||||
Name: "github.com/bmatcuk/doublestar",
|
||||
Version: "v1.3.1",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
fixture: "test-fixtures/many-packages",
|
||||
expected: map[string]pkg.Package{
|
||||
"github.com/anchore/go-testutils": {
|
||||
Name: "github.com/anchore/go-testutils",
|
||||
Version: "v0.0.0-20200624184116-66aa578126db",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
},
|
||||
"github.com/anchore/go-version": {
|
||||
Name: "github.com/anchore/go-version",
|
||||
Version: "v1.2.2-0.20200701162849-18adb9c92b9b",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
},
|
||||
"github.com/anchore/stereoscope": {
|
||||
Name: "github.com/anchore/stereoscope",
|
||||
Version: "v0.0.0-20200706164556-7cf39d7f4639",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
},
|
||||
"github.com/bmatcuk/doublestar": {
|
||||
Name: "github.com/bmatcuk/doublestar",
|
||||
Version: "v8.8.8",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
},
|
||||
"github.com/go-test/deep": {
|
||||
Name: "github.com/go-test/deep",
|
||||
Version: "v1.0.6",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.fixture, func(t *testing.T) {
|
||||
f, err := os.Open(test.fixture)
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
|
||||
actual, err := parseGoMod(test.fixture, f)
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
|
||||
if len(actual) != len(test.expected) {
|
||||
t.Fatalf("unexpected length: %d", len(actual))
|
||||
}
|
||||
|
||||
for _, a := range actual {
|
||||
e, ok := test.expected[a.Name]
|
||||
if !ok {
|
||||
t.Errorf("extra package: %s", a.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
diffs := deep.Equal(a, e)
|
||||
if len(diffs) > 0 {
|
||||
t.Errorf("diffs found for %q", a.Name)
|
||||
for _, d := range diffs {
|
||||
t.Errorf("diff: %+v", d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if t.Failed() {
|
||||
for _, a := range actual {
|
||||
t.Logf("Found: %+v", a)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
module (
|
||||
github.com/anchore/syft
|
||||
)
|
||||
|
||||
go 1.14
|
||||
|
||||
// github.com/bogus/package v10.10.10
|
||||
|
||||
require (
|
||||
github.com/adrg/xdg v0.2.1
|
||||
github.com/anchore/go-testutils v0.0.0-20200624184116-66aa578126db // github.com/bogus/package v10.10.10
|
||||
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b
|
||||
github.com/anchore/stereoscope v0.0.0-20200706164556-7cf39d7f4639
|
||||
//github.com/ignore/this v9.9.9 // indirect
|
||||
github.com/bmatcuk/doublestar v1.3.1 // indirect
|
||||
github.com/go-test/deep v1.0.6 // a comment
|
||||
)
|
||||
|
||||
replace github.com/bmatcuk/doublestar => github.com/bmatcuk/doublestar v8.8.8
|
||||
|
||||
exclude github.com/adrg/xdg v0.2.1
|
||||
@@ -0,0 +1,7 @@
|
||||
module github.com/anchore/syft
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/bmatcuk/doublestar v1.3.1
|
||||
)
|
||||
Reference in New Issue
Block a user