@contrast/contrast 1.0.2 → 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.
- package/.prettierignore +4 -0
- package/README.md +24 -16
- package/dist/audit/autodetection/autoDetectLanguage.js +32 -0
- package/dist/audit/catalogueApplication/catalogueApplication.js +2 -11
- package/dist/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +30 -13
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +25 -0
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +51 -237
- package/dist/audit/languageAnalysisEngine/report/models/reportLibraryModel.js +19 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +24 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +10 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +24 -129
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +85 -0
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -14
- package/dist/commands/audit/auditConfig.js +8 -2
- package/dist/commands/audit/auditController.js +14 -5
- package/dist/commands/audit/saveFile.js +11 -0
- package/dist/commands/auth/auth.js +19 -1
- package/dist/commands/config/config.js +19 -8
- package/dist/commands/scan/processScan.js +13 -27
- package/dist/commands/scan/sca/scaAnalysis.js +44 -0
- package/dist/common/HTTPClient.js +29 -26
- package/dist/common/errorHandling.js +15 -39
- package/dist/common/versionChecker.js +32 -0
- package/dist/constants/constants.js +16 -2
- package/dist/constants/lambda.js +3 -1
- package/dist/constants/locales.js +58 -48
- package/dist/constants.js +59 -3
- package/dist/index.js +48 -30
- package/dist/lambda/help.js +22 -14
- package/dist/lambda/lambda.js +6 -0
- package/dist/sbom/generateSbom.js +20 -0
- package/dist/scaAnalysis/common/formatMessage.js +11 -0
- package/dist/scaAnalysis/common/treeUpload.js +30 -0
- package/dist/scaAnalysis/java/analysis.js +116 -0
- package/dist/scaAnalysis/java/index.js +18 -0
- package/dist/scaAnalysis/java/javaBuildDepsParser.js +326 -0
- package/dist/scan/autoDetection.js +46 -1
- package/dist/scan/fileUtils.js +73 -1
- package/dist/scan/formatScanOutput.js +212 -0
- package/dist/scan/help.js +6 -2
- package/dist/scan/models/groupedResultsModel.js +11 -0
- package/dist/scan/models/resultContentModel.js +2 -0
- package/dist/scan/models/scanResultsModel.js +11 -0
- package/dist/scan/populateProjectIdAndProjectName.js +1 -0
- package/dist/scan/saveResults.js +9 -10
- package/dist/scan/scan.js +26 -101
- package/dist/scan/scanConfig.js +20 -1
- package/dist/scan/scanController.js +8 -4
- package/dist/scan/scanResults.js +8 -17
- package/dist/utils/getConfig.js +3 -0
- package/dist/utils/requestUtils.js +1 -1
- package/dist/utils/saveFile.js +19 -0
- package/package.json +3 -2
- package/src/audit/autodetection/autoDetectLanguage.ts +40 -0
- package/src/audit/catalogueApplication/catalogueApplication.js +4 -16
- package/src/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +41 -19
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +71 -0
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +105 -0
- package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +30 -0
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +32 -0
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +9 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +56 -0
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +110 -0
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +2 -22
- package/src/commands/audit/auditConfig.ts +12 -3
- package/src/commands/audit/auditController.ts +21 -5
- package/src/commands/audit/processAudit.ts +3 -1
- package/src/commands/audit/saveFile.ts +6 -0
- package/src/commands/auth/auth.js +25 -1
- package/src/commands/config/config.js +22 -8
- package/src/commands/scan/processScan.js +15 -31
- package/src/commands/scan/sca/scaAnalysis.js +73 -0
- package/src/common/HTTPClient.js +42 -36
- package/src/common/errorHandling.ts +17 -48
- package/src/common/versionChecker.ts +41 -0
- package/src/constants/constants.js +17 -4
- package/src/constants/lambda.js +3 -1
- package/src/constants/locales.js +69 -63
- package/src/constants.js +66 -3
- package/src/index.ts +62 -36
- package/src/lambda/help.ts +22 -14
- package/src/lambda/lambda.ts +8 -0
- package/src/sbom/generateSbom.ts +17 -0
- package/src/scaAnalysis/common/formatMessage.js +10 -0
- package/src/scaAnalysis/common/treeUpload.js +34 -0
- package/src/scaAnalysis/java/analysis.js +159 -0
- package/src/scaAnalysis/java/index.js +21 -0
- package/src/scaAnalysis/java/javaBuildDepsParser.js +391 -0
- package/src/scan/autoDetection.js +54 -1
- package/src/scan/fileUtils.js +91 -1
- package/src/scan/formatScanOutput.ts +241 -0
- package/src/scan/help.js +6 -2
- package/src/scan/models/groupedResultsModel.ts +20 -0
- package/src/scan/models/resultContentModel.ts +86 -0
- package/src/scan/models/scanResultsModel.ts +52 -0
- package/src/scan/populateProjectIdAndProjectName.js +1 -0
- package/src/scan/saveResults.js +8 -9
- package/src/scan/scan.ts +62 -0
- package/src/scan/scanConfig.js +26 -1
- package/src/scan/scanController.js +12 -4
- package/src/scan/scanResults.js +19 -17
- package/src/utils/getConfig.ts +12 -0
- package/src/utils/requestUtils.js +1 -1
- package/src/utils/saveFile.js +19 -0
- package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -17
- package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -81
- package/dist/common/findLatestCLIVersion.js +0 -23
- package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -27
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +0 -303
- package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -124
- package/src/audit/languageAnalysisEngine/report/reportingFeature.js +0 -190
- package/src/common/findLatestCLIVersion.ts +0 -27
- package/src/scan/scan.js +0 -167
|
@@ -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
|
}
|
package/src/scan/fileUtils.js
CHANGED
|
@@ -11,6 +11,90 @@ const findFile = async () => {
|
|
|
11
11
|
})
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
const findFilesJava = async languagesFound => {
|
|
15
|
+
const result = await fg(
|
|
16
|
+
['**/pom.xml', '**/build.gradle', '**/build.gradle.kts'],
|
|
17
|
+
{
|
|
18
|
+
dot: false,
|
|
19
|
+
deep: 1,
|
|
20
|
+
onlyFiles: true
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if (result.length > 0) {
|
|
25
|
+
return languagesFound.push({ java: result })
|
|
26
|
+
}
|
|
27
|
+
return languagesFound
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const findFilesJavascript = async languagesFound => {
|
|
31
|
+
const result = await fg(
|
|
32
|
+
['**/package.json', '**/yarn.lock', '**/package.lock.json'],
|
|
33
|
+
{
|
|
34
|
+
dot: false,
|
|
35
|
+
deep: 1,
|
|
36
|
+
onlyFiles: true
|
|
37
|
+
}
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
if (result.length > 0) {
|
|
41
|
+
return languagesFound.push({ javascript: result })
|
|
42
|
+
}
|
|
43
|
+
return languagesFound
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const findFilesPython = async languagesFound => {
|
|
47
|
+
const result = await fg(['**/Pipfile.lock', '**/Pipfile'], {
|
|
48
|
+
dot: false,
|
|
49
|
+
deep: 3,
|
|
50
|
+
onlyFiles: true
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
if (result.length > 0) {
|
|
54
|
+
return languagesFound.push({ python: result })
|
|
55
|
+
}
|
|
56
|
+
return languagesFound
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const findFilesGo = async languagesFound => {
|
|
60
|
+
const result = await fg(['**/go.mod'], {
|
|
61
|
+
dot: false,
|
|
62
|
+
deep: 3,
|
|
63
|
+
onlyFiles: true
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
if (result.length > 0) {
|
|
67
|
+
return languagesFound.push({ go: result })
|
|
68
|
+
}
|
|
69
|
+
return languagesFound
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const findFilesRuby = async languagesFound => {
|
|
73
|
+
const result = await fg(['**/Gemfile', '**/Gemfile.lock'], {
|
|
74
|
+
dot: false,
|
|
75
|
+
deep: 3,
|
|
76
|
+
onlyFiles: true
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
if (result.length > 0) {
|
|
80
|
+
return languagesFound.push({ ruby: result })
|
|
81
|
+
}
|
|
82
|
+
return languagesFound
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const findFilesPhp = async languagesFound => {
|
|
86
|
+
const result = await fg(['**/composer.json', '**/composer.lock'], {
|
|
87
|
+
dot: false,
|
|
88
|
+
deep: 3,
|
|
89
|
+
onlyFiles: true
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
if (result.length > 0) {
|
|
93
|
+
return languagesFound.push({ php: result })
|
|
94
|
+
}
|
|
95
|
+
return languagesFound
|
|
96
|
+
}
|
|
97
|
+
|
|
14
98
|
const checkFilePermissions = file => {
|
|
15
99
|
let readableFile = false
|
|
16
100
|
try {
|
|
@@ -29,5 +113,11 @@ const fileExists = path => {
|
|
|
29
113
|
module.exports = {
|
|
30
114
|
findFile,
|
|
31
115
|
fileExists,
|
|
32
|
-
checkFilePermissions
|
|
116
|
+
checkFilePermissions,
|
|
117
|
+
findFilesJava,
|
|
118
|
+
findFilesJavascript,
|
|
119
|
+
findFilesPython,
|
|
120
|
+
findFilesGo,
|
|
121
|
+
findFilesPhp,
|
|
122
|
+
findFilesRuby
|
|
33
123
|
}
|