@@ -9,16 +9,16 @@ import (
9
9
biutils "github.com/jfrog/build-info-go/utils"
10
10
"github.com/jfrog/build-info-go/utils/pythonutils"
11
11
"github.com/jfrog/gofrog/datastructures"
12
- utils "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/python"
12
+ artifactoryutils "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/python"
13
13
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
14
14
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
15
15
"github.com/jfrog/jfrog-cli-security/commands/audit/sca"
16
- xrayutils2 "github.com/jfrog/jfrog-cli-security/utils"
16
+ "github.com/jfrog/jfrog-cli-security/utils"
17
17
"github.com/jfrog/jfrog-cli-security/utils/techutils"
18
18
"github.com/jfrog/jfrog-client-go/utils/errorutils"
19
19
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
20
20
"github.com/jfrog/jfrog-client-go/utils/log"
21
- xrayUtils "github.com/jfrog/jfrog-client-go/xray/services/utils"
21
+ clientutils "github.com/jfrog/jfrog-client-go/xray/services/utils"
22
22
23
23
"os"
24
24
"os/exec"
@@ -34,42 +34,33 @@ const (
34
34
CurationPipMinimumVersion = "23.0.0"
35
35
)
36
36
37
- type AuditPython struct {
38
- Server * config.ServerDetails
39
- Tool pythonutils.PythonTool
40
- RemotePypiRepo string
41
- PipRequirementsFile string
42
- InstallCommandArgs []string
43
- IsCurationCmd bool
44
- }
45
-
46
- func BuildDependencyTree (auditPython * AuditPython ) (dependencyTree []* xrayUtils.GraphNode , uniqueDeps []string , downloadUrls map [string ]string , err error ) {
47
- dependenciesGraph , directDependenciesList , pipUrls , errGetTree := getDependencies (auditPython )
37
+ func BuildDependencyTree (params utils.AuditParams , technology techutils.Technology ) (dependencyTree []* clientutils.GraphNode , uniqueDeps []string , downloadUrls map [string ]string , err error ) {
38
+ dependenciesGraph , directDependenciesList , pipUrls , errGetTree := getDependencies (params , technology )
48
39
if errGetTree != nil {
49
40
err = errGetTree
50
41
return
51
42
}
52
43
downloadUrls = pipUrls
53
- directDependencies := []* xrayUtils .GraphNode {}
44
+ directDependencies := []* clientutils .GraphNode {}
54
45
uniqueDepsSet := datastructures .MakeSet [string ]()
55
46
for _ , rootDep := range directDependenciesList {
56
- directDependency := & xrayUtils .GraphNode {
47
+ directDependency := & clientutils .GraphNode {
57
48
Id : PythonPackageTypeIdentifier + rootDep ,
58
- Nodes : []* xrayUtils .GraphNode {},
49
+ Nodes : []* clientutils .GraphNode {},
59
50
}
60
51
populatePythonDependencyTree (directDependency , dependenciesGraph , uniqueDepsSet )
61
52
directDependencies = append (directDependencies , directDependency )
62
53
}
63
- root := & xrayUtils .GraphNode {
54
+ root := & clientutils .GraphNode {
64
55
Id : "root" ,
65
56
Nodes : directDependencies ,
66
57
}
67
- dependencyTree = []* xrayUtils .GraphNode {root }
58
+ dependencyTree = []* clientutils .GraphNode {root }
68
59
uniqueDeps = uniqueDepsSet .ToSlice ()
69
60
return
70
61
}
71
62
72
- func getDependencies (auditPython * AuditPython ) (dependenciesGraph map [string ][]string , directDependencies []string , pipUrls map [string ]string , err error ) {
63
+ func getDependencies (params utils. AuditParams , technology techutils. Technology ) (dependenciesGraph map [string ][]string , directDependencies []string , pipUrls map [string ]string , err error ) {
73
64
wd , err := os .Getwd ()
74
65
if errorutils .CheckError (err ) != nil {
75
66
return
@@ -100,24 +91,28 @@ func getDependencies(auditPython *AuditPython) (dependenciesGraph map[string][]s
100
91
return
101
92
}
102
93
103
- restoreEnv , err := runPythonInstall (auditPython )
104
- defer func () {
105
- err = errors .Join (err , restoreEnv ())
106
- }()
107
- if err != nil {
108
- return
94
+ pythonTool := pythonutils .PythonTool (technology )
95
+ if technology == techutils .Pipenv || ! params .SkipAutoInstall () {
96
+ var restoreEnv func () error
97
+ restoreEnv , err = runPythonInstall (params , pythonTool )
98
+ defer func () {
99
+ err = errors .Join (err , restoreEnv ())
100
+ }()
101
+ if err != nil {
102
+ return
103
+ }
109
104
}
110
105
111
106
localDependenciesPath , err := config .GetJfrogDependenciesPath ()
112
107
if err != nil {
113
108
return
114
109
}
115
- dependenciesGraph , directDependencies , err = pythonutils .GetPythonDependencies (auditPython . Tool , tempDirPath , localDependenciesPath , log .GetLogger ())
110
+ dependenciesGraph , directDependencies , err = pythonutils .GetPythonDependencies (pythonTool , tempDirPath , localDependenciesPath , log .GetLogger ())
116
111
if err != nil {
117
112
sca .LogExecutableVersion ("python" )
118
- sca .LogExecutableVersion (string (auditPython . Tool ))
113
+ sca .LogExecutableVersion (string (pythonTool ))
119
114
}
120
- if ! auditPython .IsCurationCmd {
115
+ if ! params .IsCurationCmd () {
121
116
return
122
117
}
123
118
pipUrls , errProcessed := processPipDownloadsUrlsFromReportFile ()
@@ -181,29 +176,34 @@ type pypiMetaData struct {
181
176
Version string `json:"version"`
182
177
}
183
178
184
- func runPythonInstall (auditPython * AuditPython ) (restoreEnv func () error , err error ) {
185
- switch auditPython . Tool {
179
+ func runPythonInstall (params utils. AuditParams , tool pythonutils. PythonTool ) (restoreEnv func () error , err error ) {
180
+ switch tool {
186
181
case pythonutils .Pip :
187
- return installPipDeps (auditPython )
182
+ return installPipDeps (params )
188
183
case pythonutils .Pipenv :
189
- return installPipenvDeps (auditPython )
184
+ return installPipenvDeps (params )
190
185
case pythonutils .Poetry :
191
- return installPoetryDeps (auditPython )
186
+ return installPoetryDeps (params )
192
187
}
193
188
return
194
189
}
195
190
196
- func installPoetryDeps (auditPython * AuditPython ) (restoreEnv func () error , err error ) {
191
+ func installPoetryDeps (params utils. AuditParams ) (restoreEnv func () error , err error ) {
197
192
restoreEnv = func () error {
198
193
return nil
199
194
}
200
- if auditPython .RemotePypiRepo != "" {
201
- rtUrl , username , password , err := utils .GetPypiRepoUrlWithCredentials (auditPython .Server , auditPython .RemotePypiRepo , false )
195
+ if params .DepsRepo () != "" {
196
+ var serverDetails * config.ServerDetails
197
+ serverDetails , err = params .ServerDetails ()
198
+ if err != nil {
199
+ return restoreEnv , err
200
+ }
201
+ rtUrl , username , password , err := artifactoryutils .GetPypiRepoUrlWithCredentials (serverDetails , params .DepsRepo (), false )
202
202
if err != nil {
203
203
return restoreEnv , err
204
204
}
205
205
if password != "" {
206
- err = utils .ConfigPoetryRepo (rtUrl .Scheme + "://" + rtUrl .Host + rtUrl .Path , username , password , auditPython . RemotePypiRepo )
206
+ err = artifactoryutils .ConfigPoetryRepo (rtUrl .Scheme + "://" + rtUrl .Host + rtUrl .Path , username , password , params . DepsRepo () )
207
207
if err != nil {
208
208
return restoreEnv , err
209
209
}
@@ -214,7 +214,7 @@ func installPoetryDeps(auditPython *AuditPython) (restoreEnv func() error, err e
214
214
return restoreEnv , err
215
215
}
216
216
217
- func installPipenvDeps (auditPython * AuditPython ) (restoreEnv func () error , err error ) {
217
+ func installPipenvDeps (params utils. AuditParams ) (restoreEnv func () error , err error ) {
218
218
// Set virtualenv path to venv dir
219
219
err = os .Setenv ("WORKON_HOME" , ".jfrog" )
220
220
if err != nil {
@@ -223,46 +223,56 @@ func installPipenvDeps(auditPython *AuditPython) (restoreEnv func() error, err e
223
223
restoreEnv = func () error {
224
224
return os .Unsetenv ("WORKON_HOME" )
225
225
}
226
- if auditPython .RemotePypiRepo != "" {
227
- return restoreEnv , runPipenvInstallFromRemoteRegistry (auditPython .Server , auditPython .RemotePypiRepo )
226
+ if params .DepsRepo () != "" {
227
+ var serverDetails * config.ServerDetails
228
+ serverDetails , err = params .ServerDetails ()
229
+ if err != nil {
230
+ return
231
+ }
232
+ return restoreEnv , runPipenvInstallFromRemoteRegistry (serverDetails , params .DepsRepo ())
228
233
}
229
234
// Run 'pipenv install -d'
230
235
_ , err = executeCommand ("pipenv" , "install" , "-d" )
231
236
return restoreEnv , err
232
237
}
233
238
234
- func installPipDeps (auditPython * AuditPython ) (restoreEnv func () error , err error ) {
239
+ func installPipDeps (params utils. AuditParams ) (restoreEnv func () error , err error ) {
235
240
restoreEnv , err = SetPipVirtualEnvPath ()
236
241
if err != nil {
237
242
return
238
243
}
239
244
240
245
remoteUrl := ""
241
- if auditPython .RemotePypiRepo != "" {
242
- remoteUrl , err = utils .GetPypiRepoUrl (auditPython .Server , auditPython .RemotePypiRepo , auditPython .IsCurationCmd )
246
+ if params .DepsRepo () != "" {
247
+ var serverDetails * config.ServerDetails
248
+ serverDetails , err = params .ServerDetails ()
249
+ if err != nil {
250
+ return
251
+ }
252
+ remoteUrl , err = artifactoryutils .GetPypiRepoUrl (serverDetails , params .DepsRepo (), params .IsCurationCmd ())
243
253
if err != nil {
244
254
return
245
255
}
246
256
}
247
257
248
258
var curationCachePip string
249
259
var reportFileName string
250
- if auditPython .IsCurationCmd {
260
+ if params .IsCurationCmd () {
251
261
// upgrade pip version to 23.0.0, as it is required for the curation command.
252
262
if err = upgradePipVersion (CurationPipMinimumVersion ); err != nil {
253
263
log .Warn (fmt .Sprintf ("Failed to upgrade pip version, err: %v" , err ))
254
264
}
255
- if curationCachePip , err = xrayutils2 .GetCurationPipCacheFolder (); err != nil {
265
+ if curationCachePip , err = utils .GetCurationPipCacheFolder (); err != nil {
256
266
return
257
267
}
258
268
reportFileName = pythonReportFile
259
269
}
260
270
261
- pipInstallArgs := getPipInstallArgs (auditPython .PipRequirementsFile , remoteUrl , curationCachePip , reportFileName , auditPython .InstallCommandArgs ... )
271
+ pipInstallArgs := getPipInstallArgs (params .PipRequirementsFile () , remoteUrl , curationCachePip , reportFileName , params .InstallCommandArgs () ... )
262
272
var reqErr error
263
273
_ , err = executeCommand ("python" , pipInstallArgs ... )
264
- if err != nil && auditPython .PipRequirementsFile == "" {
265
- pipInstallArgs = getPipInstallArgs ("requirements.txt" , remoteUrl , curationCachePip , reportFileName , auditPython .InstallCommandArgs ... )
274
+ if err != nil && params .PipRequirementsFile () == "" {
275
+ pipInstallArgs = getPipInstallArgs ("requirements.txt" , remoteUrl , curationCachePip , reportFileName , params .InstallCommandArgs () ... )
266
276
_ , reqErr = executeCommand ("python" , pipInstallArgs ... )
267
277
if reqErr != nil {
268
278
// Return Pip install error and log the requirements fallback error.
@@ -272,7 +282,7 @@ func installPipDeps(auditPython *AuditPython) (restoreEnv func() error, err erro
272
282
}
273
283
}
274
284
if err != nil || reqErr != nil {
275
- if msgToUser := sca .GetMsgToUserForCurationBlock (auditPython .IsCurationCmd , techutils .Pip , errors .Join (err , reqErr ).Error ()); msgToUser != "" {
285
+ if msgToUser := sca .GetMsgToUserForCurationBlock (params .IsCurationCmd () , techutils .Pip , errors .Join (err , reqErr ).Error ()); msgToUser != "" {
276
286
err = errors .Join (err , errors .New (msgToUser ))
277
287
}
278
288
}
@@ -318,7 +328,7 @@ func getPipInstallArgs(requirementsFile, remoteUrl, cacheFolder, reportFileName
318
328
args = append (args , "-r" , requirementsFile )
319
329
}
320
330
if remoteUrl != "" {
321
- args = append (args , utils .GetPypiRemoteRegistryFlag (pythonutils .Pip ), remoteUrl )
331
+ args = append (args , artifactoryutils .GetPypiRemoteRegistryFlag (pythonutils .Pip ), remoteUrl )
322
332
}
323
333
if cacheFolder != "" {
324
334
args = append (args , "--cache-dir" , cacheFolder )
@@ -359,7 +369,7 @@ func parseCustomArgs(remoteUrl, cacheFolder, reportFileName string, customArgs .
359
369
continue
360
370
}
361
371
}
362
- if remoteUrl != "" && strings .Contains (customArgs [i ], utils .GetPypiRemoteRegistryFlag (pythonutils .Pip )) {
372
+ if remoteUrl != "" && strings .Contains (customArgs [i ], artifactoryutils .GetPypiRemoteRegistryFlag (pythonutils .Pip )) {
363
373
log .Warn ("The remote registry flag is not supported in the custom arguments list. skipping..." )
364
374
i ++
365
375
continue
@@ -370,11 +380,11 @@ func parseCustomArgs(remoteUrl, cacheFolder, reportFileName string, customArgs .
370
380
}
371
381
372
382
func runPipenvInstallFromRemoteRegistry (server * config.ServerDetails , depsRepoName string ) (err error ) {
373
- rtUrl , err := utils .GetPypiRepoUrl (server , depsRepoName , false )
383
+ rtUrl , err := artifactoryutils .GetPypiRepoUrl (server , depsRepoName , false )
374
384
if err != nil {
375
385
return err
376
386
}
377
- args := []string {"install" , "-d" , utils .GetPypiRemoteRegistryFlag (pythonutils .Pipenv ), rtUrl }
387
+ args := []string {"install" , "-d" , artifactoryutils .GetPypiRemoteRegistryFlag (pythonutils .Pipenv ), rtUrl }
378
388
_ , err = executeCommand ("pipenv" , args ... )
379
389
return err
380
390
}
@@ -424,17 +434,17 @@ func SetPipVirtualEnvPath() (restoreEnv func() error, err error) {
424
434
return
425
435
}
426
436
427
- func populatePythonDependencyTree (currNode * xrayUtils .GraphNode , dependenciesGraph map [string ][]string , uniqueDepsSet * datastructures.Set [string ]) {
437
+ func populatePythonDependencyTree (currNode * clientutils .GraphNode , dependenciesGraph map [string ][]string , uniqueDepsSet * datastructures.Set [string ]) {
428
438
if currNode .NodeHasLoop () {
429
439
return
430
440
}
431
441
uniqueDepsSet .Add (currNode .Id )
432
442
currDepChildren := dependenciesGraph [strings .TrimPrefix (currNode .Id , PythonPackageTypeIdentifier )]
433
443
// Recursively create & append all node's dependencies.
434
444
for _ , dependency := range currDepChildren {
435
- childNode := & xrayUtils .GraphNode {
445
+ childNode := & clientutils .GraphNode {
436
446
Id : PythonPackageTypeIdentifier + dependency ,
437
- Nodes : []* xrayUtils .GraphNode {},
447
+ Nodes : []* clientutils .GraphNode {},
438
448
Parent : currNode ,
439
449
}
440
450
currNode .Nodes = append (currNode .Nodes , childNode )
0 commit comments