Skip to content

Commit

Permalink
Fail audit command for yarn v1 (#637)
Browse files Browse the repository at this point in the history
  • Loading branch information
RobiNino authored Jan 3, 2023
1 parent 15bc81e commit 80aa9aa
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 31 deletions.
14 changes: 9 additions & 5 deletions xray/audit/commonutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,14 @@ func GetModule(modules []*services.GraphNode, moduleId string) *services.GraphNo
return nil
}

func LogExecutableVersion(executable string) {
// Get executable version and print to log if possible
verString, _ := exec.Command(executable, "--version").CombinedOutput()
if len(verString) > 0 {
log.Debug(fmt.Sprintf("Used %q version: %s", executable, strings.TrimSpace(string(verString))))
// Gets executable version and prints to the debug log if possible.
// Only supported for package managers that use "--version".
func GetExecutableVersion(executable string) (version string, err error) {
verBytes, err := exec.Command(executable, "--version").CombinedOutput()
if err != nil || len(verBytes) == 0 {
return "", err
}
version = strings.TrimSpace(string(verBytes))
log.Debug(fmt.Sprintf("Used %q version: %s", executable, version))
return
}
31 changes: 18 additions & 13 deletions xray/audit/python/python.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@ package python

import (
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"

"github.com/jfrog/build-info-go/utils/pythonutils"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/xray/audit"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
clientLog "github.com/jfrog/jfrog-client-go/utils/log"
"github.com/jfrog/jfrog-client-go/utils/log"
"github.com/jfrog/jfrog-client-go/xray/services"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
)

const (
Expand Down Expand Up @@ -93,8 +92,12 @@ func getDependencies(pythonTool pythonutils.PythonTool, requirementsFile string)
}
dependenciesGraph, directDependencies, err = pythonutils.GetPythonDependencies(pythonTool, tempDirPath, localDependenciesPath)
if err != nil {
audit.LogExecutableVersion("python")
audit.LogExecutableVersion(string(pythonTool))
if _, innerErr := audit.GetExecutableVersion("python"); innerErr != nil {
log.Error(innerErr)
}
if _, innerErr := audit.GetExecutableVersion(string(pythonTool)); innerErr != nil {
log.Error(innerErr)
}
}
return
}
Expand All @@ -111,11 +114,11 @@ func runPythonInstall(pythonTool pythonutils.PythonTool, requirementsFile string
}
err = runPipInstall(requirementsFile)
if err != nil && requirementsFile == "" {
clientLog.Debug(err.Error() + "\ntrying to install using a requirements file.")
log.Debug(err.Error() + "\ntrying to install using a requirements file.")
reqErr := runPipInstall("requirements.txt")
if reqErr != nil {
// Return Pip install error and log the requirements fallback error.
clientLog.Debug(reqErr.Error())
log.Debug(reqErr.Error())
} else {
err = nil
}
Expand All @@ -141,10 +144,12 @@ func runPythonInstall(pythonTool pythonutils.PythonTool, requirementsFile string

func executeCommand(executable string, args ...string) error {
installCmd := exec.Command(executable, args...)
clientLog.Debug(fmt.Sprintf("Running %q", strings.Join(installCmd.Args, " ")))
log.Debug(fmt.Sprintf("Running %q", strings.Join(installCmd.Args, " ")))
output, err := installCmd.CombinedOutput()
if err != nil {
audit.LogExecutableVersion(executable)
if _, innerErr := audit.GetExecutableVersion(executable); innerErr != nil {
log.Error(innerErr)
}
return errorutils.CheckErrorf("%q command failed: %s - %s", strings.Join(installCmd.Args, " "), err.Error(), output)
}
return nil
Expand Down
41 changes: 28 additions & 13 deletions xray/audit/yarn/yarn.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package yarn

import (
biutils "github.com/jfrog/build-info-go/build/utils"
biUtils "github.com/jfrog/build-info-go/build/utils"
"github.com/jfrog/gofrog/version"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-cli-core/v2/xray/audit"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
Expand All @@ -11,28 +12,29 @@ import (

const (
npmPackageTypeIdentifier = "npm://"
yarnV2Version = "2.0.0"
YarnV1ErrorPrefix = "jf audit is only supported for yarn v2 and above."
)

func BuildDependencyTree() (dependencyTree []*services.GraphNode, err error) {
currentDir, err := coreutils.GetWorkingDirectory()
if err != nil {
return
}
executablePath, err := biutils.GetYarnExecutable()
executablePath, err := biUtils.GetYarnExecutable()
if errorutils.CheckError(err) != nil {
return
}
defer func() {
if err != nil && executablePath != "" {
audit.LogExecutableVersion(executablePath)
}
}()
packageInfo, err := biutils.ReadPackageInfoFromPackageJson(currentDir, nil)
if err = logAndValidateYarnVersion(executablePath); err != nil {
return
}

packageInfo, err := biUtils.ReadPackageInfoFromPackageJson(currentDir, nil)
if errorutils.CheckError(err) != nil {
return
}
// Calculate Yarn dependencies
dependenciesMap, _, err := biutils.GetYarnDependencies(executablePath, currentDir, packageInfo, log.Logger)
dependenciesMap, _, err := biUtils.GetYarnDependencies(executablePath, currentDir, packageInfo, log.Logger)
if err != nil {
return
}
Expand All @@ -41,14 +43,27 @@ func BuildDependencyTree() (dependencyTree []*services.GraphNode, err error) {
return
}

// Parse the dependencies into an Xray dependency tree format
func parseYarnDependenciesMap(dependencies map[string]*biutils.YarnDependency, packageInfo *biutils.PackageInfo) (xrDependencyTree *services.GraphNode) {
// Yarn audit is only supported from yarn v2.
func logAndValidateYarnVersion(executablePath string) error {
versionStr, err := audit.GetExecutableVersion(executablePath)
if errorutils.CheckError(err) != nil {
return err
}
yarnVer := version.NewVersion(versionStr)
if yarnVer.Compare(yarnV2Version) > 0 {
return errorutils.CheckErrorf(YarnV1ErrorPrefix + "The current version is: " + versionStr)
}
return nil
}

// Parse the dependencies into a Xray dependency tree format
func parseYarnDependenciesMap(dependencies map[string]*biUtils.YarnDependency, packageInfo *biUtils.PackageInfo) (xrDependencyTree *services.GraphNode) {
treeMap := make(map[string][]string)
for _, dependency := range dependencies {
xrayDepId := getXrayDependencyId(dependency)
var subDeps []string
for _, subDepPtr := range dependency.Details.Dependencies {
subDeps = append(subDeps, getXrayDependencyId(dependencies[biutils.GetYarnDependencyKeyFromLocator(subDepPtr.Locator)]))
subDeps = append(subDeps, getXrayDependencyId(dependencies[biUtils.GetYarnDependencyKeyFromLocator(subDepPtr.Locator)]))
}
if len(subDeps) > 0 {
treeMap[xrayDepId] = subDeps
Expand All @@ -57,6 +72,6 @@ func parseYarnDependenciesMap(dependencies map[string]*biutils.YarnDependency, p
return audit.BuildXrayDependencyTree(treeMap, npmPackageTypeIdentifier+packageInfo.BuildInfoModuleId())
}

func getXrayDependencyId(yarnDependency *biutils.YarnDependency) string {
func getXrayDependencyId(yarnDependency *biUtils.YarnDependency) string {
return npmPackageTypeIdentifier + yarnDependency.Name() + ":" + yarnDependency.Details.Version
}

0 comments on commit 80aa9aa

Please sign in to comment.