Skip to content

Commit 693c649

Browse files
committed
Merge remote-tracking branch 'upstream/dev' into static_sca_violations_remediations
2 parents ad480b0 + f0eb9c7 commit 693c649

File tree

7 files changed

+85
-2
lines changed

7 files changed

+85
-2
lines changed

cli/docs/flags.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ const (
141141

142142
// Unique curation flags
143143
CurationOutput = "curation-format"
144+
SolutionPath = "solution-path"
144145

145146
// Unique git flags
146147
InputFile = "input-file"
@@ -194,7 +195,7 @@ var commandFlags = map[string][]string{
194195
StaticSca, XrayLibPluginBinaryCustomPath, AnalyzerManagerCustomPath, AddSastRules,
195196
},
196197
CurationAudit: {
197-
CurationOutput, WorkingDirs, Threads, RequirementsFile, InsecureTls, useWrapperAudit,
198+
CurationOutput, WorkingDirs, Threads, RequirementsFile, InsecureTls, useWrapperAudit, SolutionPath,
198199
},
199200
GitCountContributors: {
200201
InputFile, ScmType, ScmApiUrl, Token, Owner, RepoName, Months, DetailedSummary, InsecureTls,
@@ -305,6 +306,7 @@ var flagsMap = map[string]components.Flag{
305306
XrayLibPluginBinaryCustomPath: components.NewStringFlag(XrayLibPluginBinaryCustomPath, "Defines the custom path to the xray-lib-plugin binary.", components.SetHiddenStrFlag()),
306307
StaticSca: components.NewBoolFlag(StaticSca, "Set to true to use the new SCA engine which is based on lock files.", components.SetHiddenBoolFlag()),
307308
CurationOutput: components.NewStringFlag(OutputFormat, "Defines the output format of the command. Acceptable values are: table, json.", components.WithStrDefaultValue("table")),
309+
SolutionPath: components.NewStringFlag(SolutionPath, "Path to the .NET solution file (.sln) to use when multiple solution files are present in the directory."),
308310
Sca: components.NewBoolFlag(Sca, fmt.Sprintf("Selective scanners mode: Execute SCA (Software Composition Analysis) sub-scan. Use --%s to run both SCA and Contextual Analysis. Use --%s --%s to to run SCA. Can be combined with --%s, --%s, --%s.", Sca, Sca, WithoutCA, Secrets, Sast, Iac)),
309311
Iac: components.NewBoolFlag(Iac, fmt.Sprintf("Selective scanners mode: Execute IaC sub-scan. Can be combined with --%s, --%s and --%s.", Sca, Secrets, Sast)),
310312
Sast: components.NewBoolFlag(Sast, fmt.Sprintf("Selective scanners mode: Execute SAST sub-scan. Can be combined with --%s, --%s and --%s.", Sca, Secrets, Iac)),

cli/scancommands.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,8 @@ func getCurationCommand(c *components.Context) (*curation.CurationAuditCommand,
644644
SetUseWrapper(c.GetBoolFlagValue(flags.UseWrapper)).
645645
SetInsecureTls(c.GetBoolFlagValue(flags.InsecureTls)).
646646
SetNpmScope(c.GetStringFlagValue(flags.DepType)).
647-
SetPipRequirementsFile(c.GetStringFlagValue(flags.RequirementsFile))
647+
SetPipRequirementsFile(c.GetStringFlagValue(flags.RequirementsFile)).
648+
SetSolutionFilePath(c.GetStringFlagValue(flags.SolutionPath))
648649
return curationAuditCommand, nil
649650
}
650651

commands/audit/auditbasicparams.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ type AuditParamsInterface interface {
4949
AllowPartialResults() bool
5050
GetXrayVersion() string
5151
GetConfigProfile() *xscservices.ConfigProfile
52+
SolutionFilePath() string
53+
SetSolutionFilePath(solutionFilePath string) *AuditBasicParams
5254
}
5355

5456
type AuditBasicParams struct {
@@ -79,6 +81,7 @@ type AuditBasicParams struct {
7981
xrayVersion string
8082
xscVersion string
8183
configProfile *xscservices.ConfigProfile
84+
solutionFilePath string
8285
}
8386

8487
func (abp *AuditBasicParams) DirectDependencies() *[]string {
@@ -330,3 +333,12 @@ func (abp *AuditBasicParams) SetConfigProfile(profile *xscservices.ConfigProfile
330333
func (abp *AuditBasicParams) GetConfigProfile() *xscservices.ConfigProfile {
331334
return abp.configProfile
332335
}
336+
337+
func (abp *AuditBasicParams) SolutionFilePath() string {
338+
return abp.solutionFilePath
339+
}
340+
341+
func (abp *AuditBasicParams) SetSolutionFilePath(solutionFilePath string) *AuditBasicParams {
342+
abp.solutionFilePath = solutionFilePath
343+
return abp
344+
}

commands/curation/curationaudit.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,8 @@ func (ca *CurationAuditCommand) getBuildInfoParamsByTech() (technologies.BuildIn
426426
NpmOverwritePackageLock: true,
427427
// Python params
428428
PipRequirementsFile: ca.PipRequirementsFile(),
429+
// NuGet params
430+
SolutionFilePath: ca.SolutionFilePath(),
429431
}, err
430432
}
431433

sca/bom/buildinfo/technologies/common.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ type BuildInfoBomGeneratorParams struct {
5858
NpmOverwritePackageLock bool
5959
// Pnpm params
6060
MaxTreeDepth string
61+
// NuGet params
62+
SolutionFilePath string
6163
}
6264

6365
func (bbp *BuildInfoBomGeneratorParams) SetNpmScope(depType string) *BuildInfoBomGeneratorParams {

sca/bom/buildinfo/technologies/nuget/nuget.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,13 @@ func runDotnetRestore(wd string, params technologies.BuildInfoBomGeneratorParams
267267
completeCommandArgs = append(completeCommandArgs, toolType.String(), installCommandName)
268268
}
269269

270+
// Check for solution file path from JF CA arguments for specific solution when we have more than one solution file
271+
if params.SolutionFilePath != "" {
272+
solutionFileName := filepath.Base(params.SolutionFilePath)
273+
completeCommandArgs = append(completeCommandArgs, solutionFileName)
274+
log.Info(fmt.Sprintf("Using solution file: %s", solutionFileName))
275+
}
276+
270277
// We include the flag that allows resolution from an Artifactory server, if it exists.
271278
completeCommandArgs = append(completeCommandArgs, commandExtraArgs...)
272279
command := exec.Command(completeCommandArgs[0], completeCommandArgs[1:]...)

sca/bom/buildinfo/technologies/nuget/nuget_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"strings"
88
"testing"
99

10+
bidotnet "github.com/jfrog/build-info-go/build/utils/dotnet"
1011
"github.com/jfrog/build-info-go/build/utils/dotnet/solution"
1112
"github.com/jfrog/build-info-go/utils"
1213
"github.com/jfrog/jfrog-cli-security/sca/bom/buildinfo/technologies"
@@ -229,3 +230,59 @@ func TestSkipBuildDepTreeWhenInstallForbidden(t *testing.T) {
229230
})
230231
}
231232
}
233+
234+
func TestSolutionFilePathParameter(t *testing.T) {
235+
testCases := []struct {
236+
name string
237+
solutionFilePath string
238+
expectedFileName string
239+
}{
240+
{
241+
name: "solution file path from params",
242+
solutionFilePath: "/path/to/my-solution.sln",
243+
expectedFileName: "my-solution.sln",
244+
},
245+
{
246+
name: "no solution file path",
247+
solutionFilePath: "",
248+
expectedFileName: "",
249+
},
250+
}
251+
252+
for _, test := range testCases {
253+
t.Run(test.name, func(t *testing.T) {
254+
params := technologies.BuildInfoBomGeneratorParams{
255+
SolutionFilePath: test.solutionFilePath,
256+
}
257+
258+
// Get the solution file path using the same logic as runDotnetRestore
259+
var solutionFilePath string
260+
if params.SolutionFilePath != "" {
261+
solutionFilePath = params.SolutionFilePath
262+
}
263+
var solutionFileName string
264+
if solutionFilePath != "" {
265+
solutionFileName = filepath.Base(solutionFilePath)
266+
}
267+
268+
assert.Equal(t, test.expectedFileName, solutionFileName)
269+
})
270+
}
271+
}
272+
273+
func TestRunDotnetRestoreWithRealSolutionFile(t *testing.T) {
274+
testDataDir := filepath.Join("..", "..", "..", "..", "..", "tests", "testdata", "projects", "package-managers")
275+
multiProjectPath := filepath.Join(testDataDir, "nuget", "multi")
276+
solutionFilePath := filepath.Join(multiProjectPath, "TestSolution.sln")
277+
_, err := os.Stat(solutionFilePath)
278+
assert.NoError(t, err, "Test solution file should exist")
279+
280+
params := technologies.BuildInfoBomGeneratorParams{
281+
SolutionFilePath: solutionFilePath,
282+
}
283+
toolType := bidotnet.ConvertNameToToolType("dotnet")
284+
err = runDotnetRestore(multiProjectPath, params, toolType, []string{})
285+
if err != nil {
286+
assert.NotContains(t, err.Error(), "this folder contains more than one project or solution file")
287+
}
288+
}

0 commit comments

Comments
 (0)