mirror of
https://github.com/anchore/syft.git
synced 2026-11-05 00:46:38 +01:00
feat(golang): add license parsing from vendor dirs (#3522)
Signed-off-by: Dominik Schmidt <dev@dominik-schmidt.de> Signed-off-by: Keith Zantow <kzantow@gmail.com> Co-authored-by: Keith Zantow <kzantow@gmail.com>
This commit is contained in:
co-authored by
Keith Zantow
parent
8198a706d6
commit
19a75fe504
@@ -42,6 +42,7 @@ type goLicenseResolver struct {
|
||||
catalogerName string
|
||||
opts CatalogerConfig
|
||||
localModCacheDir fs.FS
|
||||
localVendorDir fs.FS
|
||||
licenseCache cache.Resolver[[]goLicense]
|
||||
lowerLicenseFileNames *strset.Set
|
||||
}
|
||||
@@ -52,10 +53,25 @@ func newGoLicenseResolver(catalogerName string, opts CatalogerConfig) goLicenseR
|
||||
localModCacheDir = os.DirFS(opts.LocalModCacheDir)
|
||||
}
|
||||
|
||||
var localVendorDir fs.FS
|
||||
if opts.SearchLocalVendorLicenses {
|
||||
vendorDir := opts.LocalVendorDir
|
||||
if vendorDir == "" {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Warn("unable to get CWD while resolving the local go vendor dir: %v", err)
|
||||
} else {
|
||||
vendorDir = filepath.Join(wd, "vendor")
|
||||
}
|
||||
}
|
||||
localVendorDir = os.DirFS(vendorDir)
|
||||
}
|
||||
|
||||
return goLicenseResolver{
|
||||
catalogerName: catalogerName,
|
||||
opts: opts,
|
||||
localModCacheDir: localModCacheDir,
|
||||
localVendorDir: localVendorDir,
|
||||
licenseCache: cache.GetResolverCachingErrors[[]goLicense]("golang", "v1"),
|
||||
lowerLicenseFileNames: strset.New(lowercaseLicenseFiles()...),
|
||||
}
|
||||
@@ -103,6 +119,17 @@ func (c *goLicenseResolver) getLicenses(ctx context.Context, scanner licenses.Sc
|
||||
}
|
||||
}
|
||||
|
||||
// look in the local vendor directory...
|
||||
if c.opts.SearchLocalVendorLicenses {
|
||||
goLicenses, err = c.getLicensesFromLocalVendor(ctx, scanner, moduleName)
|
||||
if err != nil {
|
||||
log.WithFields("error", err, "module", moduleName, "version", moduleVersion).Trace("unable to read golang licenses vendor")
|
||||
}
|
||||
if len(goLicenses) > 0 {
|
||||
return toPkgLicenses(goLicenses)
|
||||
}
|
||||
}
|
||||
|
||||
// download from remote sources
|
||||
if c.opts.SearchRemoteLicenses {
|
||||
goLicenses, err = c.getLicensesFromRemote(ctx, scanner, moduleName, moduleVersion)
|
||||
@@ -133,6 +160,25 @@ func (c *goLicenseResolver) getLicensesFromLocal(ctx context.Context, scanner li
|
||||
return c.findLicensesInFS(ctx, scanner, "file://$GOPATH/pkg/mod/"+subdir+"/", dir)
|
||||
}
|
||||
|
||||
func (c *goLicenseResolver) getLicensesFromLocalVendor(ctx context.Context, scanner licenses.Scanner, moduleName string) ([]goLicense, error) {
|
||||
if c.localVendorDir == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
subdir := processCaps(moduleName)
|
||||
|
||||
// get the local subdirectory containing the specific go module
|
||||
dir, err := fs.Sub(c.localVendorDir, subdir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if we're running against a directory on the filesystem, it may not include the
|
||||
// user's homedir / GOPATH, so we defer to using the localModCacheResolver
|
||||
// we use $GOPATH/pkg/mod to avoid leaking information about the user's system
|
||||
return c.findLicensesInFS(ctx, scanner, "file://$GO_VENDOR/"+subdir+"/", dir)
|
||||
}
|
||||
|
||||
func (c *goLicenseResolver) getLicensesFromRemote(ctx context.Context, scanner licenses.Scanner, moduleName, moduleVersion string) ([]goLicense, error) {
|
||||
return c.licenseCache.Resolve(fmt.Sprintf("%s/%s", moduleName, moduleVersion), func() ([]goLicense, error) {
|
||||
proxies := remotesForModule(c.opts.Proxies, c.opts.NoProxy, moduleName)
|
||||
|
||||
Reference in New Issue
Block a user