Skip to content

Commit

Permalink
adjust install command in audit to not leave any traces in the direct…
Browse files Browse the repository at this point in the history
…ory upon executing 'install' command
  • Loading branch information
eranturgeman committed Mar 17, 2024
1 parent 5bc1339 commit 8741b37
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 4 deletions.
48 changes: 44 additions & 4 deletions commands/audit/sca/pnpm/pnpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package pnpm
import (
"encoding/json"
"errors"
"fmt"
biutils "github.com/jfrog/build-info-go/utils"
"os/exec"
"path/filepath"

Expand Down Expand Up @@ -46,10 +48,21 @@ func BuildDependencyTree(params utils.AuditParams) (dependencyTrees []*xrayUtils
return
}
// Build
if err = installProjectIfNeeded(pnpmExecPath, currentDir); errorutils.CheckError(err) != nil {
var tempDirForDependenciesCalculation string
if tempDirForDependenciesCalculation, err = installProjectIfNeeded(pnpmExecPath, currentDir); errorutils.CheckError(err) != nil {
return
}
return calculateDependencies(pnpmExecPath, currentDir, params)

var dirToCalcDependenciesOn string
if tempDirForDependenciesCalculation == "" {
dirToCalcDependenciesOn = currentDir
} else {
dirToCalcDependenciesOn = tempDirForDependenciesCalculation
defer func() {
err = errors.Join(err, biutils.RemoveTempDir(tempDirForDependenciesCalculation))
}()
}
return calculateDependencies(pnpmExecPath, dirToCalcDependenciesOn, params)
}

func getPnpmExecPath() (pnpmExecPath string, err error) {
Expand Down Expand Up @@ -77,7 +90,9 @@ func getPnpmCmd(pnpmExecPath, workingDir, cmd string, args ...string) *io.Comman
}

// Install is required when "pnpm-lock.yaml" lock file or "node_modules/.pnpm" directory not exists.
func installProjectIfNeeded(pnpmExecPath, workingDir string) (err error) {
// If "node_modules/.pnpm" doesn't exist we copy the project to a temporary dir and perform the 'install' on the copy, because we don't want to have node_modules in the original cloned
// Directory if it wasn't exist before
func installProjectIfNeeded(pnpmExecPath, workingDir string) (tempDirForDependenciesCalculation string, err error) {
lockFileExists, err := fileutils.IsFileExists(filepath.Join(workingDir, "pnpm-lock.yaml"), false)
if err != nil {
return
Expand All @@ -88,7 +103,32 @@ func installProjectIfNeeded(pnpmExecPath, workingDir string) (err error) {
}
// Install is needed
log.Debug("Installing Pnpm project:", workingDir)
return getPnpmCmd(pnpmExecPath, workingDir, "install", npm.IgnoreScriptsFlag).GetCmd().Run()
workingDirToRunInstallOn := workingDir

// If node_modules/.pnpm doesn't exist we clone the project to a temporary dir so the original project will not be effected by the newly added files of the 'install' command
if !pnpmDirExists {
tempDirForDependenciesCalculation, err = fileutils.CreateTempDir()
if err != nil {
err = fmt.Errorf("failed to create a temporary dir: %w", err)
return
}
defer func() {
// If we have an error for any reason we delete the temp dir
if err != nil {
err = errors.Join(err, fileutils.RemoveTempDir(tempDirForDependenciesCalculation))
}
}()

err = biutils.CopyDir(workingDir, tempDirForDependenciesCalculation, true, nil)
if err != nil {
err = fmt.Errorf("failed copying project to temp dir: %w", err)
return
}
workingDirToRunInstallOn = tempDirForDependenciesCalculation
}

err = getPnpmCmd(pnpmExecPath, workingDirToRunInstallOn, "install", npm.IgnoreScriptsFlag).GetCmd().Run()
return
}

// Run 'pnpm ls ...' command (project must be installed) and parse the returned result to create a dependencies trees for the projects.
Expand Down
24 changes: 24 additions & 0 deletions commands/audit/sca/pnpm/pnpm_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package pnpm

import (
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
"path/filepath"
"testing"

Expand Down Expand Up @@ -84,3 +86,25 @@ func TestBuildDependencyTree(t *testing.T) {
})
}
}

func TestInstallProjectIfNeeded(t *testing.T) {
_, cleanUp := sca.CreateTestWorkspace(t, filepath.Join("projects", "package-managers", "npm", "npm-no-lock"))
defer cleanUp()

currentDir, err := coreutils.GetWorkingDirectory()
assert.NoError(t, err)

pnpmExecPath, err := getPnpmExecPath()
assert.NoError(t, err)

tempDirForDependenciesCalculation, err := installProjectIfNeeded(pnpmExecPath, currentDir)

Check failure on line 100 in commands/audit/sca/pnpm/pnpm_test.go

View workflow job for this annotation

GitHub Actions / Static-Check

ineffectual assignment to err (ineffassign)
assert.NotEmpty(t, tempDirForDependenciesCalculation)

nodeModulesExist, err := fileutils.IsDirExists(filepath.Join(tempDirForDependenciesCalculation, "node_modules"), false)
assert.NoError(t, err)
assert.True(t, nodeModulesExist)

nodeModulesExist, err = fileutils.IsDirExists(filepath.Join(currentDir, "node_modules"), false)
assert.NoError(t, err)
assert.False(t, nodeModulesExist)
}

0 comments on commit 8741b37

Please sign in to comment.