@contrast/contrast 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/.prettierignore +0 -6
  2. package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +4 -2
  3. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
  4. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
  5. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
  6. package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +2 -0
  7. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +10 -1
  8. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +6 -9
  9. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +65 -3
  10. package/dist/commands/audit/processAudit.js +1 -1
  11. package/dist/commands/scan/sca/scaAnalysis.js +13 -2
  12. package/dist/common/HTTPClient.js +50 -15
  13. package/dist/common/errorHandling.js +6 -1
  14. package/dist/common/versionChecker.js +1 -1
  15. package/dist/constants/constants.js +1 -1
  16. package/dist/constants/locales.js +3 -1
  17. package/dist/lambda/analytics.js +11 -0
  18. package/dist/lambda/lambda.js +35 -4
  19. package/dist/lambda/types.js +13 -0
  20. package/dist/scaAnalysis/common/formatMessage.js +17 -1
  21. package/dist/scaAnalysis/java/analysis.js +3 -6
  22. package/dist/scaAnalysis/java/index.js +2 -2
  23. package/dist/scaAnalysis/python/analysis.js +41 -0
  24. package/dist/scaAnalysis/python/index.js +10 -0
  25. package/dist/scaAnalysis/ruby/analysis.js +226 -0
  26. package/dist/scaAnalysis/ruby/index.js +10 -0
  27. package/dist/scan/autoDetection.js +6 -2
  28. package/dist/scan/fileUtils.js +14 -7
  29. package/dist/scan/formatScanOutput.js +9 -11
  30. package/dist/scan/models/groupedResultsModel.js +1 -1
  31. package/dist/scan/models/scanResultsModel.js +3 -1
  32. package/dist/scan/populateProjectIdAndProjectName.js +2 -1
  33. package/dist/scan/scan.js +1 -0
  34. package/dist/scan/scanConfig.js +6 -1
  35. package/dist/scan/scanController.js +16 -3
  36. package/dist/scan/scanResults.js +5 -1
  37. package/dist/utils/commonApi.js +4 -1
  38. package/package.json +11 -7
  39. package/src/audit/catalogueApplication/catalogueApplication.js +0 -1
  40. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +11 -8
  41. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
  42. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
  43. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
  44. package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +8 -0
  45. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +10 -9
  46. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +34 -29
  47. package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
  48. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +15 -11
  49. package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +6 -1
  50. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +43 -27
  51. package/src/audit/languageAnalysisEngine/sendSnapshot.js +78 -3
  52. package/src/commands/audit/processAudit.ts +1 -1
  53. package/src/commands/scan/sca/scaAnalysis.js +13 -5
  54. package/src/common/HTTPClient.js +65 -25
  55. package/src/common/errorHandling.ts +10 -1
  56. package/src/common/versionChecker.ts +1 -1
  57. package/src/constants/constants.js +1 -1
  58. package/src/constants/locales.js +3 -1
  59. package/src/lambda/analytics.ts +9 -0
  60. package/src/lambda/arn.ts +2 -1
  61. package/src/lambda/lambda.ts +37 -17
  62. package/src/lambda/types.ts +35 -0
  63. package/src/lambda/utils.ts +2 -7
  64. package/src/scaAnalysis/common/formatMessage.js +19 -1
  65. package/src/scaAnalysis/go/goAnalysis.js +2 -3
  66. package/src/scaAnalysis/java/analysis.js +5 -6
  67. package/src/scaAnalysis/java/index.js +2 -2
  68. package/src/scaAnalysis/python/analysis.js +48 -0
  69. package/src/scaAnalysis/python/index.js +11 -0
  70. package/src/scaAnalysis/ruby/analysis.js +282 -0
  71. package/src/scaAnalysis/ruby/index.js +11 -0
  72. package/src/scan/autoDetection.js +9 -5
  73. package/src/scan/fileUtils.js +15 -7
  74. package/src/scan/formatScanOutput.ts +11 -12
  75. package/src/scan/models/groupedResultsModel.ts +3 -3
  76. package/src/scan/models/resultContentModel.ts +1 -1
  77. package/src/scan/models/scanResultsModel.ts +5 -2
  78. package/src/scan/populateProjectIdAndProjectName.js +3 -1
  79. package/src/scan/scan.ts +1 -0
  80. package/src/scan/scanConfig.js +5 -1
  81. package/src/scan/scanController.js +18 -4
  82. package/src/scan/scanResults.js +10 -0
  83. package/src/utils/commonApi.js +4 -1
@@ -22,7 +22,8 @@ function HTTPClient(config) {
22
22
  Authorization: authToken,
23
23
  'API-Key': apiKey,
24
24
  SuperAuthorization: superAuthToken,
25
- 'Super-API-Key': superApiKey
25
+ 'Super-API-Key': superApiKey,
26
+ 'User-Agent': 'contrast-cli-v2'
26
27
  }
27
28
  }
28
29
 
@@ -33,7 +34,7 @@ function HTTPClient(config) {
33
34
  this.maybeAddCertsToRequest(config)
34
35
  }
35
36
 
36
- HTTPClient.prototype.maybeAddCertsToRequest = function(config) {
37
+ HTTPClient.prototype.maybeAddCertsToRequest = function (config) {
37
38
  // cacert
38
39
  const caCertFilePath = config.cacert
39
40
  if (caCertFilePath) {
@@ -91,13 +92,30 @@ HTTPClient.prototype.getSpecificScanResult = function getSpecificScanResult(
91
92
  return requestUtils.sendRequest({ method: 'get', options })
92
93
  }
93
94
 
94
- HTTPClient.prototype.getSpecificScanResultSarif = function getSpecificScanResultSarif(
95
+ HTTPClient.prototype.getSpecificScanResultSarif =
96
+ function getSpecificScanResultSarif(config, scanId) {
97
+ const options = _.cloneDeep(this.requestOptions)
98
+ options.url = createRawOutputURL(config, scanId)
99
+ return requestUtils.sendRequest({ method: 'get', options })
100
+ }
101
+
102
+ HTTPClient.prototype.createNewEvent = function createNewEvent(
95
103
  config,
96
- scanId
104
+ scanId,
105
+ newProject
97
106
  ) {
98
107
  const options = _.cloneDeep(this.requestOptions)
99
- options.url = createRawOutputURL(config, scanId)
100
- return requestUtils.sendRequest({ method: 'get', options })
108
+ options.url = createEventCollectorURL(config, scanId)
109
+
110
+ options.body = {
111
+ eventSource: process.env.CODESEC_INVOCATION_ENVIRONMENT,
112
+ trackingProperties: {
113
+ projectNameSource: config.projectNameSource,
114
+ waitedForResults: !config.ff,
115
+ newProject
116
+ }
117
+ }
118
+ return requestUtils.sendRequest({ method: 'post', options })
101
119
  }
102
120
 
103
121
  HTTPClient.prototype.getScanId = function getScanId(config, codeArtifactId) {
@@ -190,9 +208,6 @@ HTTPClient.prototype.catalogueCommand = function catalogueCommand(config) {
190
208
  }
191
209
 
192
210
  HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
193
- if (config.language.toUpperCase() === 'RUBY') {
194
- //console.log('sendSnapshot requestBody', requestBody.snapshot.ruby)
195
- }
196
211
  const options = _.cloneDeep(this.requestOptions)
197
212
  let url = createSnapshotURL(config)
198
213
  options.url = url
@@ -210,17 +225,24 @@ HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
210
225
  return requestUtils.sendRequest({ method: 'get', options })
211
226
  }
212
227
 
213
- HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(
228
+ HTTPClient.prototype.getReportStatusById = function getReportStatusById(
214
229
  config,
215
- requestBody
230
+ snapshotId
216
231
  ) {
217
232
  const options = _.cloneDeep(this.requestOptions)
218
- options.url = createLibraryVulnerabilitiesUrl(config)
219
- options.body = requestBody
220
-
221
- return requestUtils.sendRequest({ method: 'put', options })
233
+ options.url = createSpecificReportStatusURL(config, snapshotId)
234
+ return requestUtils.sendRequest({ method: 'get', options })
222
235
  }
223
236
 
237
+ HTTPClient.prototype.getLibraryVulnerabilities =
238
+ function getLibraryVulnerabilities(config, requestBody) {
239
+ const options = _.cloneDeep(this.requestOptions)
240
+ options.url = createLibraryVulnerabilitiesUrl(config)
241
+ options.body = requestBody
242
+
243
+ return requestUtils.sendRequest({ method: 'put', options })
244
+ }
245
+
224
246
  HTTPClient.prototype.getAppId = function getAppId(config) {
225
247
  const options = _.cloneDeep(this.requestOptions)
226
248
  let url = createAppNameUrl(config)
@@ -295,17 +317,13 @@ HTTPClient.prototype.getScanResources = async function getScanResources(
295
317
  return requestUtils.sendRequest({ method: 'get', options })
296
318
  }
297
319
 
298
- HTTPClient.prototype.getFunctionScanResults = async function getFunctionScanResults(
299
- config,
300
- params,
301
- scanId,
302
- functionArn
303
- ) {
304
- const url = createScanResultsGetUrl(config, params, scanId, functionArn)
305
- const options = { ...this.requestOptions, url }
320
+ HTTPClient.prototype.getFunctionScanResults =
321
+ async function getFunctionScanResults(config, params, scanId, functionArn) {
322
+ const url = createScanResultsGetUrl(config, params, scanId, functionArn)
323
+ const options = { ...this.requestOptions, url }
306
324
 
307
- return requestUtils.sendRequest({ method: 'get', options })
308
- }
325
+ return requestUtils.sendRequest({ method: 'get', options })
326
+ }
309
327
 
310
328
  HTTPClient.prototype.checkLibrary = function checkLibrary(data) {
311
329
  const options = _.cloneDeep(this.requestOptions)
@@ -321,6 +339,20 @@ HTTPClient.prototype.getSbom = function getSbom(config) {
321
339
  return requestUtils.sendRequest({ method: 'get', options })
322
340
  }
323
341
 
342
+ // analytics
343
+
344
+ HTTPClient.prototype.postAnalyticsFunction = function (config, provider, body) {
345
+ const url = createAnalyticsFunctionPostUrl(config, provider)
346
+ const options = { ...this.requestOptions, body, url }
347
+
348
+ return requestUtils.sendRequest({ method: 'post', options })
349
+ }
350
+
351
+ const createAnalyticsFunctionPostUrl = (config, provider) => {
352
+ const url = getServerlessHost(config)
353
+ return `${url}/organizations/${config.organizationId}/providers/${provider}/analytics`
354
+ }
355
+
324
356
  // scan
325
357
  const createGetScanIdURL = config => {
326
358
  return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/`
@@ -350,6 +382,10 @@ function createScanProjectUrl(config) {
350
382
  return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}`
351
383
  }
352
384
 
385
+ const createEventCollectorURL = (config, scanId) => {
386
+ return `${config.host}/Contrast/api/sast/organizations/${config.organizationId}/projects/${config.projectId}/scans/${scanId}/events`
387
+ }
388
+
353
389
  const createGlobalPropertiesUrl = protocol => {
354
390
  return `${protocol}/Contrast/api/ng/global/properties`
355
391
  }
@@ -384,6 +420,10 @@ function createSpecificReportWithProdUrl(config, reportId) {
384
420
  )
385
421
  }
386
422
 
423
+ function createSpecificReportStatusURL(config, reportId) {
424
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/snapshots/${reportId}/status`
425
+ }
426
+
387
427
  function createDataUrl() {
388
428
  return `https://ardy.contrastsecurity.com/production`
389
429
  }
@@ -64,6 +64,14 @@ const proxyError = () => {
64
64
  generalError('proxyErrorHeader', 'proxyErrorMessage')
65
65
  }
66
66
 
67
+ const maxAppError = () => {
68
+ generalError(
69
+ 'No applications remaining',
70
+ 'You have reached the maximum number of application you can create.'
71
+ )
72
+ process.exit(1)
73
+ }
74
+
67
75
  const failOptionError = () => {
68
76
  console.log(
69
77
  '\n ******************************** ' +
@@ -140,5 +148,6 @@ export {
140
148
  findCommandOnError,
141
149
  snapshotFailureError,
142
150
  vulnerabilitiesFailureError,
143
- reportFailureError
151
+ reportFailureError,
152
+ maxAppError
144
153
  }
@@ -37,5 +37,5 @@ export async function findLatestCLIVersion(updateMessageHidden: boolean) {
37
37
  }
38
38
 
39
39
  export async function isCorrectNodeVersion(currentVersion: string) {
40
- return semver.satisfies(currentVersion, '>=16.13.2 <17')
40
+ return semver.satisfies(currentVersion, '>=16')
41
41
  }
@@ -13,7 +13,7 @@ const MEDIUM = 'MEDIUM'
13
13
  const HIGH = 'HIGH'
14
14
  const CRITICAL = 'CRITICAL'
15
15
  const APP_NAME = 'contrast'
16
- const APP_VERSION = '1.0.6'
16
+ const APP_VERSION = '1.0.7'
17
17
  const TIMEOUT = 120000
18
18
  const HIGH_COLOUR = '#ff9900'
19
19
  const CRITICAL_COLOUR = '#e35858'
@@ -146,7 +146,7 @@ const en_locales = () => {
146
146
  constantsHeader: 'CodeSec by Contrast Security',
147
147
  constantsPrerequisitesContentScanLanguages: 'Java & JavaScript supported',
148
148
  constantsContrastContent:
149
- 'Use the Contrast CLI to run a scan (Java, JavaScript and .NET ) or lambda command (Java and Python) to find your vulnerabilities and start securing your code.',
149
+ "Use the 'contrast' command for fast and accurate security analysis of your applications and APIs (Java, JavaScript and .NET ) as well as serverless functions (AWS lambda, Java and Python).",
150
150
  constantsUsageGuideContentRecommendation:
151
151
  'Our recommendation is that this is invoked as part of a CI pipeline so that running the cli is automated as part of your build process.',
152
152
  constantsPrerequisitesHeader: 'Pre-requisites',
@@ -356,6 +356,7 @@ const en_locales = () => {
356
356
  scanZipError:
357
357
  'A .zip archive can be used for Javascript Scan. Archive found %s does not contain .JS files for Scan.',
358
358
  fileNotExist: 'File specified does not exist, please check and try again.',
359
+ scanFileIsEmpty: 'File specified is empty. Please choose another.',
359
360
  fileHasWhiteSpacesError:
360
361
  'File cannot have spaces, please rename or choose another file to Scan.',
361
362
  zipFileException: 'Error reading zip file',
@@ -395,6 +396,7 @@ const en_locales = () => {
395
396
  'saves the output in specified format Txt text, sbom',
396
397
  scanNotCompleted:
397
398
  'Scan not completed. Check for framework and language support here: %s',
399
+ auditNotCompleted: 'audit not completed. Please try again',
398
400
  scanNoVulnerabilitiesFound: '👏 No vulnerabilities found',
399
401
  scanNoVulnerabilitiesFoundSecureCode: '👍 Your code looks secure.',
400
402
  scanNoVulnerabilitiesFoundGoodWork: '👏 Keep up the good work.',
@@ -0,0 +1,9 @@
1
+ import { getHttpClient } from '../utils/commonApi'
2
+ import { getAuth } from '../utils/paramsUtil/paramHandler'
3
+ import { AnalyticsOption } from './types'
4
+
5
+ export const postAnalytics = (data: AnalyticsOption, provider = 'aws') => {
6
+ const config = getAuth()
7
+ const client = getHttpClient(config)
8
+ return client.postAnalyticsFunction(config, provider, data)
9
+ }
package/src/lambda/arn.ts CHANGED
@@ -10,7 +10,8 @@ type ARN = {
10
10
  resourceId?: string
11
11
  }
12
12
 
13
- const ARN_REGEX = /arn:(?<partition>[^:\n]*):(?<service>[^:\n]*):(?<region>[^:\n]*):(?<accountId>[^:\n]*):(?<ignore>(?<resource>[^:/\n]*)[:/])?(?<resourceId>.*)/
13
+ const ARN_REGEX =
14
+ /arn:(?<partition>[^:\n]*):(?<service>[^:\n]*):(?<region>[^:\n]*):(?<accountId>[^:\n]*):(?<ignore>(?<resource>[^:/\n]*)[:/])?(?<resourceId>.*)/
14
15
 
15
16
  const parseARN = (arn: string | undefined) => {
16
17
  if (!arn) {
@@ -14,18 +14,8 @@ import { printResults } from './utils'
14
14
  import { getAllLambdas, printAvailableLambdas } from './lambdaUtils'
15
15
  import { sleep } from '../utils/requestUtils'
16
16
  import ora from '../utils/oraWrapper'
17
-
18
- type LambdaOptions = {
19
- functionName?: string
20
- listFunctions?: boolean
21
- region?: string
22
- endpointUrl?: string
23
- profile?: string
24
- help?: boolean
25
- verbose?: boolean
26
- jsonOutput?: boolean
27
- _unknown?: string[]
28
- }
17
+ import { postAnalytics } from './analytics'
18
+ import { LambdaOptions, AnalyticsOption, StatusType, EventType } from './types'
29
19
 
30
20
  type ApiParams = {
31
21
  organizationId: string
@@ -74,10 +64,20 @@ const getLambdaOptions = (argv: string[]) => {
74
64
  }
75
65
 
76
66
  const processLambda = async (argv: string[]) => {
67
+ let errorMsg
68
+ let scanInfo: { functionArn: string; scanId: string } | undefined
69
+ const commandSessionId = Date.now().toString(36)
77
70
  try {
78
71
  const lambdaOptions = getLambdaOptions(argv)
79
72
  const { help } = lambdaOptions
80
-
73
+ const startCommandAnalytics: AnalyticsOption = {
74
+ arguments: lambdaOptions,
75
+ sessionId: commandSessionId,
76
+ eventType: EventType.START
77
+ }
78
+ postAnalytics(startCommandAnalytics).catch((error: Error) => {
79
+ /* ignore */
80
+ })
81
81
  if (help) {
82
82
  return handleLambdaHelp()
83
83
  }
@@ -87,15 +87,33 @@ const processLambda = async (argv: string[]) => {
87
87
  if (lambdaOptions.listFunctions) {
88
88
  await getAvailableFunctions(lambdaOptions)
89
89
  } else {
90
- await actualProcessLambda(lambdaOptions)
90
+ scanInfo = await actualProcessLambda(lambdaOptions)
91
91
  }
92
92
  } catch (error) {
93
93
  if (error instanceof CliError) {
94
- console.error(error.getErrorMessage())
94
+ errorMsg = error.getErrorMessage()
95
95
  } else if (error instanceof Error) {
96
- console.error(error.message)
96
+ errorMsg = error.message
97
+ }
98
+ } finally {
99
+ const endCommandAnalytics: AnalyticsOption = {
100
+ sessionId: commandSessionId,
101
+ eventType: EventType.END,
102
+ status: errorMsg ? StatusType.FAILED : StatusType.SUCCESS
103
+ }
104
+ if (errorMsg) {
105
+ endCommandAnalytics.errorMsg = errorMsg
106
+ console.error(errorMsg)
107
+ }
108
+ if (scanInfo) {
109
+ endCommandAnalytics.scanFunctionData = scanInfo
110
+ }
111
+ await postAnalytics(endCommandAnalytics).catch((error: Error) => {
112
+ /* ignore */
113
+ })
114
+ if (errorMsg) {
115
+ process.exit(1)
97
116
  }
98
- process.exit(1)
99
117
  }
100
118
  }
101
119
 
@@ -162,6 +180,8 @@ const actualProcessLambda = async (lambdaOptions: LambdaOptions) => {
162
180
  if (results?.length) {
163
181
  printResults(results)
164
182
  }
183
+
184
+ return { functionArn, scanId }
165
185
  }
166
186
 
167
187
  const validateRequiredLambdaParams = (options: LambdaOptions) => {
@@ -0,0 +1,35 @@
1
+ export enum StatusType {
2
+ FAILED = 'failed',
3
+ SUCCESS = 'success'
4
+ }
5
+
6
+ export enum EventType {
7
+ START = 'start_command_session',
8
+ END = 'end_command_session'
9
+ }
10
+
11
+ export type LambdaOptions = {
12
+ functionName?: string
13
+ listFunctions?: boolean
14
+ region?: string
15
+ endpointUrl?: string
16
+ profile?: string
17
+ help?: boolean
18
+ verbose?: boolean
19
+ jsonOutput?: boolean
20
+ _unknown?: string[]
21
+ }
22
+
23
+ type ScanFunctionData = {
24
+ functionArn: string
25
+ scanId: string
26
+ }
27
+
28
+ export type AnalyticsOption = {
29
+ sessionId: string
30
+ eventType: EventType
31
+ arguments?: LambdaOptions
32
+ scanFunctionData?: ScanFunctionData
33
+ status?: StatusType
34
+ errorMsg?: string
35
+ }
@@ -19,13 +19,8 @@ class PrintVulnerability {
19
19
  whatHappened: string
20
20
 
21
21
  constructor(index: number, vulnerability: any, group?: any[]) {
22
- const {
23
- severityText,
24
- title,
25
- description,
26
- remediation,
27
- categoryText
28
- } = vulnerability
22
+ const { severityText, title, description, remediation, categoryText } =
23
+ vulnerability
29
24
 
30
25
  this.group = group
31
26
  this.vulnerability = vulnerability
@@ -14,7 +14,25 @@ const createGoTSMessage = goTree => {
14
14
  }
15
15
  }
16
16
 
17
+ const createRubyTSMessage = rubyTree => {
18
+ return {
19
+ ruby: {
20
+ rubyDependencyTrees: rubyTree
21
+ }
22
+ }
23
+ }
24
+
25
+ const createPythonTSMessage = pythonTree => {
26
+ return {
27
+ python: {
28
+ pythonDependencyTrees: pythonTree
29
+ }
30
+ }
31
+ }
32
+
17
33
  module.exports = {
18
34
  createJavaTSMessage,
19
- createGoTSMessage
35
+ createGoTSMessage,
36
+ createRubyTSMessage,
37
+ createPythonTSMessage
20
38
  }
@@ -5,9 +5,8 @@ const goParseDeps = require('./goParseDeps')
5
5
  const goAnalysis = (config, languageFiles) => {
6
6
  try {
7
7
  const rawGoDependencies = goReadDepFile.getGoDependencies(config)
8
- const parsedGoDependencies = goParseDeps.parseGoDependencies(
9
- rawGoDependencies
10
- )
8
+ const parsedGoDependencies =
9
+ goParseDeps.parseGoDependencies(rawGoDependencies)
11
10
 
12
11
  return createGoTSMessage(parsedGoDependencies)
13
12
  } catch (e) {
@@ -11,16 +11,15 @@ const determineProjectTypeAndCwd = (files, projectPath) => {
11
11
 
12
12
  if (files[0].includes('pom.xml')) {
13
13
  projectData.projectType = MAVEN
14
- projectData.cwd = projectPath
15
- ? projectPath
16
- : files[0].replace('pom.xml', '')
17
14
  } else if (files[0].includes('build.gradle')) {
18
15
  projectData.projectType = GRADLE
19
- projectData.cwd = projectPath
20
- ? projectPath
21
- : files[0].replace('pom.xml', '')
22
16
  }
23
17
 
18
+ //clean up the path to be a folder not a file
19
+ projectData.cwd = projectPath
20
+ ? projectPath.replace('pom.xml', '').replace('build.gradle', '')
21
+ : projectPath
22
+
24
23
  return projectData
25
24
  }
26
25
 
@@ -3,11 +3,11 @@ const { parseBuildDeps } = require('./javaBuildDepsParser')
3
3
  const { createJavaTSMessage } = require('../common/formatMessage')
4
4
 
5
5
  const javaAnalysis = (config, languageFiles) => {
6
- languageFiles.java.forEach(file => {
6
+ languageFiles.JAVA.forEach(file => {
7
7
  file.replace('build.gradle.kts', 'build.gradle')
8
8
  })
9
9
 
10
- const javaDeps = buildJavaTree(config, languageFiles.java)
10
+ const javaDeps = buildJavaTree(config, languageFiles.JAVA)
11
11
  return createJavaTSMessage(javaDeps)
12
12
  }
13
13
 
@@ -0,0 +1,48 @@
1
+ const multiReplace = require('string-multiple-replace')
2
+ const fs = require('fs')
3
+
4
+ const readAndParseProjectFile = projectPath => {
5
+ const filePath = filePathForWindows(projectPath + '/Pipfile')
6
+ const pipFile = fs.readFileSync(filePath, 'utf8')
7
+
8
+ const matcherObj = { '"': '' }
9
+ const sequencer = ['"']
10
+ const parsedPipfile = multiReplace(pipFile, matcherObj, sequencer)
11
+
12
+ const pythonArray = parsedPipfile.split('\n')
13
+
14
+ return pythonArray.filter(element => element !== '' && !element.includes('#'))
15
+ }
16
+
17
+ const readAndParseLockFile = projectPath => {
18
+ const filePath = filePathForWindows(projectPath + '/Pipfile.lock')
19
+ const lockFile = fs.readFileSync(filePath, 'utf8')
20
+ let parsedPipLock = JSON.parse(lockFile)
21
+ parsedPipLock['defaults'] = parsedPipLock['default']
22
+ return parsedPipLock
23
+ }
24
+
25
+ const getPythonDeps = config => {
26
+ try {
27
+ const parseProject = readAndParseProjectFile(config.projectPath)
28
+ const parsePip = readAndParseLockFile(config.projectPath)
29
+
30
+ return { pipfileLock: parseProject, pipfilDependanceies: parsePip }
31
+ } catch (err) {
32
+ console.log(err.message.toString())
33
+ process.exit(1)
34
+ }
35
+ }
36
+
37
+ const filePathForWindows = path => {
38
+ if (process.platform === 'win32') {
39
+ path = path.replace(/\//g, '\\')
40
+ }
41
+ return path
42
+ }
43
+
44
+ module.exports = {
45
+ getPythonDeps,
46
+ readAndParseProjectFile,
47
+ readAndParseLockFile
48
+ }
@@ -0,0 +1,11 @@
1
+ const { createPythonTSMessage } = require('../common/formatMessage')
2
+ const { getPythonDeps } = require('./analysis')
3
+
4
+ const pythonAnalysis = (config, languageFiles) => {
5
+ const pythonDeps = getPythonDeps(config, languageFiles.PYTHON)
6
+ return createPythonTSMessage(pythonDeps)
7
+ }
8
+
9
+ module.exports = {
10
+ pythonAnalysis
11
+ }