diff --git a/dependency-check/go.mod b/dependency-check/go.mod index a11b493..d75ad0f 100644 --- a/dependency-check/go.mod +++ b/dependency-check/go.mod @@ -2,4 +2,4 @@ module github.com/TencentBlueKing/ci-repoAnalysis/dependency-check go 1.18 -require github.com/TencentBlueKing/ci-repoAnalysis/analysis-tool-sdk-golang v0.0.15 +require github.com/TencentBlueKing/ci-repoAnalysis/analysis-tool-sdk-golang v0.0.16 diff --git a/dependency-check/go.sum b/dependency-check/go.sum index e37ca6b..6857462 100644 --- a/dependency-check/go.sum +++ b/dependency-check/go.sum @@ -1,2 +1,2 @@ -github.com/TencentBlueKing/ci-repoAnalysis/analysis-tool-sdk-golang v0.0.15 h1:+Ytj6MbRvf9QflKrnCfYqdtyUi1Ff1UNS7tt9TGAT8w= -github.com/TencentBlueKing/ci-repoAnalysis/analysis-tool-sdk-golang v0.0.15/go.mod h1:8fgb+y0YWqULX/oVg4dsWAq6ftsVZfFrXQjCKXwAE1Q= +github.com/TencentBlueKing/ci-repoAnalysis/analysis-tool-sdk-golang v0.0.16 h1:wYcG08v3iq2DIwDZ++2oCp/sy087PSJI3fKedHpH1MI= +github.com/TencentBlueKing/ci-repoAnalysis/analysis-tool-sdk-golang v0.0.16/go.mod h1:8fgb+y0YWqULX/oVg4dsWAq6ftsVZfFrXQjCKXwAE1Q= diff --git a/dependency-check/pkg/scan_executor.go b/dependency-check/pkg/scan_executor.go index 7f00e23..4c3c853 100644 --- a/dependency-check/pkg/scan_executor.go +++ b/dependency-check/pkg/scan_executor.go @@ -2,11 +2,17 @@ package pkg import ( "encoding/json" + "errors" + "fmt" "github.com/TencentBlueKing/ci-repoAnalysis/analysis-tool-sdk-golang/object" "github.com/TencentBlueKing/ci-repoAnalysis/analysis-tool-sdk-golang/util" "os" + "path/filepath" + "strings" ) +const PackageTypeNpm = "NPM" + // DependencyCheckExecutor DependencyCheck分析器 type DependencyCheckExecutor struct{} @@ -17,22 +23,84 @@ func (e DependencyCheckExecutor) Execute(config *object.ToolConfig, file *os.Fil return nil, err } + inputFile := file.Name() + if config.GetStringArg(util.ArgKeyPkgType) == PackageTypeNpm { + if err := npmPrepare(file); err != nil { + return nil, err + } + inputFile = filepath.Join(filepath.Dir(inputFile), "package-lock.json") + } + // 下载漏洞库 + downloader := &util.DefaultDownloader{} dbUrl := config.GetStringArg(ConfigDbUrl) if len(dbUrl) > 0 { - if err := util.ExtractTarUrl(dbUrl, DirDependencyCheckData, 0770); err != nil { + if err := util.ExtractTarUrl(dbUrl, DirDependencyCheckData, 0770, downloader); err != nil { return nil, err } } // 执行扫描 - reportFile, err := doExecute(file.Name(), offline) + reportFile, err := doExecute(inputFile, offline) if err != nil { return nil, err } return transform(reportFile) } +func npmPrepare(file *os.File) error { + fileAbsPath := file.Name() + fileBaseName := filepath.Base(fileAbsPath) + workDir := filepath.Dir(fileAbsPath) + + // npm install + if err := util.ExecAndLog("npm", []string{"install", file.Name()}, workDir); err != nil { + return err + } + + // 获取 pkgName 和 pkgVersion + indexOfHyphens := strings.Index(fileBaseName, "-") + if indexOfHyphens == -1 { + return errors.New("'-' not found in file name " + fileBaseName) + } + indexOfLastDot := strings.LastIndex(fileBaseName, ".") + if indexOfLastDot == -1 { + return errors.New("'.' not found in file name " + fileBaseName) + } + pkgName := fileBaseName[:indexOfHyphens] + pkgVersion := fileBaseName[indexOfHyphens+1 : indexOfLastDot] + util.Info("npm package %s, version %s", pkgName, pkgVersion) + + // 替换 package-lock.json中的file:xxx 为实际版本号 + sedExp := fmt.Sprintf( + "s/\\\"%s\\\": \\\"file:%s\\\"/\\\"%s\\\": \\\"%s\\\"/", + pkgName, fileBaseName, pkgName, pkgVersion, + ) + if err := sed(sedExp, filepath.Join(workDir, "package-lock.json")); err != nil { + return err + } + if err := sed(sedExp, filepath.Join(workDir, "package.json")); err != nil { + return err + } + + sedExp = fmt.Sprintf( + "s/\\\"version\\\": \\\"file:%s\\\"/\\\"version\\\": \\\"%s\\\"/", + fileBaseName, pkgVersion, + ) + if err := sed(sedExp, filepath.Join(workDir, "package-lock.json")); err != nil { + return err + } + return nil +} + +func sed(exp string, fileAbsPath string) error { + args := []string{"-i", exp, fileAbsPath} + if err := util.ExecAndLog("sed", args, ""); err != nil { + return err + } + return nil +} + // doExecute 执行扫描,扫描成功后返回报告路径 func doExecute(inputFile string, offline bool) (string, error) { // dependency-check.sh --scan /src --format JSON --out /report @@ -50,7 +118,7 @@ func doExecute(inputFile string, offline bool) (string, error) { "--disableYarnAudit", "--disablePnpmAudit", "--disableNodeAudit", "--disableOssIndex", "--disableCentral") } - if err := util.ExecAndLog(CMDDependencyCheck, args); err != nil { + if err := util.ExecAndLog(CMDDependencyCheck, args, ""); err != nil { return "", err }