This is an automated email from the ASF dual-hosted git repository.

kezhenxu94 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-eyes.git


The following commit(s) were added to refs/heads/main by this push:
     new 2cfd5a1  Enhance Npm Resolver: support recording license contents (#71)
2cfd5a1 is described below

commit 2cfd5a18c0d4b03cb8b69f3412d4d53737d831a6
Author: Youhan Wu <[email protected]>
AuthorDate: Wed Sep 15 00:32:21 2021 -0500

    Enhance Npm Resolver: support recording license contents (#71)
---
 pkg/deps/npm.go      | 80 +++++++++++++++++++++++++++-------------------------
 pkg/deps/npm_test.go |  7 ++---
 pkg/deps/result.go   |  1 +
 3 files changed, 45 insertions(+), 43 deletions(-)

diff --git a/pkg/deps/npm.go b/pkg/deps/npm.go
index fc51930..00bf2c5 100644
--- a/pkg/deps/npm.go
+++ b/pkg/deps/npm.go
@@ -85,12 +85,12 @@ func (resolver *NpmResolver) Resolve(pkgFile string, report 
*Report) error {
        // Walk through each package's root directory to resolve licenses
        // Resolve from a package's package.json file or its license file
        for _, pkg := range pkgs {
-               if err := resolver.ResolvePackageLicense(pkg.Name, pkg.Path, 
report); err != nil {
-                       logger.Log.Warnln("Failed to resolve the license of 
dependency:", pkg.Name, err)
-                       report.Skip(&Result{
-                               Dependency:    pkg.Name,
-                               LicenseSpdxID: Unknown,
-                       })
+               if result := resolver.ResolvePackageLicense(pkg.Name, 
pkg.Path); result.LicenseSpdxID != "" {
+                       report.Resolve(result)
+               } else {
+                       result.LicenseSpdxID = Unknown
+                       report.Skip(result)
+                       logger.Log.Warnln("Failed to resolve the license of 
dependency:", pkg.Name, result.ResolveErrors)
                }
        }
        return nil
@@ -184,47 +184,43 @@ func (resolver *NpmResolver) GetInstalledPkgs(pkgDir 
string) []*Package {
 // ResolvePackageLicense resolves the licenses of the given packages.
 // First, try to find and parse the package's package.json file to check the 
license file
 // If the previous step fails, then try to identify the package's LICENSE file
-func (resolver *NpmResolver) ResolvePackageLicense(pkgName, pkgPath string, 
report *Report) error {
-       var resolveErrs error
-       expectedPkgFile := filepath.Join(pkgPath, PkgFileName)
-       lcs, err := resolver.ResolvePkgFile(expectedPkgFile)
-       if err == nil {
-               report.Resolve(&Result{
-                       Dependency:    pkgName,
-                       LicenseSpdxID: lcs,
-               })
-               return nil
+// It's a necessary procedure to check the LICENSE file, because the resolver 
needs to record the license content
+func (resolver *NpmResolver) ResolvePackageLicense(pkgName, pkgPath string) 
*Result {
+       result := &Result{
+               Dependency: pkgName,
+       }
+       // resolve from the package.json file
+       if err := resolver.ResolvePkgFile(result, pkgPath); err != nil {
+               result.ResolveErrors = append(result.ResolveErrors, err)
        }
-       resolveErrs = err
 
-       lcs, err = resolver.ResolveLcsFile(pkgName, pkgPath)
-       if err == nil {
-               report.Resolve(&Result{
-                       Dependency:    pkgName,
-                       LicenseSpdxID: lcs,
-               })
-               return nil
+       // resolve from the LICENSE file
+       if err := resolver.ResolveLcsFile(result, pkgPath); err != nil {
+               result.ResolveErrors = append(result.ResolveErrors, err)
        }
-       resolveErrs = fmt.Errorf("%+v; %+v", resolveErrs, err)
-       return resolveErrs
+
+       return result
 }
 
 // ResolvePkgFile tries to find and parse the package.json file to capture the 
license field
-func (resolver *NpmResolver) ResolvePkgFile(pkgFile string) (string, error) {
-       packageInfo, err := resolver.ParsePkgFile(pkgFile)
+func (resolver *NpmResolver) ResolvePkgFile(result *Result, pkgPath string) 
error {
+       expectedPkgFile := filepath.Join(pkgPath, PkgFileName)
+       packageInfo, err := resolver.ParsePkgFile(expectedPkgFile)
        if err != nil {
-               return "", err
+               return err
        }
 
        if lcs, ok := resolver.ResolveLicenseField(packageInfo.License); ok {
-               return lcs, nil
+               result.LicenseSpdxID = lcs
+               return nil
        }
 
        if lcs, ok := resolver.ResolveLicensesField(packageInfo.Licenses); ok {
-               return lcs, nil
+               result.LicenseSpdxID = lcs
+               return nil
        }
 
-       return "", fmt.Errorf(`cannot parse the "license"/"licenses" field`)
+       return fmt.Errorf(`cannot parse the "license"/"licenses" field`)
 }
 
 // ResolveLicenseField parses and validates the "license" field in 
package.json file
@@ -262,27 +258,33 @@ func (resolver *NpmResolver) 
ResolveLicensesField(licenses []Lcs) (string, bool)
 }
 
 // ResolveLcsFile tries to find the license file to identify the license
-func (resolver *NpmResolver) ResolveLcsFile(pkgName, pkgPath string) (string, 
error) {
+func (resolver *NpmResolver) ResolveLcsFile(result *Result, pkgPath string) 
error {
        depFiles, err := ioutil.ReadDir(pkgPath)
        if err != nil {
-               return "", err
+               return err
        }
        for _, info := range depFiles {
                if info.IsDir() || 
!possibleLicenseFileName.MatchString(info.Name()) {
                        continue
                }
                licenseFilePath := filepath.Join(pkgPath, info.Name())
+               result.LicenseFilePath = licenseFilePath
                content, err := ioutil.ReadFile(licenseFilePath)
                if err != nil {
-                       return "", err
+                       return err
+               }
+               result.LicenseContent = string(content)
+               if result.LicenseSpdxID != "" {
+                       return nil
                }
-               identifier, err := license.Identify(pkgName, string(content))
+               identifier, err := license.Identify(result.Dependency, 
string(content))
                if err != nil {
-                       return "", err
+                       return err
                }
-               return identifier, nil
+               result.LicenseSpdxID = identifier
+               return nil
        }
-       return "", fmt.Errorf("cannot find the license file")
+       return fmt.Errorf("cannot find the license file")
 }
 
 // ParsePkgFile parses the content of the package file
diff --git a/pkg/deps/npm_test.go b/pkg/deps/npm_test.go
index ba11961..c914d32 100644
--- a/pkg/deps/npm_test.go
+++ b/pkg/deps/npm_test.go
@@ -88,9 +88,9 @@ func TestResolvePkgFile(t *testing.T) {
                t.Fatal(err)
        }
        defer os.RemoveAll(dir)
-
        resolver := new(deps.NpmResolver)
        for _, data := range TestData {
+               result := &deps.Result{}
                f, err := ioutil.TempFile(dir, "*.json")
                if err != nil {
                        t.Fatal(err)
@@ -99,9 +99,8 @@ func TestResolvePkgFile(t *testing.T) {
                if err != nil {
                        t.Fatal(err)
                }
-
-               lcs, err := resolver.ResolvePkgFile(f.Name())
-               if lcs != data.result && (err != nil) == data.hasErr {
+               err = resolver.ResolvePkgFile(result, f.Name())
+               if result.LicenseSpdxID != data.result && (err != nil) == 
data.hasErr {
                        t.Fail()
                }
                _ = f.Close()
diff --git a/pkg/deps/result.go b/pkg/deps/result.go
index 6bfc104..f460bcc 100644
--- a/pkg/deps/result.go
+++ b/pkg/deps/result.go
@@ -35,6 +35,7 @@ type Result struct {
        LicenseFilePath string
        LicenseContent  string
        LicenseSpdxID   string
+       ResolveErrors   []error
 }
 
 // Report is a collection of resolved Result.

Reply via email to