mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
fix: golang remote license search not executing when error reading local mod dir (#3549)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
This commit is contained in:
parent
2a8c8ac832
commit
a2a56dd3e9
@ -80,29 +80,38 @@ func remotesForModule(proxies []string, noProxy []string, module string) []strin
|
|||||||
return proxies
|
return proxies
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *goLicenseResolver) getLicenses(ctx context.Context, scanner licenses.Scanner, resolver file.Resolver, moduleName, moduleVersion string) ([]pkg.License, error) {
|
func (c *goLicenseResolver) getLicenses(ctx context.Context, scanner licenses.Scanner, resolver file.Resolver, moduleName, moduleVersion string) []pkg.License {
|
||||||
// search the scan target first, ignoring local and remote sources
|
// search the scan target first, ignoring local and remote sources
|
||||||
goLicenses, err := c.findLicensesInSource(ctx, scanner, resolver,
|
goLicenses, err := c.findLicensesInSource(ctx, scanner, resolver,
|
||||||
fmt.Sprintf(`**/go/pkg/mod/%s@%s/*`, processCaps(moduleName), moduleVersion),
|
fmt.Sprintf(`**/go/pkg/mod/%s@%s/*`, processCaps(moduleName), moduleVersion),
|
||||||
)
|
)
|
||||||
if err != nil || len(goLicenses) > 0 {
|
if err != nil {
|
||||||
return toPkgLicenses(goLicenses), err
|
log.WithFields("error", err, "module", moduleName, "version", moduleVersion).Trace("unable to read golang licenses from source")
|
||||||
|
}
|
||||||
|
if len(goLicenses) > 0 {
|
||||||
|
return toPkgLicenses(goLicenses)
|
||||||
}
|
}
|
||||||
|
|
||||||
// look in the local host mod directory...
|
// look in the local host mod directory...
|
||||||
if c.opts.SearchLocalModCacheLicenses {
|
if c.opts.SearchLocalModCacheLicenses {
|
||||||
goLicenses, err = c.getLicensesFromLocal(ctx, scanner, moduleName, moduleVersion)
|
goLicenses, err = c.getLicensesFromLocal(ctx, scanner, moduleName, moduleVersion)
|
||||||
if err != nil || len(goLicenses) > 0 {
|
if err != nil {
|
||||||
return toPkgLicenses(goLicenses), err
|
log.WithFields("error", err, "module", moduleName, "version", moduleVersion).Trace("unable to read golang licenses local")
|
||||||
|
}
|
||||||
|
if len(goLicenses) > 0 {
|
||||||
|
return toPkgLicenses(goLicenses)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// download from remote sources
|
// download from remote sources
|
||||||
if c.opts.SearchRemoteLicenses {
|
if c.opts.SearchRemoteLicenses {
|
||||||
goLicenses, err = c.getLicensesFromRemote(ctx, scanner, moduleName, moduleVersion)
|
goLicenses, err = c.getLicensesFromRemote(ctx, scanner, moduleName, moduleVersion)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields("error", err, "module", moduleName, "version", moduleVersion).Debug("unable to read golang licenses remote")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return toPkgLicenses(goLicenses), err
|
return toPkgLicenses(goLicenses)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *goLicenseResolver) getLicensesFromLocal(ctx context.Context, scanner licenses.Scanner, moduleName, moduleVersion string) ([]goLicense, error) {
|
func (c *goLicenseResolver) getLicensesFromLocal(ctx context.Context, scanner licenses.Scanner, moduleName, moduleVersion string) ([]goLicense, error) {
|
||||||
|
|||||||
@ -23,81 +23,11 @@ import (
|
|||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_LocalLicenseSearch(t *testing.T) {
|
func Test_LicenseSearch(t *testing.T) {
|
||||||
loc1 := file.NewLocation("github.com/someorg/somename@v0.3.2/LICENSE")
|
loc1 := file.NewLocation("github.com/someorg/somename@v0.3.2/LICENSE")
|
||||||
loc2 := file.NewLocation("github.com/!cap!o!r!g/!cap!project@v4.111.5/LICENSE.txt")
|
loc2 := file.NewLocation("github.com/!cap!o!r!g/!cap!project@v4.111.5/LICENSE.txt")
|
||||||
loc3 := file.NewLocation("github.com/someorg/strangelicense@v1.2.3/LiCeNsE.tXt")
|
loc3 := file.NewLocation("github.com/someorg/strangelicense@v1.2.3/LiCeNsE.tXt")
|
||||||
|
|
||||||
licenseScanner := licenses.TestingOnlyScanner()
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
version string
|
|
||||||
expected pkg.License
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "github.com/someorg/somename",
|
|
||||||
version: "v0.3.2",
|
|
||||||
expected: pkg.License{
|
|
||||||
Value: "Apache-2.0",
|
|
||||||
SPDXExpression: "Apache-2.0",
|
|
||||||
Type: license.Concluded,
|
|
||||||
URLs: []string{"file://$GOPATH/pkg/mod/" + loc1.RealPath},
|
|
||||||
Locations: file.NewLocationSet(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "github.com/CapORG/CapProject",
|
|
||||||
version: "v4.111.5",
|
|
||||||
expected: pkg.License{
|
|
||||||
Value: "MIT",
|
|
||||||
SPDXExpression: "MIT",
|
|
||||||
Type: license.Concluded,
|
|
||||||
URLs: []string{"file://$GOPATH/pkg/mod/" + loc2.RealPath},
|
|
||||||
Locations: file.NewLocationSet(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "github.com/someorg/strangelicense",
|
|
||||||
version: "v1.2.3",
|
|
||||||
expected: pkg.License{
|
|
||||||
Value: "Apache-2.0",
|
|
||||||
SPDXExpression: "Apache-2.0",
|
|
||||||
Type: license.Concluded,
|
|
||||||
URLs: []string{"file://$GOPATH/pkg/mod/" + loc3.RealPath},
|
|
||||||
Locations: file.NewLocationSet(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
wd, err := os.Getwd()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
l := newGoLicenseResolver(
|
|
||||||
"",
|
|
||||||
CatalogerConfig{
|
|
||||||
SearchLocalModCacheLicenses: true,
|
|
||||||
LocalModCacheDir: filepath.Join(wd, "test-fixtures", "licenses", "pkg", "mod"),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
lics, err := l.getLicenses(context.Background(), licenseScanner, fileresolver.Empty{}, test.name, test.version)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.Len(t, lics, 1)
|
|
||||||
|
|
||||||
require.Equal(t, test.expected, lics[0])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RemoteProxyLicenseSearch(t *testing.T) {
|
|
||||||
loc1 := file.NewLocation("github.com/someorg/somename@v0.3.2/LICENSE")
|
|
||||||
loc2 := file.NewLocation("github.com/!cap!o!r!g/!cap!project@v4.111.5/LICENSE.txt")
|
|
||||||
|
|
||||||
licenseScanner := licenses.TestingOnlyScanner()
|
|
||||||
|
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
uri := strings.TrimPrefix(strings.TrimSuffix(r.RequestURI, ".zip"), "/")
|
uri := strings.TrimPrefix(strings.TrimSuffix(r.RequestURI, ".zip"), "/")
|
||||||
@ -135,52 +65,116 @@ func Test_RemoteProxyLicenseSearch(t *testing.T) {
|
|||||||
}))
|
}))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
licenseScanner := licenses.TestingOnlyScanner()
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
version string
|
version string
|
||||||
expected pkg.License
|
config CatalogerConfig
|
||||||
|
expected []pkg.License
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "github.com/someorg/somename",
|
name: "github.com/someorg/somename",
|
||||||
version: "v0.3.2",
|
version: "v0.3.2",
|
||||||
expected: pkg.License{
|
config: CatalogerConfig{
|
||||||
|
SearchLocalModCacheLicenses: true,
|
||||||
|
LocalModCacheDir: filepath.Join(wd, "test-fixtures", "licenses", "pkg", "mod"),
|
||||||
|
},
|
||||||
|
expected: []pkg.License{{
|
||||||
|
Value: "Apache-2.0",
|
||||||
|
SPDXExpression: "Apache-2.0",
|
||||||
|
Type: license.Concluded,
|
||||||
|
URLs: []string{"file://$GOPATH/pkg/mod/" + loc1.RealPath},
|
||||||
|
Locations: file.NewLocationSet(),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "github.com/CapORG/CapProject",
|
||||||
|
version: "v4.111.5",
|
||||||
|
config: CatalogerConfig{
|
||||||
|
SearchLocalModCacheLicenses: true,
|
||||||
|
LocalModCacheDir: filepath.Join(wd, "test-fixtures", "licenses", "pkg", "mod"),
|
||||||
|
},
|
||||||
|
expected: []pkg.License{{
|
||||||
|
Value: "MIT",
|
||||||
|
SPDXExpression: "MIT",
|
||||||
|
Type: license.Concluded,
|
||||||
|
URLs: []string{"file://$GOPATH/pkg/mod/" + loc2.RealPath},
|
||||||
|
Locations: file.NewLocationSet(),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "github.com/someorg/strangelicense",
|
||||||
|
version: "v1.2.3",
|
||||||
|
config: CatalogerConfig{
|
||||||
|
SearchLocalModCacheLicenses: true,
|
||||||
|
LocalModCacheDir: filepath.Join(wd, "test-fixtures", "licenses", "pkg", "mod"),
|
||||||
|
},
|
||||||
|
expected: []pkg.License{{
|
||||||
|
Value: "Apache-2.0",
|
||||||
|
SPDXExpression: "Apache-2.0",
|
||||||
|
Type: license.Concluded,
|
||||||
|
URLs: []string{"file://$GOPATH/pkg/mod/" + loc3.RealPath},
|
||||||
|
Locations: file.NewLocationSet(),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "github.com/someorg/somename",
|
||||||
|
version: "v0.3.2",
|
||||||
|
config: CatalogerConfig{
|
||||||
|
SearchRemoteLicenses: true,
|
||||||
|
Proxies: []string{server.URL},
|
||||||
|
},
|
||||||
|
expected: []pkg.License{{
|
||||||
Value: "Apache-2.0",
|
Value: "Apache-2.0",
|
||||||
SPDXExpression: "Apache-2.0",
|
SPDXExpression: "Apache-2.0",
|
||||||
Type: license.Concluded,
|
Type: license.Concluded,
|
||||||
URLs: []string{server.URL + "/github.com/someorg/somename/@v/v0.3.2.zip#" + loc1.RealPath},
|
URLs: []string{server.URL + "/github.com/someorg/somename/@v/v0.3.2.zip#" + loc1.RealPath},
|
||||||
Locations: file.NewLocationSet(),
|
Locations: file.NewLocationSet(),
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "github.com/CapORG/CapProject",
|
name: "github.com/CapORG/CapProject",
|
||||||
version: "v4.111.5",
|
version: "v4.111.5",
|
||||||
expected: pkg.License{
|
config: CatalogerConfig{
|
||||||
|
SearchRemoteLicenses: true,
|
||||||
|
Proxies: []string{server.URL},
|
||||||
|
},
|
||||||
|
expected: []pkg.License{{
|
||||||
Value: "MIT",
|
Value: "MIT",
|
||||||
SPDXExpression: "MIT",
|
SPDXExpression: "MIT",
|
||||||
Type: license.Concluded,
|
Type: license.Concluded,
|
||||||
URLs: []string{server.URL + "/github.com/CapORG/CapProject/@v/v4.111.5.zip#" + loc2.RealPath},
|
URLs: []string{server.URL + "/github.com/CapORG/CapProject/@v/v4.111.5.zip#" + loc2.RealPath},
|
||||||
Locations: file.NewLocationSet(),
|
Locations: file.NewLocationSet(),
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "github.com/CapORG/CapProject",
|
||||||
|
version: "v4.111.5",
|
||||||
|
config: CatalogerConfig{
|
||||||
|
SearchLocalModCacheLicenses: true,
|
||||||
|
LocalModCacheDir: filepath.Join(wd, "test-fixtures"), // valid dir but does not find modules
|
||||||
|
SearchRemoteLicenses: true,
|
||||||
|
Proxies: []string{server.URL},
|
||||||
|
},
|
||||||
|
expected: []pkg.License{{
|
||||||
|
Value: "MIT",
|
||||||
|
SPDXExpression: "MIT",
|
||||||
|
Type: license.Concluded,
|
||||||
|
URLs: []string{server.URL + "/github.com/CapORG/CapProject/@v/v4.111.5.zip#" + loc2.RealPath},
|
||||||
|
Locations: file.NewLocationSet(),
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
l := newGoLicenseResolver("", test.config)
|
||||||
l := newGoLicenseResolver(
|
lics := l.getLicenses(context.Background(), licenseScanner, fileresolver.Empty{}, test.name, test.version)
|
||||||
"",
|
require.EqualValues(t, test.expected, lics)
|
||||||
CatalogerConfig{
|
|
||||||
SearchRemoteLicenses: true,
|
|
||||||
Proxies: []string{server.URL},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
lics, err := l.getLicenses(context.Background(), licenseScanner, fileresolver.Empty{}, test.name, test.version)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.Len(t, lics, 1)
|
|
||||||
|
|
||||||
require.Equal(t, test.expected, lics[0])
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -119,11 +119,7 @@ func (c *goBinaryCataloger) buildGoPkgInfo(ctx context.Context, licenseScanner l
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
lics, err := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, dep.Path, dep.Version)
|
lics := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, dep.Path, dep.Version)
|
||||||
if err != nil {
|
|
||||||
log.Tracef("error getting licenses for golang package: %s %v", dep.Path, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
gover, experiments := getExperimentsFromVersion(mod.GoVersion)
|
gover, experiments := getExperimentsFromVersion(mod.GoVersion)
|
||||||
p := c.newGoBinaryPackage(
|
p := c.newGoBinaryPackage(
|
||||||
dep,
|
dep,
|
||||||
@ -162,12 +158,7 @@ func missingMainModule(mod *extendedBuildInfo) bool {
|
|||||||
|
|
||||||
func (c *goBinaryCataloger) makeGoMainPackage(ctx context.Context, licenseScanner licenses.Scanner, resolver file.Resolver, mod *extendedBuildInfo, arch string, location file.Location, reader io.ReadSeekCloser) pkg.Package {
|
func (c *goBinaryCataloger) makeGoMainPackage(ctx context.Context, licenseScanner licenses.Scanner, resolver file.Resolver, mod *extendedBuildInfo, arch string, location file.Location, reader io.ReadSeekCloser) pkg.Package {
|
||||||
gbs := getBuildSettings(mod.Settings)
|
gbs := getBuildSettings(mod.Settings)
|
||||||
|
lics := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, mod.Main.Path, mod.Main.Version)
|
||||||
lics, err := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, mod.Main.Path, mod.Main.Version)
|
|
||||||
if err != nil {
|
|
||||||
log.Tracef("error getting licenses for golang package: %s %v", mod.Main.Path, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
gover, experiments := getExperimentsFromVersion(mod.GoVersion)
|
gover, experiments := getExperimentsFromVersion(mod.GoVersion)
|
||||||
main := c.newGoBinaryPackage(
|
main := c.newGoBinaryPackage(
|
||||||
&mod.Main,
|
&mod.Main,
|
||||||
|
|||||||
@ -53,11 +53,7 @@ func (c *goModCataloger) parseGoModFile(ctx context.Context, resolver file.Resol
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, m := range f.Require {
|
for _, m := range f.Require {
|
||||||
lics, err := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, m.Mod.Path, m.Mod.Version)
|
lics := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, m.Mod.Path, m.Mod.Version)
|
||||||
if err != nil {
|
|
||||||
log.Tracef("error getting licenses for package: %s %v", m.Mod.Path, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
packages[m.Mod.Path] = pkg.Package{
|
packages[m.Mod.Path] = pkg.Package{
|
||||||
Name: m.Mod.Path,
|
Name: m.Mod.Path,
|
||||||
Version: m.Mod.Version,
|
Version: m.Mod.Version,
|
||||||
@ -74,10 +70,7 @@ func (c *goModCataloger) parseGoModFile(ctx context.Context, resolver file.Resol
|
|||||||
|
|
||||||
// remove any old packages and replace with new ones...
|
// remove any old packages and replace with new ones...
|
||||||
for _, m := range f.Replace {
|
for _, m := range f.Replace {
|
||||||
lics, err := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, m.New.Path, m.New.Version)
|
lics := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, m.New.Path, m.New.Version)
|
||||||
if err != nil {
|
|
||||||
log.Tracef("error getting licenses for package: %s %v", m.New.Path, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// the old path and new path may be the same, in which case this is a noop,
|
// the old path and new path may be the same, in which case this is a noop,
|
||||||
// but if they're different we need to remove the old package.
|
// but if they're different we need to remove the old package.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user