diff --git a/action/node_modules/.package-lock.json b/action/node_modules/.package-lock.json
index d5a139759..b61afb6da 100644
--- a/action/node_modules/.package-lock.json
+++ b/action/node_modules/.package-lock.json
@@ -1,7 +1,7 @@
{
"name": "@jfrog/frogbot",
"version": "1.0.0",
- "lockfileVersion": 2,
+ "lockfileVersion": 3,
"requires": true,
"packages": {
"node_modules/@actions/core": {
diff --git a/packagehandlers/commonpackagehandler.go b/packagehandlers/commonpackagehandler.go
index 7d9129616..b30e39237 100644
--- a/packagehandlers/commonpackagehandler.go
+++ b/packagehandlers/commonpackagehandler.go
@@ -14,7 +14,7 @@ type PackageHandler interface {
UpdateDependency(details *utils.VulnerabilityDetails) error
}
-func GetCompatiblePackageHandler(vulnDetails *utils.VulnerabilityDetails, details *utils.ScanDetails) (handler PackageHandler) {
+func GetCompatiblePackageHandler(vulnDetails *utils.VulnerabilityDetails, details *utils.RepositoryScanDetails) (handler PackageHandler) {
switch vulnDetails.Technology {
case coreutils.Go:
handler = &GoPackageHandler{}
@@ -27,9 +27,9 @@ func GetCompatiblePackageHandler(vulnDetails *utils.VulnerabilityDetails, detail
case coreutils.Yarn:
handler = &YarnPackageHandler{}
case coreutils.Pip:
- handler = &PythonPackageHandler{pipRequirementsFile: details.PipRequirementsFile}
+ handler = &PythonPackageHandler{pipRequirementsFile: details.Project().PipRequirementsFile}
case coreutils.Maven:
- handler = &MavenPackageHandler{depsRepo: details.DepsRepo, ServerDetails: details.ServerDetails}
+ handler = &MavenPackageHandler{depsRepo: details.Project().DepsRepo, ServerDetails: details.ServerDetails()}
case coreutils.Nuget:
handler = &NugetPackageHandler{}
default:
diff --git a/packagehandlers/packagehandlers_test.go b/packagehandlers/packagehandlers_test.go
index a3dc10539..8ac224b07 100644
--- a/packagehandlers/packagehandlers_test.go
+++ b/packagehandlers/packagehandlers_test.go
@@ -18,7 +18,7 @@ import (
type dependencyFixTest struct {
vulnDetails *utils.VulnerabilityDetails
- scanDetails *utils.ScanDetails
+ project *utils.Project
fixSupported bool
specificTechVersion string
uniqueChecksExtraArgs []string
@@ -74,7 +74,7 @@ func TestUpdateDependency(t *testing.T) {
SuggestedFixedVersion: "1.25.9",
VulnerabilityOrViolationRow: formats.VulnerabilityOrViolationRow{Technology: coreutils.Pip, ImpactedDependencyName: "urllib3"},
},
- scanDetails: &utils.ScanDetails{Project: &utils.Project{PipRequirementsFile: "requirements.txt"}},
+ project: &utils.Project{PipRequirementsFile: "requirements.txt"},
fixSupported: false,
},
{
@@ -82,7 +82,7 @@ func TestUpdateDependency(t *testing.T) {
SuggestedFixedVersion: "1.25.9",
VulnerabilityOrViolationRow: formats.VulnerabilityOrViolationRow{Technology: coreutils.Poetry, ImpactedDependencyName: "urllib3"},
},
- scanDetails: &utils.ScanDetails{Project: &utils.Project{PipRequirementsFile: "pyproejct.toml"}},
+ project: &utils.Project{PipRequirementsFile: "pyproejct.toml"},
fixSupported: false,
},
{
@@ -90,7 +90,7 @@ func TestUpdateDependency(t *testing.T) {
SuggestedFixedVersion: "1.25.9",
VulnerabilityOrViolationRow: formats.VulnerabilityOrViolationRow{Technology: coreutils.Pipenv, ImpactedDependencyName: "urllib3"},
},
- scanDetails: &utils.ScanDetails{Project: &utils.Project{PipRequirementsFile: "Pipfile"}},
+ project: &utils.Project{PipRequirementsFile: "Pipfile"},
fixSupported: false,
},
{
@@ -99,7 +99,7 @@ func TestUpdateDependency(t *testing.T) {
VulnerabilityOrViolationRow: formats.VulnerabilityOrViolationRow{Technology: coreutils.Pip, ImpactedDependencyName: "pyjwt"},
IsDirectDependency: true,
},
- scanDetails: &utils.ScanDetails{Project: &utils.Project{PipRequirementsFile: "requirements.txt"}},
+ project: &utils.Project{PipRequirementsFile: "requirements.txt"},
fixSupported: true,
},
{
@@ -107,7 +107,7 @@ func TestUpdateDependency(t *testing.T) {
SuggestedFixedVersion: "2.4.0",
VulnerabilityOrViolationRow: formats.VulnerabilityOrViolationRow{Technology: coreutils.Pip, ImpactedDependencyName: "Pyjwt"},
IsDirectDependency: true},
- scanDetails: &utils.ScanDetails{Project: &utils.Project{PipRequirementsFile: "requirements.txt"}},
+ project: &utils.Project{PipRequirementsFile: "requirements.txt"},
fixSupported: true,
},
{
@@ -115,7 +115,7 @@ func TestUpdateDependency(t *testing.T) {
SuggestedFixedVersion: "2.4.0",
VulnerabilityOrViolationRow: formats.VulnerabilityOrViolationRow{Technology: coreutils.Pip, ImpactedDependencyName: "pyjwt"},
IsDirectDependency: true},
- scanDetails: &utils.ScanDetails{Project: &utils.Project{PipRequirementsFile: "setup.py"}},
+ project: &utils.Project{PipRequirementsFile: "setup.py"},
fixSupported: true,
},
{
@@ -123,7 +123,7 @@ func TestUpdateDependency(t *testing.T) {
SuggestedFixedVersion: "2.4.0",
VulnerabilityOrViolationRow: formats.VulnerabilityOrViolationRow{Technology: coreutils.Poetry, ImpactedDependencyName: "pyjwt"},
IsDirectDependency: true},
- scanDetails: &utils.ScanDetails{Project: &utils.Project{PipRequirementsFile: "pyproject.toml"}},
+ project: &utils.Project{PipRequirementsFile: "pyproject.toml"},
fixSupported: true,
},
},
@@ -185,7 +185,7 @@ func TestUpdateDependency(t *testing.T) {
SuggestedFixedVersion: "2.7",
VulnerabilityOrViolationRow: formats.VulnerabilityOrViolationRow{Technology: coreutils.Maven, ImpactedDependencyName: "commons-io:commons-io"},
IsDirectDependency: true},
- scanDetails: &utils.ScanDetails{Project: &utils.Project{DepsRepo: ""}, ServerDetails: nil},
+ project: &utils.Project{DepsRepo: ""},
fixSupported: true,
},
{
@@ -193,7 +193,7 @@ func TestUpdateDependency(t *testing.T) {
SuggestedFixedVersion: "4.3.20",
VulnerabilityOrViolationRow: formats.VulnerabilityOrViolationRow{Technology: coreutils.Maven, ImpactedDependencyName: "org.springframework:spring-core"},
IsDirectDependency: false},
- scanDetails: &utils.ScanDetails{Project: &utils.Project{DepsRepo: ""}, ServerDetails: nil},
+ project: &utils.Project{DepsRepo: ""},
fixSupported: false,
},
},
@@ -222,7 +222,11 @@ func TestUpdateDependency(t *testing.T) {
for _, testBatch := range testCases {
for _, test := range testBatch {
- packageHandler := GetCompatiblePackageHandler(test.vulnDetails, test.scanDetails)
+ repositoryScanDetails := utils.NewRepositoryScanDetails(nil, nil)
+ if test.project != nil {
+ repositoryScanDetails.SetProject(test.project)
+ }
+ packageHandler := GetCompatiblePackageHandler(test.vulnDetails, repositoryScanDetails)
t.Run(fmt.Sprintf("%s:%s direct:%s", test.vulnDetails.Technology.ToString()+test.specificTechVersion, test.vulnDetails.ImpactedDependencyName, strconv.FormatBool(test.vulnDetails.IsDirectDependency)),
func(t *testing.T) {
testDataDir := getTestDataDir(t, test.vulnDetails.IsDirectDependency)
diff --git a/scanpullrequest/scanpullrequest.go b/scanpullrequest/scanpullrequest.go
index 757e817e9..8802768b6 100644
--- a/scanpullrequest/scanpullrequest.go
+++ b/scanpullrequest/scanpullrequest.go
@@ -164,18 +164,13 @@ func auditPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient,
err = errors.Join(err, cleanupSource(), cleanupTarget())
}()
- scanDetails := utils.NewScanDetails(client, &repoConfig.Server, &repoConfig.Git).
- SetXrayGraphScanParams(repoConfig.Watches, repoConfig.JFrogProjectKey).
- SetMinSeverity(repoConfig.MinSeverity).
- SetFixableOnly(repoConfig.FixableOnly).
- SetFailOnInstallationErrors(*repoConfig.FailOnSecurityIssues)
-
+ scanDetails := utils.NewPullRequestScanDetails(client, repoConfig)
for i := range repoConfig.Projects {
scanDetails.SetProject(&repoConfig.Projects[i])
// Audit source branch
var sourceResults *audit.Results
- workingDirs := utils.GetFullPathWorkingDirs(scanDetails.Project.WorkingDirs, sourceBranchWd)
+ workingDirs := utils.GetFullPathWorkingDirs(scanDetails.Project().WorkingDirs, sourceBranchWd)
sourceResults, err = scanDetails.RunInstallAndAudit(workingDirs...)
if err != nil {
return
@@ -202,7 +197,7 @@ func auditPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient,
// Set target branch scan details
var targetResults *audit.Results
- workingDirs = utils.GetFullPathWorkingDirs(scanDetails.Project.WorkingDirs, targetBranchWd)
+ workingDirs = utils.GetFullPathWorkingDirs(scanDetails.Project().WorkingDirs, targetBranchWd)
targetResults, err = scanDetails.RunInstallAndAudit(workingDirs...)
if err != nil {
diff --git a/scanrepository/scanrepository.go b/scanrepository/scanrepository.go
index 03f3444dd..82b7bffe8 100644
--- a/scanrepository/scanrepository.go
+++ b/scanrepository/scanrepository.go
@@ -32,13 +32,11 @@ type ScanRepositoryCmd struct {
// When dryRun is enabled, dryRunRepoPath specifies the repository local path to clone
dryRunRepoPath string
// The scanDetails of the current scan
- scanDetails *utils.ScanDetails
+ scanDetails *utils.RepositoryScanDetails
// The base working directory
baseWd string
// The git client the command performs git operations with
gitManager *utils.GitManager
- // Determines whether to open a pull request for each vulnerability fix or to aggregate all fixes into one pull request
- aggregateFixes bool
// The current project technology
projectTech coreutils.Technology
// Stores all package manager handlers for detected issues
@@ -58,7 +56,6 @@ func (cfp *ScanRepositoryCmd) scanAndFixRepository(repository *utils.Repository,
if err = cfp.setCommandPrerequisites(repository, branch, client); err != nil {
return
}
- cfp.scanDetails.SetXscGitInfoContext(branch, repository.Project, client)
if err = cfp.scanAndFixBranch(repository); err != nil {
return
}
@@ -80,7 +77,7 @@ func (cfp *ScanRepositoryCmd) scanAndFixBranch(repository *utils.Repository) (er
err = errors.Join(err, restoreBaseDir(), fileutils.RemoveTempDir(clonedRepoDir))
}()
for i := range repository.Projects {
- cfp.scanDetails.Project = &repository.Projects[i]
+ cfp.scanDetails.SetProject(&repository.Projects[i])
cfp.projectTech = ""
if err = cfp.scanAndFixProject(repository); err != nil {
return
@@ -90,29 +87,28 @@ func (cfp *ScanRepositoryCmd) scanAndFixBranch(repository *utils.Repository) (er
}
func (cfp *ScanRepositoryCmd) setCommandPrerequisites(repository *utils.Repository, branch string, client vcsclient.VcsClient) (err error) {
-
- cfp.scanDetails = utils.NewScanDetails(client, &repository.Server, &repository.Git).
- SetXrayGraphScanParams(repository.Watches, repository.JFrogProjectKey).
- SetFailOnInstallationErrors(*repository.FailOnSecurityIssues).
- SetBaseBranch(branch).
- SetFixableOnly(repository.FixableOnly).
- SetMinSeverity(repository.MinSeverity)
-
- cfp.aggregateFixes = repository.Git.AggregateFixes
cfp.OutputWriter = outputwriter.GetCompatibleOutputWriter(repository.GitProvider)
- repositoryInfo, err := client.GetRepositoryInfo(context.Background(), cfp.scanDetails.RepoOwner, cfp.scanDetails.RepoName)
+ repositoryInfo, err := client.GetRepositoryInfo(context.Background(), repository.RepoOwner, repository.RepoName)
if err != nil {
return
}
- cfp.scanDetails.Git.RepositoryCloneUrl = repositoryInfo.CloneInfo.HTTP
+
+ cfp.scanDetails = utils.NewRepositoryScanDetails(client, repository).
+ SetBaseBranch(branch).
+ SetAggregateFixes(repository.Git.AggregateFixes).
+ SetRepositoryCloneUrl(repositoryInfo.CloneInfo.HTTP).
+ SetXscGitInfoContext(branch, repository.Project, client)
+
cfp.gitManager, err = utils.NewGitManager().
- SetAuth(cfp.scanDetails.Username, cfp.scanDetails.Token).
+ SetAuth(cfp.scanDetails.VcsInfo().Username, cfp.scanDetails.VcsInfo().Username).
SetDryRun(cfp.dryRun, cfp.dryRunRepoPath).
- SetRemoteGitUrl(cfp.scanDetails.Git.RepositoryCloneUrl)
+ SetEmailAuthor(repository.EmailAuthor).
+ SetRemoteGitUrl(repositoryInfo.CloneInfo.HTTP)
if err != nil {
return
}
- _, err = cfp.gitManager.SetGitParams(cfp.scanDetails.Git)
+ customTemplates := utils.NewCustomTemplates(repository.CommitMessageTemplate, repository.BranchNameTemplate, repository.PullRequestTitleTemplate)
+ cfp.gitManager, err = cfp.gitManager.SetTemplates(customTemplates)
return
}
@@ -122,7 +118,7 @@ func (cfp *ScanRepositoryCmd) scanAndFixProject(repository *utils.Repository) er
// The value is a map of vulnerable package names -> the scanDetails of the vulnerable packages.
// That means we have a map of all the vulnerabilities that were found in a specific folder, along with their full scanDetails.
vulnerabilitiesByPathMap := make(map[string]map[string]*utils.VulnerabilityDetails)
- projectFullPathWorkingDirs := utils.GetFullPathWorkingDirs(cfp.scanDetails.Project.WorkingDirs, cfp.baseWd)
+ projectFullPathWorkingDirs := utils.GetFullPathWorkingDirs(cfp.scanDetails.Project().WorkingDirs, cfp.baseWd)
for _, fullPathWd := range projectFullPathWorkingDirs {
scanResults, err := cfp.scan(fullPathWd)
if err != nil {
@@ -132,7 +128,7 @@ func (cfp *ScanRepositoryCmd) scanAndFixProject(repository *utils.Repository) er
if repository.GitProvider.String() == vcsutils.GitHub.String() {
// Uploads Sarif results to GitHub in order to view the scan in the code scanning UI
// Currently available on GitHub only
- if err = utils.UploadSarifResultsToGithubSecurityTab(scanResults, repository, cfp.scanDetails.BaseBranch(), cfp.scanDetails.Client()); err != nil {
+ if err = utils.UploadSarifResultsToGithubSecurityTab(scanResults, repository, cfp.scanDetails.BaseBranch(), cfp.scanDetails.GitClient()); err != nil {
log.Warn(err)
}
}
@@ -181,7 +177,7 @@ func (cfp *ScanRepositoryCmd) getVulnerabilitiesMap(scanResults *xrayutils.Exten
}
func (cfp *ScanRepositoryCmd) fixVulnerablePackages(vulnerabilitiesByWdMap map[string]map[string]*utils.VulnerabilityDetails) (err error) {
- if cfp.aggregateFixes {
+ if cfp.scanDetails.AggregateFixes() {
return cfp.fixIssuesSinglePR(vulnerabilitiesByWdMap)
}
return cfp.fixIssuesSeparatePRs(vulnerabilitiesByWdMap)
@@ -334,7 +330,7 @@ func (cfp *ScanRepositoryCmd) openFixingPullRequest(fixBranchName string, vulnDe
return
}
log.Debug("Creating Pull Request form:", fixBranchName, " to:", cfp.scanDetails.BaseBranch())
- return cfp.scanDetails.Client().CreatePullRequest(context.Background(), cfp.scanDetails.RepoOwner, cfp.scanDetails.RepoName, fixBranchName, cfp.scanDetails.BaseBranch(), pullRequestTitle, prBody)
+ return cfp.scanDetails.GitClient().CreatePullRequest(context.Background(), cfp.scanDetails.RepoOwner(), cfp.scanDetails.RepoName(), fixBranchName, cfp.scanDetails.BaseBranch(), pullRequestTitle, prBody)
}
// openAggregatedPullRequest handles the opening or updating of a pull request when the aggregate mode is active.
@@ -353,20 +349,20 @@ func (cfp *ScanRepositoryCmd) openAggregatedPullRequest(fixBranchName string, pu
}
if pullRequestInfo == nil {
log.Info("Creating Pull Request from:", fixBranchName, "to:", cfp.scanDetails.BaseBranch())
- return cfp.scanDetails.Client().CreatePullRequest(context.Background(), cfp.scanDetails.RepoOwner, cfp.scanDetails.RepoName, fixBranchName, cfp.scanDetails.BaseBranch(), pullRequestTitle, prBody)
+ return cfp.scanDetails.GitClient().CreatePullRequest(context.Background(), cfp.scanDetails.RepoOwner(), cfp.scanDetails.RepoName(), fixBranchName, cfp.scanDetails.BaseBranch(), pullRequestTitle, prBody)
}
log.Info("Updating Pull Request from:", fixBranchName, "to:", cfp.scanDetails.BaseBranch())
- return cfp.scanDetails.Client().UpdatePullRequest(context.Background(), cfp.scanDetails.RepoOwner, cfp.scanDetails.RepoName, pullRequestTitle, prBody, pullRequestInfo.Target.Name, int(pullRequestInfo.ID), vcsutils.Open)
+ return cfp.scanDetails.GitClient().UpdatePullRequest(context.Background(), cfp.scanDetails.RepoOwner(), cfp.scanDetails.RepoName(), pullRequestTitle, prBody, "", int(pullRequestInfo.ID), vcsutils.Open)
}
func (cfp *ScanRepositoryCmd) preparePullRequestDetails(vulnerabilitiesDetails ...*utils.VulnerabilityDetails) (string, string, error) {
- if cfp.dryRun && cfp.aggregateFixes {
+ if cfp.dryRun && cfp.scanDetails.AggregateFixes() {
// For testings, don't compare pull request body as scan results order may change.
return outputwriter.GetAggregatedPullRequestTitle(cfp.projectTech), "", nil
}
vulnerabilitiesRows := utils.ExtractVulnerabilitiesDetailsToRows(vulnerabilitiesDetails)
prBody := cfp.OutputWriter.VulnerabilitiesTitle(false) + "\n" + cfp.OutputWriter.VulnerabilitiesContent(vulnerabilitiesRows) + "\n---\n" + cfp.OutputWriter.UntitledForJasMsg() + cfp.OutputWriter.Footer()
- if cfp.aggregateFixes {
+ if cfp.scanDetails.AggregateFixes() {
scanHash, err := utils.VulnerabilityDetailsToMD5Hash(vulnerabilitiesRows...)
if err != nil {
return "", "", err
@@ -381,7 +377,7 @@ func (cfp *ScanRepositoryCmd) preparePullRequestDetails(vulnerabilitiesDetails .
func (cfp *ScanRepositoryCmd) cloneRepositoryAndCheckoutToBranch() (tempWd string, restoreDir func() error, err error) {
if cfp.dryRun {
- tempWd = filepath.Join(cfp.dryRunRepoPath, cfp.scanDetails.RepoName)
+ tempWd = filepath.Join(cfp.dryRunRepoPath, cfp.scanDetails.RepoName())
} else {
// Create temp working directory
if tempWd, err = fileutils.CreateTempDir(); err != nil {
@@ -500,7 +496,7 @@ func (cfp *ScanRepositoryCmd) getRemoteBranchScanHash(prBody string) string {
}
func (cfp *ScanRepositoryCmd) getOpenPullRequestBySourceBranch(branchName string) (prInfo *vcsclient.PullRequestInfo, err error) {
- list, err := cfp.scanDetails.Client().ListOpenPullRequestsWithBody(context.Background(), cfp.scanDetails.RepoOwner, cfp.scanDetails.RepoName)
+ list, err := cfp.scanDetails.GitClient().ListOpenPullRequestsWithBody(context.Background(), cfp.scanDetails.RepoOwner(), cfp.scanDetails.RepoName())
if err != nil {
return
}
diff --git a/scanrepository/scanrepository_test.go b/scanrepository/scanrepository_test.go
index a8dc66448..5a278a21a 100644
--- a/scanrepository/scanrepository_test.go
+++ b/scanrepository/scanrepository_test.go
@@ -115,8 +115,9 @@ func TestScanRepositoryCmd_Run(t *testing.T) {
testName: "aggregate-cant-fix",
expectedPackagesInBranch: map[string][]string{"frogbot-update-pip-dependencies": {}},
expectedVersionUpdatesInBranch: map[string][]string{"frogbot-update-pip-dependencies": {}},
- packageDescriptorPaths: []string{"setup.py"}, // This is a build tool dependency which should not be fixed
- aggregateFixes: true,
+ // This is a build tool dependency that should not be fixed
+ packageDescriptorPaths: []string{"setup.py"},
+ aggregateFixes: true,
},
{
testName: "non-aggregate",
@@ -365,7 +366,7 @@ func TestPackageTypeFromScan(t *testing.T) {
Params: params,
}
for _, pkg := range testPackagesData {
- // Create temp technology project
+ // Create a temp technology project
projectPath := filepath.Join("..", "testdata", "projects", pkg.packageType)
t.Run(pkg.packageType, func(t *testing.T) {
tmpDir, err := fileutils.CreateTempDir()
@@ -379,22 +380,18 @@ func TestPackageTypeFromScan(t *testing.T) {
assert.NoError(t, os.Chmod(filepath.Join(tmpDir, "gradlew.bat"), 0777))
}
frogbotParams.Projects[0].WorkingDirs = []string{tmpDir}
- files, err := fileutils.ListFiles(tmpDir, true)
- assert.NoError(t, err)
- for _, file := range files {
- log.Info(file)
- }
frogbotParams.Projects[0].InstallCommandName = pkg.commandName
frogbotParams.Projects[0].InstallCommandArgs = pkg.commandArgs
- scanSetup := utils.ScanDetails{
- XrayGraphScanParams: &services.XrayGraphScanParams{},
- Project: &frogbotParams.Projects[0],
- ServerDetails: &frogbotParams.Server,
- }
- testScan.scanDetails = &scanSetup
+ scanDetails := utils.NewRepositoryScanDetails(nil, nil)
+ scanDetails.SetProject(&frogbotParams.Projects[0]).SetServerDetails(&frogbotParams.Server).SetXrayGraphScanParams(nil, "")
+ testScan.scanDetails = scanDetails
scanResponse, err := testScan.scan(tmpDir)
assert.NoError(t, err)
- verifyTechnologyNaming(t, scanResponse.ExtendedScanResults.XrayResults, pkg.packageType)
+ packageName := pkg.packageType
+ if pkg.commandName != "" {
+ packageName = pkg.commandName
+ }
+ verifyTechnologyNaming(t, scanResponse.ExtendedScanResults.XrayResults, packageName)
})
}
}
@@ -659,7 +656,7 @@ random body
}
func TestPreparePullRequestDetails(t *testing.T) {
- cfp := ScanRepositoryCmd{OutputWriter: &outputwriter.StandardOutput{}, gitManager: &utils.GitManager{}}
+ cfp := ScanRepositoryCmd{OutputWriter: &outputwriter.StandardOutput{}, gitManager: &utils.GitManager{}, scanDetails: utils.NewRepositoryScanDetails(nil, nil)}
vulnerabilities := []*utils.VulnerabilityDetails{
{
VulnerabilityOrViolationRow: formats.VulnerabilityOrViolationRow{
@@ -689,7 +686,7 @@ func TestPreparePullRequestDetails(t *testing.T) {
},
SuggestedFixedVersion: "2.0.0",
})
- cfp.aggregateFixes = true
+ cfp.scanDetails.SetAggregateFixes(true)
expectedPrBody = "
\n\n[![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/v2/vulnerabilitiesFixBannerPR.png)](https://github.com/jfrog/frogbot#readme)\n\n
\n\n\n\n## 📦 Vulnerable Dependencies \n\n### ✍️ Summary\n\n\n\n\n| SEVERITY | DIRECT DEPENDENCIES | IMPACTED DEPENDENCY | FIXED VERSIONS | CVES |\n| :---------------------: | :----------------------------------: | :-----------------------------------: | :---------------------------------: | :---------------------------------: | \n| ![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/v2/applicableHighSeverity.png)
High | | package1:1.0.0 | 1.0.0
2.0.0 | CVE-2022-1234 |\n| ![](https://raw.githubusercontent.com/jfrog/frogbot/master/resources/v2/applicableCriticalSeverity.png)
Critical | | package2:2.0.0 | 2.0.0
3.0.0 | CVE-2022-4321 |\n\n
\n\n## 👇 Details\n\n\n [ CVE-2022-1234 ] package1 1.0.0
\n
\n\n**Description:**\nsummary\n\n\n \n\n\n\n [ CVE-2022-4321 ] package2 2.0.0
\n
\n\n**Description:**\nsummary\n\n\n \n\n\n---\n\n\n\n**Frogbot** also supports **Contextual Analysis, Secret Detection and IaC Vulnerabilities Scanning**. This features are included as part of the [JFrog Advanced Security](https://jfrog.com/xray/) package, which isn't enabled on your system.\n\n
\n\n---\n\n\n[🐸 JFrog Frogbot](https://github.com/jfrog/frogbot#readme)\n\n
\n\n[comment]: <> (Checksum: bec823edaceb5d0478b789798e819bde)\n"
prTitle, prBody, err = cfp.preparePullRequestDetails(vulnerabilities...)
assert.NoError(t, err)
diff --git a/utils/depsutil.go b/utils/depsutil.go
index 6e5fe1cea..b1845a572 100644
--- a/utils/depsutil.go
+++ b/utils/depsutil.go
@@ -27,9 +27,9 @@ var MapTechToResolvingFunc = map[string]resolveDependenciesFunc{
const yarnV2Version = "2.0.0"
-func resolveNpmDependencies(scanSetup *ScanDetails) (output []byte, err error) {
- npmCmd := npm.NewNpmCommand(scanSetup.InstallCommandArgs[0], false).SetServerDetails(scanSetup.ServerDetails)
- if err = npmCmd.PreparePrerequisites(scanSetup.DepsRepo); err != nil {
+func resolveNpmDependencies(scanDetails *ScanDetails) (output []byte, err error) {
+ npmCmd := npm.NewNpmCommand(scanDetails.project.InstallCommandArgs[0], false).SetServerDetails(&scanDetails.serverDetails)
+ if err = npmCmd.PreparePrerequisites(scanDetails.project.DepsRepo); err != nil {
return nil, err
}
if err = npmCmd.CreateTempNpmrc(); err != nil {
@@ -41,10 +41,10 @@ func resolveNpmDependencies(scanSetup *ScanDetails) (output []byte, err error) {
err = restoreNpmrc()
}
}()
- return exec.Command(coreutils.Npm.ToString(), scanSetup.InstallCommandArgs...).CombinedOutput()
+ return exec.Command(coreutils.Npm.ToString(), scanDetails.project.InstallCommandArgs...).CombinedOutput()
}
-func resolveYarnDependencies(scanSetup *ScanDetails) (output []byte, err error) {
+func resolveYarnDependencies(scanDetails *ScanDetails) (output []byte, err error) {
currWd, err := coreutils.GetWorkingDirectory()
if err != nil {
return nil, err
@@ -70,7 +70,7 @@ func resolveYarnDependencies(scanSetup *ScanDetails) (output []byte, err error)
return nil, err
}
- registry, repoAuthIdent, err := yarn.GetYarnAuthDetails(scanSetup.ServerDetails, scanSetup.DepsRepo)
+ registry, repoAuthIdent, err := yarn.GetYarnAuthDetails(&scanDetails.serverDetails, scanDetails.project.DepsRepo)
if err != nil {
return nil, yarn.RestoreConfigurationsAndError(nil, restoreYarnrcFunc, err)
}
@@ -84,10 +84,10 @@ func resolveYarnDependencies(scanSetup *ScanDetails) (output []byte, err error)
err = e
}
}()
- return nil, build.RunYarnCommand(yarnExecPath, currWd, scanSetup.InstallCommandArgs...)
+ return nil, build.RunYarnCommand(yarnExecPath, currWd, scanDetails.project.InstallCommandArgs...)
}
-func resolveDotnetDependencies(scanSetup *ScanDetails) (output []byte, err error) {
+func resolveDotnetDependencies(scanDetails *ScanDetails) (output []byte, err error) {
wd, err := fileutils.CreateTempDir()
if err != nil {
return
@@ -98,12 +98,12 @@ func resolveDotnetDependencies(scanSetup *ScanDetails) (output []byte, err error
err = e
}
}()
- configFile, err := dotnet.InitNewConfig(wd, scanSetup.DepsRepo, scanSetup.ServerDetails, false)
+ configFile, err := dotnet.InitNewConfig(wd, scanDetails.project.DepsRepo, &scanDetails.serverDetails, false)
if err != nil {
return
}
- toolType := dotnetutils.ConvertNameToToolType(scanSetup.InstallCommandName)
- args := scanSetup.InstallCommandArgs
+ toolType := dotnetutils.ConvertNameToToolType(scanDetails.project.InstallCommandName)
+ args := scanDetails.project.InstallCommandArgs
args = append(args, toolType.GetTypeFlagPrefix()+"configfile", configFile.Name())
return exec.Command(toolType.String(), args...).CombinedOutput()
}
diff --git a/utils/depsutil_test.go b/utils/depsutil_test.go
index cf80488a2..2a129e813 100644
--- a/utils/depsutil_test.go
+++ b/utils/depsutil_test.go
@@ -89,57 +89,49 @@ func TestResolveDependencies(t *testing.T) {
testCases := []struct {
name string
tech string
- scanSetup *ScanDetails
+ project Project
repoKey string
- resolveFunc func(scanSetup *ScanDetails) ([]byte, error)
+ resolveFunc func(scanDetails *ScanDetails) ([]byte, error)
shouldExpectError bool
}{
{
name: "Resolve NPM dependencies",
tech: "npm",
- scanSetup: &ScanDetails{
- ServerDetails: ¶ms,
- Project: &Project{
- InstallCommandName: "npm",
- InstallCommandArgs: []string{"install"},
- }},
+ project: Project{
+ InstallCommandName: "npm",
+ InstallCommandArgs: []string{"install"},
+ },
resolveFunc: resolveNpmDependencies,
shouldExpectError: false,
},
{
name: "Resolve Yarn V2 dependencies",
tech: "yarn2",
- scanSetup: &ScanDetails{
- ServerDetails: ¶ms,
- Project: &Project{
- InstallCommandName: "yarn",
- InstallCommandArgs: []string{"install"},
- }},
+ project: Project{
+ InstallCommandName: "yarn",
+ InstallCommandArgs: []string{"install"},
+ },
resolveFunc: resolveYarnDependencies,
shouldExpectError: false,
},
{
name: "Resolve Yarn V1 dependencies",
tech: "yarn1",
- scanSetup: &ScanDetails{
- ServerDetails: ¶ms,
- Project: &Project{
- InstallCommandName: "yarn",
- InstallCommandArgs: []string{"install"},
- }},
+ project: Project{
+ InstallCommandName: "yarn",
+ InstallCommandArgs: []string{"install"},
+ },
resolveFunc: resolveYarnDependencies,
shouldExpectError: true,
},
{
name: "Resolve .NET dependencies",
tech: "dotnet",
- scanSetup: &ScanDetails{
- ServerDetails: ¶ms,
- Project: &Project{
- DepsRepo: "frogbot-nuget-remote-tests",
- InstallCommandName: "dotnet",
- InstallCommandArgs: []string{"restore"},
- }},
+ project: Project{
+ DepsRepo: "frogbot-nuget-remote-tests",
+ InstallCommandName: "dotnet",
+ InstallCommandArgs: []string{"restore"},
+ },
resolveFunc: resolveDotnetDependencies,
shouldExpectError: false,
},
@@ -149,8 +141,9 @@ func TestResolveDependencies(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
restoreFunc, repoKey := setTestEnvironment(t, test.tech, ¶ms)
defer restoreFunc()
- test.scanSetup.Project.DepsRepo = repoKey
- output, err := test.resolveFunc(test.scanSetup)
+ scanDetails := &ScanDetails{project: test.project, serverDetails: params}
+ scanDetails.project.DepsRepo = repoKey
+ output, err := test.resolveFunc(scanDetails)
if test.shouldExpectError {
assert.Error(t, err)
} else {
diff --git a/utils/git.go b/utils/git.go
index 77b3d711c..8f97d7af8 100644
--- a/utils/git.go
+++ b/utils/git.go
@@ -44,12 +44,10 @@ type GitManager struct {
dryRun bool
// When dryRun is enabled, dryRunRepoPath specifies the repository local path to clone
dryRunRepoPath string
- // When dryRun is enabled, skipClone allows skipping the cloning of a repository for testing purposes
- SkipClone bool
// Custom naming formats
customTemplates CustomTemplates
- // Git details
- git *Git
+ // Email author of the commits
+ emailAuthor string
}
type CustomTemplates struct {
@@ -61,6 +59,14 @@ type CustomTemplates struct {
pullRequestTitleTemplate string
}
+func NewCustomTemplates(commitMessage, branchName, prTitle string) *CustomTemplates {
+ return &CustomTemplates{
+ commitMessageTemplate: commitMessage,
+ branchNameTemplate: branchName,
+ pullRequestTitleTemplate: prTitle,
+ }
+}
+
func NewGitManager() *GitManager {
setGoGitCustomClient()
return &GitManager{}
@@ -117,12 +123,11 @@ func (gm *GitManager) SetLocalRepository() (*GitManager, error) {
return gm, err
}
-func (gm *GitManager) SetGitParams(gitParams *Git) (*GitManager, error) {
+func (gm *GitManager) SetTemplates(templates *CustomTemplates) (*GitManager, error) {
var err error
- if gm.customTemplates, err = loadCustomTemplates(gitParams.CommitMessageTemplate, gitParams.BranchNameTemplate, gitParams.PullRequestTitleTemplate); err != nil {
+ if gm.customTemplates, err = loadCustomTemplates(templates.commitMessageTemplate, templates.branchNameTemplate, templates.pullRequestTitleTemplate); err != nil {
return nil, err
}
- gm.git = gitParams
return gm, nil
}
@@ -132,6 +137,11 @@ func (gm *GitManager) SetDryRun(dryRun bool, dryRunRepoPath string) *GitManager
return gm
}
+func (gm *GitManager) SetEmailAuthor(emailAuthor string) *GitManager {
+ gm.emailAuthor = emailAuthor
+ return gm
+}
+
func (gm *GitManager) Checkout(branchName string) error {
log.Debug("Running git checkout to branch:", branchName)
if err := gm.createBranchAndCheckout(branchName, false); err != nil {
@@ -252,7 +262,7 @@ func (gm *GitManager) commit(commitMessage string) error {
_, err = worktree.Commit(commitMessage, &git.CommitOptions{
Author: &object.Signature{
Name: frogbotAuthorName,
- Email: gm.git.EmailAuthor,
+ Email: gm.emailAuthor,
When: time.Now(),
},
})
diff --git a/utils/pullrequestscandetails.go b/utils/pullrequestscandetails.go
new file mode 100644
index 000000000..03e46d046
--- /dev/null
+++ b/utils/pullrequestscandetails.go
@@ -0,0 +1,17 @@
+package utils
+
+import (
+ "github.com/jfrog/froggit-go/vcsclient"
+)
+
+type PullRequestScanDetails struct {
+ *ScanDetails
+}
+
+func NewPullRequestScanDetails(client vcsclient.VcsClient, repository *Repository) *PullRequestScanDetails {
+ return &PullRequestScanDetails{ScanDetails: newScanDetails(client, repository)}
+}
+
+func (prd *PullRequestScanDetails) PullRequestDetails() vcsclient.PullRequestInfo {
+ return prd.git.PullRequestDetails
+}
diff --git a/utils/repositoryscandetails.go b/utils/repositoryscandetails.go
new file mode 100644
index 000000000..6867ec5d8
--- /dev/null
+++ b/utils/repositoryscandetails.go
@@ -0,0 +1,122 @@
+package utils
+
+import (
+ "context"
+ "fmt"
+ "github.com/jfrog/froggit-go/vcsclient"
+ "github.com/jfrog/froggit-go/vcsutils"
+ "github.com/jfrog/jfrog-client-go/utils/log"
+ "github.com/jfrog/jfrog-client-go/xray/services"
+)
+
+type RepositoryScanDetails struct {
+ *ScanDetails
+ baseBranch string
+}
+
+func NewRepositoryScanDetails(client vcsclient.VcsClient, repository *Repository) *RepositoryScanDetails {
+ return &RepositoryScanDetails{ScanDetails: newScanDetails(client, repository)}
+}
+
+func (rsd *RepositoryScanDetails) SetBaseBranch(branch string) *RepositoryScanDetails {
+ rsd.baseBranch = branch
+ return rsd
+}
+
+func (rsd *RepositoryScanDetails) BaseBranch() string {
+ return rsd.baseBranch
+}
+
+func (rsd *RepositoryScanDetails) SetRepoOwner(owner string) *RepositoryScanDetails {
+ rsd.git.RepoOwner = owner
+ return rsd
+}
+
+func (rsd *RepositoryScanDetails) RepoOwner() string {
+ return rsd.git.RepoOwner
+}
+
+func (rsd *RepositoryScanDetails) SetRepoName(repoName string) *RepositoryScanDetails {
+ rsd.git.RepoName = repoName
+ return rsd
+}
+
+func (rsd *RepositoryScanDetails) RepoName() string {
+ return rsd.git.RepoName
+}
+
+func (rsd *RepositoryScanDetails) BranchNameTemplate() string {
+ return rsd.git.BranchNameTemplate
+}
+
+func (rsd *RepositoryScanDetails) CommitMessageTemplate() string {
+ return rsd.git.CommitMessageTemplate
+}
+
+func (rsd *RepositoryScanDetails) PullRequestTitleTemplate() string {
+ return rsd.git.PullRequestTitleTemplate
+}
+
+func (rsd *RepositoryScanDetails) EmailAuthor() string {
+ return rsd.git.EmailAuthor
+}
+
+func (rsd *RepositoryScanDetails) GitProvider() vcsutils.VcsProvider {
+ return rsd.git.GitProvider
+}
+
+func (rsd *RepositoryScanDetails) VcsInfo() vcsclient.VcsInfo {
+ return rsd.git.VcsInfo
+}
+
+func (rsd *RepositoryScanDetails) SetAggregateFixes(toAggregate bool) *RepositoryScanDetails {
+ rsd.git.AggregateFixes = toAggregate
+ return rsd
+}
+
+func (rsd *RepositoryScanDetails) AggregateFixes() bool {
+ return rsd.git.AggregateFixes
+}
+
+func (rsd *RepositoryScanDetails) SetRepositoryCloneUrl(cloneUrl string) *RepositoryScanDetails {
+ rsd.git.RepositoryCloneUrl = cloneUrl
+ return rsd
+}
+
+func (rsd *RepositoryScanDetails) SetXscGitInfoContext(scannedBranch, gitProject string, client vcsclient.VcsClient) *RepositoryScanDetails {
+ XscGitInfoContext, err := rsd.createGitInfoContext(scannedBranch, gitProject, client)
+ if err != nil {
+ log.Debug("failed trying to create GitInfoContext for Xsc with the following error: ", err.Error())
+ return rsd
+ }
+ rsd.xrayGraphScanParams.XscGitInfoContext = XscGitInfoContext
+ return rsd
+}
+
+// CreateGitInfoContext Creates GitInfoContext for XSC scans, this is optional.
+// ScannedBranch - name of the branch we are scanning.
+// GitProject - [Optional] relevant for azure repos and Bitbucket server.
+// Client vscClient
+func (rsd *RepositoryScanDetails) createGitInfoContext(scannedBranch, gitProject string, client vcsclient.VcsClient) (gitInfo *services.XscGitInfoContext, err error) {
+ latestCommit, err := client.GetLatestCommit(context.Background(), rsd.git.RepoOwner, rsd.git.RepoName, scannedBranch)
+ if err != nil {
+ return nil, fmt.Errorf("failed getting latest commit, repository: %s, branch: %s. error: %s ", rsd.git.RepoName, scannedBranch, err.Error())
+ }
+ // In some VCS providers, there are no git projects, fallback to the repository owner.
+ if gitProject == "" {
+ gitProject = rsd.git.RepoOwner
+ }
+ gitInfo = &services.XscGitInfoContext{
+ // Use Clone URLs as Repo Url, on browsers it will redirect to repository URLS.
+ GitRepoUrl: rsd.git.RepositoryCloneUrl,
+ GitRepoName: rsd.git.RepoName,
+ GitProvider: rsd.git.GitProvider.String(),
+ GitProject: gitProject,
+ BranchName: scannedBranch,
+ LastCommit: latestCommit.Url,
+ CommitHash: latestCommit.Hash,
+ CommitMessage: latestCommit.Message,
+ CommitAuthor: latestCommit.AuthorName,
+ }
+ return
+}
diff --git a/utils/scandetails.go b/utils/scandetails.go
index 0026b8e26..fd7dd34e9 100644
--- a/utils/scandetails.go
+++ b/utils/scandetails.go
@@ -1,7 +1,6 @@
package utils
import (
- "context"
"errors"
"fmt"
"github.com/jfrog/froggit-go/vcsclient"
@@ -12,87 +11,96 @@ import (
"github.com/jfrog/jfrog-client-go/xray/services"
"os/exec"
- "path/filepath"
"strings"
)
const (
- installationCmdFailedErr = "Couldn't run the installation command on the base branch. Assuming new project in the source branch: "
+ installationCmdFailedMsg = "Couldn't run the installation command on the base branch. Assuming new project in the source branch: "
)
type ScanDetails struct {
- *Project
- *Git
- *services.XrayGraphScanParams
- *config.ServerDetails
- client vcsclient.VcsClient
- failOnInstallationErrors bool
- fixableOnly bool
- minSeverityFilter string
- baseBranch string
+ project Project
+ xrayGraphScanParams services.XrayGraphScanParams
+ serverDetails config.ServerDetails
+ git Git
+ client vcsclient.VcsClient
+ failOnSecurityIssues bool
+ fixableOnly bool
+ minSeverityFilter string
+}
+
+func newScanDetails(client vcsclient.VcsClient, repository *Repository) *ScanDetails {
+ if repository == nil {
+ return &ScanDetails{}
+ }
+ scanDetails := ScanDetails{client: client, serverDetails: repository.Server, git: repository.Git}
+ scanDetails.SetFailOnSecurityIssues(*repository.FailOnSecurityIssues).
+ SetMinSeverity(repository.MinSeverity).
+ SetFixableOnly(repository.FixableOnly).
+ SetXrayGraphScanParams(repository.Watches, repository.JFrogProjectKey)
+ return &scanDetails
}
-func NewScanDetails(client vcsclient.VcsClient, server *config.ServerDetails, git *Git) *ScanDetails {
- return &ScanDetails{client: client, ServerDetails: server, Git: git}
+func (sc *ScanDetails) Project() *Project {
+ return &sc.project
}
-func (sc *ScanDetails) SetFailOnInstallationErrors(toFail bool) *ScanDetails {
- sc.failOnInstallationErrors = toFail
- return sc
+func (sc *ScanDetails) XrayGraphScanParams() *services.XrayGraphScanParams {
+ return &sc.xrayGraphScanParams
}
-func (sc *ScanDetails) SetProject(project *Project) *ScanDetails {
- sc.Project = project
- return sc
+func (sc *ScanDetails) ServerDetails() *config.ServerDetails {
+ return &sc.serverDetails
}
-func (sc *ScanDetails) SetXrayGraphScanParams(watches []string, jfrogProjectKey string) *ScanDetails {
- sc.XrayGraphScanParams = createXrayScanParams(watches, jfrogProjectKey)
- return sc
+func (sc *ScanDetails) GitClient() vcsclient.VcsClient {
+ return sc.client
}
-func (sc *ScanDetails) SetFixableOnly(fixable bool) *ScanDetails {
- sc.fixableOnly = fixable
- return sc
+func (sc *ScanDetails) FailOnSecurityIssues() bool {
+ return sc.failOnSecurityIssues
}
-func (sc *ScanDetails) SetMinSeverity(minSeverity string) *ScanDetails {
- sc.minSeverityFilter = minSeverity
- return sc
+func (sc *ScanDetails) FixableOnly() bool {
+ return sc.fixableOnly
}
-func (sc *ScanDetails) SetBaseBranch(branch string) *ScanDetails {
- sc.baseBranch = branch
- return sc
+func (sc *ScanDetails) MinSeverityFilter() string {
+ return sc.minSeverityFilter
}
-func (sc *ScanDetails) Client() vcsclient.VcsClient {
- return sc.client
+func (sc *ScanDetails) SetMinSeverityFilter(minSeverityFilter string) *ScanDetails {
+ sc.minSeverityFilter = minSeverityFilter
+ return sc
}
-func (sc *ScanDetails) BaseBranch() string {
- return sc.baseBranch
+func (sc *ScanDetails) SetFailOnSecurityIssues(toFail bool) *ScanDetails {
+ sc.failOnSecurityIssues = toFail
+ return sc
}
-func (sc *ScanDetails) FailOnInstallationErrors() bool {
- return sc.failOnInstallationErrors
+func (sc *ScanDetails) SetProject(project *Project) *ScanDetails {
+ sc.project = *project
+ return sc
}
-func (sc *ScanDetails) FixableOnly() bool {
- return sc.fixableOnly
+func (sc *ScanDetails) SetXrayGraphScanParams(watches []string, jfrogProjectKey string) *ScanDetails {
+ sc.xrayGraphScanParams = *createXrayScanParams(watches, jfrogProjectKey)
+ return sc
}
-func (sc *ScanDetails) MinSeverityFilter() string {
- return sc.minSeverityFilter
+func (sc *ScanDetails) SetFixableOnly(fixable bool) *ScanDetails {
+ sc.fixableOnly = fixable
+ return sc
}
-func (sc *ScanDetails) SetRepoOwner(owner string) *ScanDetails {
- sc.RepoOwner = owner
+func (sc *ScanDetails) SetMinSeverity(minSeverity string) *ScanDetails {
+ sc.minSeverityFilter = minSeverity
return sc
}
-func (sc *ScanDetails) SetRepoName(repoName string) *ScanDetails {
- sc.RepoName = repoName
+func (sc *ScanDetails) SetServerDetails(serverDetails *config.ServerDetails) *ScanDetails {
+ sc.serverDetails = *serverDetails
return sc
}
@@ -122,17 +130,17 @@ func (sc *ScanDetails) RunInstallAndAudit(workDirs ...string) (auditResults *aud
}
auditBasicParams := (&xrayutils.AuditBasicParams{}).
- SetPipRequirementsFile(sc.PipRequirementsFile).
- SetUseWrapper(*sc.UseWrapper).
- SetDepsRepo(sc.DepsRepo).
+ SetPipRequirementsFile(sc.project.PipRequirementsFile).
+ SetUseWrapper(*sc.project.UseWrapper).
+ SetDepsRepo(sc.project.DepsRepo).
SetIgnoreConfigFile(true).
- SetServerDetails(sc.ServerDetails)
+ SetServerDetails(&sc.serverDetails)
auditParams := audit.NewAuditParams().
- SetXrayGraphScanParams(sc.XrayGraphScanParams).
+ SetXrayGraphScanParams(&sc.xrayGraphScanParams).
SetWorkingDirs(workDirs).
- SetMinSeverityFilter(sc.MinSeverityFilter()).
- SetFixableOnly(sc.FixableOnly()).
+ SetMinSeverityFilter(sc.minSeverityFilter).
+ SetFixableOnly(sc.fixableOnly).
SetGraphBasicParams(auditBasicParams)
auditResults, err = audit.RunAudit(auditParams)
@@ -143,86 +151,32 @@ func (sc *ScanDetails) RunInstallAndAudit(workDirs ...string) (auditResults *aud
}
func (sc *ScanDetails) runInstallIfNeeded(workDir string) (err error) {
- if sc.InstallCommandName == "" {
+ if sc.project.InstallCommandName == "" {
return nil
}
restoreDir, err := Chdir(workDir)
defer func() {
err = errors.Join(err, restoreDir())
}()
- log.Info(fmt.Sprintf("Executing '%s %s' at %s", sc.InstallCommandName, strings.Join(sc.InstallCommandArgs, " "), workDir))
+ log.Info(fmt.Sprintf("Executing '%s %s' at %s", sc.project.InstallCommandName, strings.Join(sc.project.InstallCommandArgs, " "), workDir))
output, err := sc.runInstallCommand()
- if err != nil && !sc.FailOnInstallationErrors() {
- log.Info(installationCmdFailedErr, err.Error(), "\n", string(output))
- // failOnInstallationErrors set to 'false'
+ if err != nil && !sc.failOnSecurityIssues {
+ log.Info(installationCmdFailedMsg, err.Error(), "\n", string(output))
+ // failOnSecurityIssues set to 'false'
err = nil
}
return
}
func (sc *ScanDetails) runInstallCommand() ([]byte, error) {
- if sc.DepsRepo == "" {
+ if sc.project.DepsRepo == "" {
//#nosec G204 -- False positive - the subprocess only runs after the user's approval.
- return exec.Command(sc.InstallCommandName, sc.InstallCommandArgs...).CombinedOutput()
- }
-
- if _, exists := MapTechToResolvingFunc[sc.InstallCommandName]; !exists {
- return nil, fmt.Errorf(sc.InstallCommandName, "isn't recognized as an install command")
+ return exec.Command(sc.project.InstallCommandName, sc.project.InstallCommandArgs...).CombinedOutput()
}
- log.Info("Resolving dependencies from", sc.ServerDetails.Url, "from repo", sc.DepsRepo)
- return MapTechToResolvingFunc[sc.InstallCommandName](sc)
-}
-
-func (sc *ScanDetails) SetXscGitInfoContext(scannedBranch, gitProject string, client vcsclient.VcsClient) *ScanDetails {
- XscGitInfoContext, err := sc.createGitInfoContext(scannedBranch, gitProject, client)
- if err != nil {
- log.Debug("failed trying to create GitInfoContext for Xsc with the following error: ", err.Error())
- return sc
- }
- sc.XscGitInfoContext = XscGitInfoContext
- return sc
-}
-
-// CreateGitInfoContext Creates GitInfoContext for XSC scans, this is optional.
-// ScannedBranch - name of the branch we are scanning.
-// GitProject - [Optional] relevant for azure repos and Bitbucket server.
-// Client vscClient
-func (sc *ScanDetails) createGitInfoContext(scannedBranch, gitProject string, client vcsclient.VcsClient) (gitInfo *services.XscGitInfoContext, err error) {
- latestCommit, err := client.GetLatestCommit(context.Background(), sc.RepoOwner, sc.RepoName, scannedBranch)
- if err != nil {
- return nil, fmt.Errorf("failed getting latest commit, repository: %s, branch: %s. error: %s ", sc.RepoName, scannedBranch, err.Error())
- }
- // In some VCS providers, there are no git projects, fallback to the repository owner.
- if gitProject == "" {
- gitProject = sc.RepoOwner
- }
- gitInfo = &services.XscGitInfoContext{
- // Use Clone URLs as Repo Url, on browsers it will redirect to repository URLS.
- GitRepoUrl: sc.Git.RepositoryCloneUrl,
- GitRepoName: sc.RepoName,
- GitProvider: sc.GitProvider.String(),
- GitProject: gitProject,
- BranchName: scannedBranch,
- LastCommit: latestCommit.Url,
- CommitHash: latestCommit.Hash,
- CommitMessage: latestCommit.Message,
- CommitAuthor: latestCommit.AuthorName,
- }
- return
-}
-func GetFullPathWorkingDirs(workingDirs []string, baseWd string) []string {
- var fullPathWds []string
- if len(workingDirs) != 0 {
- for _, workDir := range workingDirs {
- if workDir == RootDir {
- fullPathWds = append(fullPathWds, baseWd)
- continue
- }
- fullPathWds = append(fullPathWds, filepath.Join(baseWd, workDir))
- }
- } else {
- fullPathWds = append(fullPathWds, baseWd)
+ if _, exists := MapTechToResolvingFunc[sc.project.InstallCommandName]; !exists {
+ return nil, fmt.Errorf(sc.project.InstallCommandName, "isn't recognized as an install command")
}
- return fullPathWds
+ log.Info("Resolving dependencies from", sc.serverDetails.Url, "from repo", sc.project.DepsRepo)
+ return MapTechToResolvingFunc[sc.project.InstallCommandName](sc)
}
diff --git a/utils/scandetails_test.go b/utils/scandetails_test.go
index 8810a3196..8ba8ed253 100644
--- a/utils/scandetails_test.go
+++ b/utils/scandetails_test.go
@@ -11,31 +11,31 @@ func TestCreateXrayScanParams(t *testing.T) {
// Project
scanDetails := &ScanDetails{}
scanDetails.SetXrayGraphScanParams(nil, "")
- assert.Empty(t, scanDetails.Watches)
- assert.Equal(t, "", scanDetails.ProjectKey)
- assert.True(t, scanDetails.IncludeVulnerabilities)
- assert.False(t, scanDetails.IncludeLicenses)
+ assert.Empty(t, scanDetails.xrayGraphScanParams.Watches)
+ assert.Equal(t, "", scanDetails.xrayGraphScanParams.ProjectKey)
+ assert.True(t, scanDetails.xrayGraphScanParams.IncludeVulnerabilities)
+ assert.False(t, scanDetails.xrayGraphScanParams.IncludeLicenses)
// Watches
scanDetails.SetXrayGraphScanParams([]string{"watch-1", "watch-2"}, "")
- assert.Equal(t, []string{"watch-1", "watch-2"}, scanDetails.Watches)
- assert.Equal(t, "", scanDetails.ProjectKey)
- assert.False(t, scanDetails.IncludeVulnerabilities)
- assert.False(t, scanDetails.IncludeLicenses)
+ assert.Equal(t, []string{"watch-1", "watch-2"}, scanDetails.xrayGraphScanParams.Watches)
+ assert.Equal(t, "", scanDetails.xrayGraphScanParams.ProjectKey)
+ assert.False(t, scanDetails.xrayGraphScanParams.IncludeVulnerabilities)
+ assert.False(t, scanDetails.xrayGraphScanParams.IncludeLicenses)
// Project
scanDetails.SetXrayGraphScanParams(nil, "project")
- assert.Empty(t, scanDetails.Watches)
- assert.Equal(t, "project", scanDetails.ProjectKey)
- assert.False(t, scanDetails.IncludeVulnerabilities)
- assert.False(t, scanDetails.IncludeLicenses)
+ assert.Empty(t, scanDetails.xrayGraphScanParams.Watches)
+ assert.Equal(t, "project", scanDetails.xrayGraphScanParams.ProjectKey)
+ assert.False(t, scanDetails.xrayGraphScanParams.IncludeVulnerabilities)
+ assert.False(t, scanDetails.xrayGraphScanParams.IncludeLicenses)
}
func TestRunInstallIfNeeded(t *testing.T) {
scanSetup := ScanDetails{
- Project: &Project{},
+ project: Project{},
}
- scanSetup.SetFailOnInstallationErrors(true)
+ scanSetup.SetFailOnSecurityIssues(true)
assert.NoError(t, scanSetup.runInstallIfNeeded(""))
tmpDir, err := fileutils.CreateTempDir()
assert.NoError(t, err)
@@ -47,20 +47,20 @@ func TestRunInstallIfNeeded(t *testing.T) {
InstallCommandName: "echo",
InstallCommandArgs: []string{"Hello"},
}
- scanSetup.Project = params
+ scanSetup.SetProject(params)
assert.NoError(t, scanSetup.runInstallIfNeeded(tmpDir))
- scanSetup.InstallCommandName = "not-exist"
- scanSetup.InstallCommandArgs = []string{"1", "2"}
- scanSetup.SetFailOnInstallationErrors(false)
+ scanSetup.project.InstallCommandName = "not-exist"
+ scanSetup.project.InstallCommandArgs = []string{"1", "2"}
+ scanSetup.SetFailOnSecurityIssues(false)
assert.NoError(t, scanSetup.runInstallIfNeeded(tmpDir))
params = &Project{
InstallCommandName: "not-existed",
InstallCommandArgs: []string{"1", "2"},
}
- scanSetup.Project = params
- scanSetup.SetFailOnInstallationErrors(true)
+ scanSetup.SetProject(params)
+ scanSetup.SetFailOnSecurityIssues(true)
assert.Error(t, scanSetup.runInstallIfNeeded(tmpDir))
}
diff --git a/utils/utils.go b/utils/utils.go
index a2b146213..ab66745f3 100644
--- a/utils/utils.go
+++ b/utils/utils.go
@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"os"
+ "path/filepath"
"regexp"
"sort"
"strings"
@@ -366,3 +367,19 @@ func GetSortedPullRequestComments(client vcsclient.VcsClient, repoOwner, repoNam
})
return pullRequestsComments, nil
}
+
+func GetFullPathWorkingDirs(workingDirs []string, baseWd string) []string {
+ var fullPathWds []string
+ if len(workingDirs) != 0 {
+ for _, workDir := range workingDirs {
+ if workDir == RootDir {
+ fullPathWds = append(fullPathWds, baseWd)
+ continue
+ }
+ fullPathWds = append(fullPathWds, filepath.Join(baseWd, workDir))
+ }
+ } else {
+ fullPathWds = append(fullPathWds, baseWd)
+ }
+ return fullPathWds
+}