diff --git a/dependency-check/pkg/npm_utils.go b/dependency-check/pkg/npm_utils.go new file mode 100644 index 0000000..c9ab330 --- /dev/null +++ b/dependency-check/pkg/npm_utils.go @@ -0,0 +1,69 @@ +package pkg + +import ( + "archive/tar" + "compress/gzip" + "encoding/json" + "github.com/TencentBlueKing/ci-repoAnalysis/analysis-tool-sdk-golang/util" + "io" + "os" + "strings" +) + +// ParsePackageNameAndVersion 从文件名解析包名和版本 +func ParsePackageNameAndVersion(fileBaseName string) (string, string) { + // 获取 pkgName 和 pkgVersion + indexOfLastHyphens := strings.LastIndex(fileBaseName, "-") + if indexOfLastHyphens == -1 { + return "", "" + } + indexOfLastDot := strings.LastIndex(fileBaseName, ".") + if indexOfLastDot == -1 { + return "", "" + } + pkgName := fileBaseName[:indexOfLastHyphens] + pkgVersion := fileBaseName[indexOfLastHyphens+1 : indexOfLastDot] + util.Info("npm package %s, version %s", pkgName, pkgVersion) + + return pkgName, pkgVersion +} + +// ExtractPackageNameAndVersion 从package.json文件中解析出packageName、version +func ExtractPackageNameAndVersion(npmPkgPath string) (string, string, error) { + f, err := os.Open(npmPkgPath) + if err != nil { + return "", "", err + } + defer f.Close() + + uncompressedStream, err := gzip.NewReader(f) + if err != nil { + return "", "", err + } + defer uncompressedStream.Close() + tarReader := tar.NewReader(uncompressedStream) + + for true { + header, err := tarReader.Next() + if err == io.EOF { + break + } + if err != nil { + return "", "", err + } + if header.Typeflag == tar.TypeReg && header.Name == "package/package.json" { + npmPkg := &npmPackage{} + if err := json.NewDecoder(tarReader).Decode(npmPkg); err != nil { + return "", "", err + } + return npmPkg.Name, npmPkg.Version, nil + } + } + + return "", "", nil +} + +type npmPackage struct { + Name string `json:"name"` + Version string `json:"version"` +} diff --git a/dependency-check/pkg/npm_utils_test.go b/dependency-check/pkg/npm_utils_test.go new file mode 100644 index 0000000..b3bcdcb --- /dev/null +++ b/dependency-check/pkg/npm_utils_test.go @@ -0,0 +1,22 @@ +package pkg + +import ( + "testing" +) + +func TestParsePackageNameAndVersion(t *testing.T) { + pkgName, pkgVersion := ParsePackageNameAndVersion("npm-test-0.0.1.tgz") + if pkgName != "npm-test" || pkgVersion != "0.0.1" { + t.Fatalf("parese failed pkgName[%s] pkgVersion[%s]", pkgName, pkgVersion) + } +} + +func TestExtractPackageNameAndVersion(t *testing.T) { + pkgName, pkgVersion, err := ExtractPackageNameAndVersion("testdata/axios-0.16.2.tgz") + if err != nil { + t.Fatal(err.Error()) + } + if pkgName != "axios" || pkgVersion != "0.16.2" { + t.Fatalf("parese failed pkgName[%s] pkgVersion[%s]", pkgName, pkgVersion) + } +} diff --git a/dependency-check/pkg/scan_executor.go b/dependency-check/pkg/scan_executor.go index 4c3c853..123737e 100644 --- a/dependency-check/pkg/scan_executor.go +++ b/dependency-check/pkg/scan_executor.go @@ -8,7 +8,6 @@ import ( "github.com/TencentBlueKing/ci-repoAnalysis/analysis-tool-sdk-golang/util" "os" "path/filepath" - "strings" ) const PackageTypeNpm = "NPM" @@ -59,16 +58,16 @@ func npmPrepare(file *os.File) error { } // 获取 pkgName 和 pkgVersion - indexOfHyphens := strings.Index(fileBaseName, "-") - if indexOfHyphens == -1 { - return errors.New("'-' not found in file name " + fileBaseName) + pkgName, pkgVersion, err := ExtractPackageNameAndVersion(fileAbsPath) + if err != nil { + return err + } + if len(pkgName) == 0 || len(pkgVersion) == 0 { + pkgName, pkgVersion = ParsePackageNameAndVersion(fileBaseName) } - indexOfLastDot := strings.LastIndex(fileBaseName, ".") - if indexOfLastDot == -1 { - return errors.New("'.' not found in file name " + fileBaseName) + if len(pkgName) == 0 || len(pkgVersion) == 0 { + return errors.New("failed to parse npm pkgName and pkgVersion") } - pkgName := fileBaseName[:indexOfHyphens] - pkgVersion := fileBaseName[indexOfHyphens+1 : indexOfLastDot] util.Info("npm package %s, version %s", pkgName, pkgVersion) // 替换 package-lock.json中的file:xxx 为实际版本号 diff --git a/dependency-check/pkg/testdata/axios-0.16.2.tgz b/dependency-check/pkg/testdata/axios-0.16.2.tgz new file mode 100644 index 0000000..e69de29