@contrast/contrast 1.0.4 → 1.0.5

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 (62) hide show
  1. package/.prettierignore +2 -0
  2. package/dist/audit/autodetection/autoDetectLanguage.js +32 -0
  3. package/dist/audit/catalogueApplication/catalogueApplication.js +2 -11
  4. package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +4 -2
  5. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +25 -0
  6. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +3 -17
  7. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +1 -1
  8. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -16
  9. package/dist/commands/audit/auditConfig.js +8 -2
  10. package/dist/commands/audit/auditController.js +8 -2
  11. package/dist/commands/scan/processScan.js +6 -3
  12. package/dist/commands/scan/sca/scaAnalysis.js +44 -0
  13. package/dist/common/HTTPClient.js +0 -1
  14. package/dist/common/errorHandling.js +7 -17
  15. package/dist/constants/constants.js +14 -2
  16. package/dist/constants/locales.js +28 -35
  17. package/dist/constants.js +20 -0
  18. package/dist/scaAnalysis/common/formatMessage.js +11 -0
  19. package/dist/scaAnalysis/common/treeUpload.js +30 -0
  20. package/dist/scaAnalysis/java/analysis.js +116 -0
  21. package/dist/scaAnalysis/java/index.js +18 -0
  22. package/dist/scaAnalysis/java/javaBuildDepsParser.js +326 -0
  23. package/dist/scan/autoDetection.js +46 -1
  24. package/dist/scan/fileUtils.js +73 -1
  25. package/dist/scan/formatScanOutput.js +212 -0
  26. package/dist/scan/help.js +3 -1
  27. package/dist/scan/models/groupedResultsModel.js +2 -1
  28. package/dist/scan/scan.js +1 -96
  29. package/dist/scan/scanController.js +1 -2
  30. package/dist/scan/scanResults.js +3 -17
  31. package/package.json +2 -1
  32. package/src/audit/autodetection/autoDetectLanguage.ts +40 -0
  33. package/src/audit/catalogueApplication/catalogueApplication.js +4 -16
  34. package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +9 -5
  35. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +71 -0
  36. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +3 -25
  37. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +1 -1
  38. package/src/audit/languageAnalysisEngine/sendSnapshot.js +2 -24
  39. package/src/commands/audit/auditConfig.ts +12 -3
  40. package/src/commands/audit/auditController.ts +9 -2
  41. package/src/commands/audit/processAudit.ts +3 -0
  42. package/src/commands/scan/processScan.js +8 -3
  43. package/src/commands/scan/sca/scaAnalysis.js +73 -0
  44. package/src/common/HTTPClient.js +1 -1
  45. package/src/common/errorHandling.ts +7 -24
  46. package/src/constants/constants.js +14 -2
  47. package/src/constants/locales.js +30 -49
  48. package/src/constants.js +22 -0
  49. package/src/scaAnalysis/common/formatMessage.js +10 -0
  50. package/src/scaAnalysis/common/treeUpload.js +34 -0
  51. package/src/scaAnalysis/java/analysis.js +159 -0
  52. package/src/scaAnalysis/java/index.js +21 -0
  53. package/src/scaAnalysis/java/javaBuildDepsParser.js +391 -0
  54. package/src/scan/autoDetection.js +54 -1
  55. package/src/scan/fileUtils.js +91 -1
  56. package/src/scan/formatScanOutput.ts +241 -0
  57. package/src/scan/help.js +3 -1
  58. package/src/scan/models/groupedResultsModel.ts +7 -5
  59. package/src/scan/models/resultContentModel.ts +2 -2
  60. package/src/scan/scan.ts +0 -130
  61. package/src/scan/scanController.js +1 -2
  62. package/src/scan/scanResults.js +9 -17
@@ -0,0 +1,159 @@
1
+ const child_process = require('child_process')
2
+ const path = require('path')
3
+ const i18n = require('i18n')
4
+ const fs = require('fs')
5
+
6
+ const MAVEN = 'maven'
7
+ const GRADLE = 'gradle'
8
+
9
+ const determineProjectTypeAndCwd = (files, projectPath) => {
10
+ const projectData = {}
11
+
12
+ if (files[0].includes('pom.xml')) {
13
+ projectData.projectType = MAVEN
14
+ projectData.cwd = projectPath
15
+ ? projectPath
16
+ : files[0].replace('pom.xml', '')
17
+ } else if (files[0].includes('build.gradle')) {
18
+ projectData.projectType = GRADLE
19
+ projectData.cwd = projectPath
20
+ ? projectPath
21
+ : files[0].replace('pom.xml', '')
22
+ }
23
+
24
+ return projectData
25
+ }
26
+
27
+ const buildMaven = async (config, projectData, timeout) => {
28
+ let cmdStdout
29
+ let mvn_settings = ''
30
+
31
+ try {
32
+ // Allow users to provide a custom location for their settings.xml
33
+ if (config.mavenSettingsPath) {
34
+ mvn_settings = ' -s ' + config.mavenSettingsPath
35
+ }
36
+ cmdStdout = child_process.execSync(
37
+ 'mvn dependency:tree -B' + mvn_settings,
38
+ {
39
+ cwd: projectData.cwd,
40
+ timeout
41
+ }
42
+ )
43
+ // output.mvnDependancyTreeOutput = cmdStdout.toString()
44
+ // console.log(cmdStdout.toString())
45
+ return cmdStdout.toString()
46
+ } catch (err) {
47
+ try {
48
+ child_process.execSync('mvn --version', {
49
+ cwd: projectData.cwd,
50
+ timeout
51
+ })
52
+ throw new Error(
53
+ i18n.__('mavenDependencyTreeNonZero', projectData.cwd, `${err.message}`)
54
+ )
55
+ } catch (mvnErr) {
56
+ throw new Error(
57
+ i18n.__('mavenNotInstalledError', projectData.cwd, `${mvnErr.message}`)
58
+ )
59
+ }
60
+ }
61
+ }
62
+
63
+ const buildGradle = (config, projectData, timeout) => {
64
+ let cmdStdout
65
+ let output = {}
66
+
67
+ try {
68
+ // path.sep is user here to either execute as "./gradlew" for UNIX/Linux/MacOS
69
+ // & ".\gradlew" for Windows
70
+ // Check if the user has specified a sub-project
71
+ if (config.subProject) {
72
+ cmdStdout = child_process.execSync(
73
+ '.' +
74
+ path.sep +
75
+ 'gradlew :' +
76
+ config.subProject +
77
+ ':dependencies --configuration runtimeClasspath',
78
+ {
79
+ cwd: projectData.cwd,
80
+ timeout
81
+ }
82
+ )
83
+ } else {
84
+ cmdStdout = child_process.execSync(
85
+ '.' +
86
+ path.sep +
87
+ 'gradlew dependencies --configuration runtimeClasspath',
88
+ {
89
+ cwd: projectData.cwd,
90
+ timeout
91
+ }
92
+ )
93
+ }
94
+ if (
95
+ cmdStdout
96
+ .toString()
97
+ .includes(
98
+ "runtimeClasspath - Runtime classpath of source set 'main'.\n" +
99
+ 'No dependencies'
100
+ )
101
+ ) {
102
+ cmdStdout = child_process.execSync(
103
+ '.' + path.sep + 'gradlew dependencies',
104
+ {
105
+ cwd: projectData.cwd,
106
+ timeout
107
+ }
108
+ )
109
+ }
110
+ output.mvnDependancyTreeOutput = cmdStdout.toString()
111
+ return output
112
+ } catch (err) {
113
+ if (
114
+ fs.existsSync(projectData.cwd + 'gradlew') ||
115
+ fs.existsSync(projectData.cwd + 'gradlew.bat')
116
+ ) {
117
+ throw new Error(
118
+ i18n.__(
119
+ 'gradleDependencyTreeNonZero',
120
+ projectData.cwd,
121
+ `${err.message}`
122
+ )
123
+ )
124
+ } else {
125
+ throw new Error(
126
+ i18n.__('gradleWrapperUnavailable', projectData.cwd, `${err.message}`)
127
+ )
128
+ }
129
+ }
130
+ }
131
+
132
+ const getJavaBuildDeps = async (config, files) => {
133
+ const timeout = 960000
134
+ let output = {
135
+ mvnDependancyTreeOutput: undefined,
136
+ projectType: undefined
137
+ }
138
+
139
+ try {
140
+ const projectData = determineProjectTypeAndCwd(files, config.projectPath)
141
+ if (projectData.projectType === MAVEN) {
142
+ output.mvnDependancyTreeOutput = await buildMaven(
143
+ config,
144
+ projectData,
145
+ timeout
146
+ )
147
+ } else if (projectData.projectType === GRADLE) {
148
+ output.mvnDependancyTreeOutput = buildGradle(config, projectData, timeout)
149
+ }
150
+ output.projectType = projectData.projectType
151
+ return output
152
+ } catch (err) {
153
+ //
154
+ }
155
+ }
156
+
157
+ module.exports = {
158
+ getJavaBuildDeps
159
+ }
@@ -0,0 +1,21 @@
1
+ const { getJavaBuildDeps } = require('./analysis')
2
+ const { parseBuildDeps } = require('./javaBuildDepsParser')
3
+ const { createJavaTSMessage } = require('../common/formatMessage')
4
+
5
+ const javaAnalysis = async (config, languageFiles) => {
6
+ languageFiles.java.forEach(file => {
7
+ file.replace('build.gradle.kts', 'build.gradle')
8
+ })
9
+
10
+ const javaDeps = await buildJavaTree(config, languageFiles.java)
11
+ return createJavaTSMessage(javaDeps)
12
+ }
13
+
14
+ const buildJavaTree = async (config, files) => {
15
+ const javaBuildDeps = await getJavaBuildDeps(config, files)
16
+ return parseBuildDeps(config, javaBuildDeps)
17
+ }
18
+
19
+ module.exports = {
20
+ javaAnalysis
21
+ }
@@ -0,0 +1,391 @@
1
+ const i18n = require('i18n')
2
+ const StringBuilder = require('string-builder')
3
+ let sb = new StringBuilder()
4
+
5
+ const parseBuildDeps = (config, input) => {
6
+ const { mvnDependancyTreeOutput, projectType } = input
7
+ // console.log(projectType)
8
+ try {
9
+ return parseGradle(mvnDependancyTreeOutput, config, projectType)
10
+ } catch (err) {
11
+ throw new Error(i18n.__('javaParseProjectFile') + `${err.message}`)
12
+ }
13
+ }
14
+ const preParser = shavedOutput => {
15
+ let obj = []
16
+ for (let dep in shavedOutput) {
17
+ obj.push(
18
+ shavedOutput[dep]
19
+ .replace('+-', '+---')
20
+ .replace('[INFO]', '')
21
+ .replace('\\-', '\\---')
22
+ .replace(':jar:', ':')
23
+ .replace(':test', '')
24
+ .replace(':compile', '')
25
+ .replace(' +', '+')
26
+ .replace(' |', '|')
27
+ .replace(' \\', '\\')
28
+ .replace(':runtime', '')
29
+ )
30
+ }
31
+
32
+ let depTree = []
33
+ for (let x in obj) {
34
+ let nodeLevel = computeRelationToLastElement(obj[x])
35
+
36
+ let notLastLevel =
37
+ obj[x].startsWith('|') ||
38
+ obj[x].startsWith('+') ||
39
+ obj[x].startsWith('\\')
40
+
41
+ if (notLastLevel) {
42
+ if (nodeLevel === 0) {
43
+ depTree.push(obj[x])
44
+ } else {
45
+ let level = computeLevel(nodeLevel)
46
+ let validatedLevel = addIndentation(nodeLevel === 2 ? 5 : level, obj[x])
47
+ depTree.push(validatedLevel)
48
+ }
49
+ } else {
50
+ let level = computeLevel(nodeLevel)
51
+ let validatedLevel = addIndentation(nodeLevel === 3 ? 5 : level, obj[x])
52
+ depTree.push(validatedLevel)
53
+ }
54
+ }
55
+
56
+ return depTree
57
+ }
58
+
59
+ const shaveOutput = (gradleDependencyTreeOutput, projectType) => {
60
+ let shavedOutput = gradleDependencyTreeOutput.split('\n')
61
+
62
+ // console.log(projectType)
63
+
64
+ if (projectType === 'maven') {
65
+ shavedOutput = preParser(shavedOutput)
66
+ }
67
+
68
+ let obj = []
69
+ for (let key in shavedOutput) {
70
+ if (shavedOutput[key].includes('project :')) {
71
+ //skip
72
+ } else if (
73
+ shavedOutput[key].includes('+---') ||
74
+ shavedOutput[key].includes('\\---')
75
+ ) {
76
+ obj.push(shavedOutput[key])
77
+ }
78
+ }
79
+ return obj
80
+ }
81
+
82
+ const computeIndentation = element => {
83
+ let hasPlus = element.includes('+')
84
+ let hasSlash = element.includes('\\')
85
+ if (hasPlus) {
86
+ return element.substring(element.indexOf('+'))
87
+ }
88
+ if (hasSlash) {
89
+ return element.substring(element.indexOf('\\'))
90
+ }
91
+ }
92
+
93
+ const computeLevel = nodeLevel => {
94
+ let num = [5, 8, 11, 14, 17, 20]
95
+ for (let z in num) {
96
+ if (num[z] === nodeLevel) {
97
+ let n = parseInt(z)
98
+ return 5 * (n + 2)
99
+ }
100
+ }
101
+ }
102
+
103
+ const addIndentation = (number, str) => {
104
+ str = computeIndentation(str)
105
+ sb.clear() // need to clear so each dep doesn't append to the string
106
+ for (let j = 0; j < number; j++) {
107
+ sb.append(' ')
108
+ }
109
+ sb.append(str)
110
+ return sb.toString()
111
+ }
112
+
113
+ const computeRelationToLastElement = element => {
114
+ let hasPlus = element.includes('+---')
115
+ let hasSlash = element.includes('\\---')
116
+ if (hasPlus) {
117
+ return element.split('+---')[0].length
118
+ }
119
+ if (hasSlash) {
120
+ return element.split('\\---')[0].length
121
+ }
122
+ }
123
+
124
+ const stripElement = element => {
125
+ return element
126
+ .replace(/[|]/g, '')
127
+ .replace('+---', '')
128
+ .replace('\\---', '')
129
+ .replace(/[' ']/g, '')
130
+ .replace('(c)', '')
131
+ .replace('->', '@')
132
+ .replace('(*)', '')
133
+ }
134
+
135
+ const checkVersion = element => {
136
+ let version = element.split(':')
137
+ return version[version.length - 1]
138
+ }
139
+
140
+ const createElement = (element, isRoot) => {
141
+ let tree
142
+ let cleanElement = stripElement(element)
143
+ let splitGroupName = cleanElement.split(':')
144
+
145
+ let validateVersion = false
146
+ if (!element.includes('->')) {
147
+ validateVersion = true
148
+ }
149
+
150
+ tree = {
151
+ artifactID: splitGroupName[1],
152
+ group: splitGroupName[0],
153
+ version: validateVersion
154
+ ? checkVersion(cleanElement)
155
+ : splitGroupName[splitGroupName.length - 1],
156
+ scope: 'compile',
157
+ type: isRoot ? 'direct' : 'transitive',
158
+ edges: {}
159
+ }
160
+ return tree
161
+ }
162
+
163
+ const getElementHeader = element => {
164
+ let elementHeader = stripElement(element)
165
+ elementHeader = elementHeader.replace(':', '/')
166
+ elementHeader = elementHeader.replace(':', '@')
167
+
168
+ return elementHeader
169
+ }
170
+
171
+ const buildElement = (element, rootElement, parentOfCurrent, tree, isRoot) => {
172
+ let childElement = createElement(element, isRoot)
173
+ let elementHeader = getElementHeader(element)
174
+ let levelsArray = [rootElement, parentOfCurrent]
175
+ const treeNode = getNestedObject(tree, levelsArray)
176
+ const rootNode = getNestedObject(tree, [rootElement])
177
+
178
+ // eslint-disable-next-line
179
+ if (!rootNode.hasOwnProperty(elementHeader)) {
180
+ tree[rootElement][elementHeader] = childElement
181
+ }
182
+ treeNode.edges[elementHeader] = elementHeader
183
+ }
184
+
185
+ const hasChildren = (nextNodeLevel, nodeLevel) => {
186
+ if (nextNodeLevel > nodeLevel) {
187
+ return true
188
+ }
189
+ }
190
+
191
+ const lastChild = (nextNodeLevel, nodeLevel) => {
192
+ if (nextNodeLevel < nodeLevel) {
193
+ return true
194
+ }
195
+ }
196
+
197
+ const calculateLevels = (nextNodeLevel, nodeLevel) => {
198
+ return (nodeLevel - nextNodeLevel) / 5
199
+ }
200
+
201
+ const buildTree = shavedOutput => {
202
+ let tree = {}
203
+ let rootElement
204
+ let levelNodes = []
205
+
206
+ shavedOutput.forEach((element, index) => {
207
+ if (index === 0) {
208
+ // console.log(element, index)
209
+ let cleanElement = stripElement(element)
210
+ let elementHeader = getElementHeader(cleanElement)
211
+ let splitElement = element.split(' ')
212
+ let splitGroupName = splitElement[1].split(':')
213
+
214
+ let validateVersion = false
215
+ if (!element.includes('->')) {
216
+ validateVersion = true
217
+ }
218
+
219
+ tree[splitGroupName[0]] = {}
220
+ tree[splitGroupName[0]][elementHeader] = {
221
+ artifactID: splitGroupName[1],
222
+ group: splitGroupName[0],
223
+ version: validateVersion
224
+ ? checkVersion(cleanElement)
225
+ : splitElement[splitElement.length - 1],
226
+ scope: 'compile',
227
+ type: 'direct',
228
+ edges: {}
229
+ }
230
+
231
+ rootElement = splitGroupName[0]
232
+ levelNodes.push(elementHeader)
233
+ }
234
+
235
+ if (shavedOutput.length - 1 === index) {
236
+ // console.log(element, index)
237
+ const parentOfCurrent = levelNodes[levelNodes.length - 1]
238
+ let nodeLevel = computeRelationToLastElement(element)
239
+
240
+ let validateVersion = false
241
+ if (!element.includes('->')) {
242
+ validateVersion = true
243
+ }
244
+
245
+ if (nodeLevel === 0) {
246
+ let cleanElement = stripElement(element)
247
+ let elementHeader = getElementHeader(cleanElement)
248
+ let splitElement = element.split(' ')
249
+ let splitGroupName = splitElement[1].split(':')
250
+ tree[rootElement][elementHeader] = {
251
+ artifactID: splitGroupName[1],
252
+ group: splitGroupName[0],
253
+ version: validateVersion
254
+ ? checkVersion(cleanElement)
255
+ : splitElement[splitElement.length - 1],
256
+ scope: 'compile',
257
+ type: 'direct',
258
+ edges: {}
259
+ }
260
+ } else {
261
+ buildElement(element, rootElement, parentOfCurrent, tree)
262
+ }
263
+ }
264
+
265
+ if (index >= 1 && index < shavedOutput.length - 1) {
266
+ let nodeLevel = computeRelationToLastElement(element)
267
+ let nextNodeLevel = computeRelationToLastElement(shavedOutput[index + 1])
268
+ const parentOfCurrent = levelNodes[levelNodes.length - 1]
269
+
270
+ let isRoot = false
271
+ if (nodeLevel === 0) {
272
+ isRoot = true
273
+ }
274
+
275
+ // useful for debugging
276
+ // console.log(
277
+ // element,
278
+ // index,
279
+ // 'nodeLevel:',
280
+ // nodeLevel,
281
+ // 'nextNodeLevel:',
282
+ // nextNodeLevel,
283
+ // 'parentofCurrent:',
284
+ // parentOfCurrent
285
+ // )
286
+
287
+ if (isRoot) {
288
+ let cleanElement = stripElement(element)
289
+ let elementHeader = getElementHeader(cleanElement)
290
+ let splitElement = element.split(' ')
291
+ let splitGroupName = splitElement[1].split(':')
292
+
293
+ let validateVersion = false
294
+ if (!element.includes('->')) {
295
+ validateVersion = true
296
+ }
297
+
298
+ tree[rootElement][elementHeader] = {
299
+ artifactID: splitGroupName[1],
300
+ group: splitGroupName[0],
301
+ version: validateVersion
302
+ ? checkVersion(cleanElement)
303
+ : splitElement[splitElement.length - 1],
304
+ scope: 'compile',
305
+ type: 'direct',
306
+ edges: {}
307
+ }
308
+ levelNodes.push(elementHeader)
309
+ return
310
+ }
311
+
312
+ let elementHeader = getElementHeader(element)
313
+ buildElement(element, rootElement, parentOfCurrent, tree, isRoot)
314
+
315
+ if (hasChildren(nextNodeLevel, nodeLevel)) {
316
+ buildElement(element, rootElement, parentOfCurrent, tree, isRoot)
317
+ levelNodes.push(elementHeader)
318
+ }
319
+
320
+ if (lastChild(nextNodeLevel, nodeLevel)) {
321
+ let levelDifference = calculateLevels(nextNodeLevel, nodeLevel)
322
+ if (levelDifference === 0) {
323
+ levelNodes.pop()
324
+ } else {
325
+ let i
326
+ for (i = 0; i < levelDifference; i++) {
327
+ levelNodes.pop()
328
+ }
329
+ }
330
+ }
331
+ }
332
+ })
333
+
334
+ return tree
335
+ }
336
+
337
+ const getNestedObject = (nestedObj, pathArr) => {
338
+ return pathArr.reduce(
339
+ (obj, key) => (obj && obj[key] !== 'undefined' ? obj[key] : undefined),
340
+ nestedObj
341
+ )
342
+ }
343
+
344
+ // emit any "+--- project :" within the tree
345
+ const parseSubProject = shavedOutput => {
346
+ let obj = []
347
+ for (let key in shavedOutput) {
348
+ if (!shavedOutput[key].includes('project')) {
349
+ obj.push(shavedOutput[key])
350
+ }
351
+ }
352
+ return obj
353
+ }
354
+
355
+ const validateIndentation = shavedOutput => {
356
+ let validatedTree = []
357
+ shavedOutput.forEach((element, index) => {
358
+ let nextNodeLevel
359
+ let nodeLevel = computeRelationToLastElement(element)
360
+ if (shavedOutput[index + 1] !== undefined) {
361
+ nextNodeLevel = computeRelationToLastElement(shavedOutput[index + 1])
362
+ }
363
+ if (index === 0) {
364
+ validatedTree.push(shavedOutput[index])
365
+ validatedTree.push(shavedOutput[index + 1])
366
+ } else if (nextNodeLevel > nodeLevel + 5) {
367
+ return
368
+ } else {
369
+ validatedTree.push(shavedOutput[index + 1])
370
+ }
371
+ })
372
+ validatedTree.pop()
373
+ return validatedTree
374
+ }
375
+
376
+ const parseGradle = (gradleDependencyTreeOutput, config, projectType) => {
377
+ let shavedOutput = shaveOutput(gradleDependencyTreeOutput, projectType)
378
+
379
+ if (config.subProject) {
380
+ let subProject = parseSubProject(shavedOutput)
381
+ let validatedOutput = validateIndentation(subProject)
382
+ return buildTree(validatedOutput)
383
+ } else {
384
+ let validatedOutput = validateIndentation(shavedOutput)
385
+ return buildTree(validatedOutput)
386
+ }
387
+ }
388
+
389
+ module.exports = {
390
+ parseBuildDeps
391
+ }
@@ -1,5 +1,7 @@
1
1
  const i18n = require('i18n')
2
2
  const fileFinder = require('./fileUtils')
3
+ const languageResolver = require('../audit/languageAnalysisEngine/reduceIdentifiedLanguages')
4
+ const rootFile = require('../audit/languageAnalysisEngine/getProjectRootFilenames')
3
5
 
4
6
  const autoDetectFileAndLanguage = async configToUse => {
5
7
  const entries = await fileFinder.findFile()
@@ -21,6 +23,39 @@ const autoDetectFileAndLanguage = async configToUse => {
21
23
  }
22
24
  }
23
25
 
26
+ const autoDetectAuditFilesAndLanguages = async () => {
27
+ let languagesFound = []
28
+ console.log(i18n.__('searchingAuditFileDirectory', process.cwd()))
29
+
30
+ await fileFinder.findFilesJava(languagesFound)
31
+ await fileFinder.findFilesJavascript(languagesFound)
32
+ await fileFinder.findFilesPython(languagesFound)
33
+ await fileFinder.findFilesGo(languagesFound)
34
+ await fileFinder.findFilesPhp(languagesFound)
35
+ await fileFinder.findFilesRuby(languagesFound)
36
+
37
+ if (languagesFound.length === 1) {
38
+ return languagesFound
39
+ } else {
40
+ console.log(
41
+ 'found multiple languages, please specify one using --file to run SCA analysis'
42
+ )
43
+ }
44
+ }
45
+
46
+ const manualDetectAuditFilesAndLanguages = async projectPath => {
47
+ let projectRootFilenames = await rootFile.getProjectRootFilenames(projectPath)
48
+ let identifiedLanguages = languageResolver.deduceLanguageScaAnalysis(
49
+ projectRootFilenames
50
+ )
51
+
52
+ if (Object.keys(identifiedLanguages).length === 0) {
53
+ console.log(i18n.__('languageAnalysisNoLanguage', projectPath))
54
+ return []
55
+ }
56
+ return [identifiedLanguages]
57
+ }
58
+
24
59
  const hasWhiteSpace = s => {
25
60
  const filename = s.split('/').pop()
26
61
  return filename.indexOf(' ') >= 0
@@ -42,7 +77,25 @@ const errorOnFileDetection = entries => {
42
77
  process.exit(1)
43
78
  }
44
79
 
80
+ const errorOnAuditFileDetection = entries => {
81
+ if (entries.length > 1) {
82
+ console.log(i18n.__('searchingDirectoryScan'))
83
+ for (let file in entries) {
84
+ console.log('-', entries[file])
85
+ }
86
+ console.log('')
87
+ console.log(i18n.__('specifyFileAuditNotFound'))
88
+ } else {
89
+ console.log(i18n.__('noFileFoundScan'))
90
+ console.log('')
91
+ console.log(i18n.__('specifyFileAuditNotFound'))
92
+ }
93
+ }
94
+
45
95
  module.exports = {
46
96
  autoDetectFileAndLanguage,
47
- errorOnFileDetection
97
+ errorOnFileDetection,
98
+ autoDetectAuditFilesAndLanguages,
99
+ errorOnAuditFileDetection,
100
+ manualDetectAuditFilesAndLanguages
48
101
  }