@contrast/contrast 1.0.4 → 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.
- package/.prettierignore +0 -3
- package/dist/audit/autodetection/autoDetectLanguage.js +32 -0
- package/dist/audit/catalogueApplication/catalogueApplication.js +2 -11
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +4 -2
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +6 -2
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +39 -1
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +69 -30
- package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +24 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +3 -1
- package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +13 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +2 -2
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +56 -45
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +65 -17
- package/dist/commands/audit/auditConfig.js +8 -2
- package/dist/commands/audit/auditController.js +9 -3
- package/dist/commands/audit/processAudit.js +1 -1
- package/dist/commands/scan/processScan.js +7 -4
- package/dist/commands/scan/sca/scaAnalysis.js +60 -0
- package/dist/common/HTTPClient.js +50 -16
- package/dist/common/errorHandling.js +11 -16
- package/dist/common/versionChecker.js +1 -1
- package/dist/constants/constants.js +24 -2
- package/dist/constants/locales.js +31 -36
- package/dist/constants.js +20 -0
- package/dist/lambda/analytics.js +11 -0
- package/dist/lambda/lambda.js +35 -4
- package/dist/lambda/types.js +13 -0
- package/dist/scaAnalysis/common/formatMessage.js +35 -0
- package/dist/scaAnalysis/common/treeUpload.js +29 -0
- package/dist/scaAnalysis/go/goAnalysis.js +17 -0
- package/dist/scaAnalysis/go/goParseDeps.js +158 -0
- package/dist/scaAnalysis/go/goReadDepFile.js +23 -0
- package/dist/scaAnalysis/java/analysis.js +105 -0
- package/dist/scaAnalysis/java/index.js +18 -0
- package/dist/scaAnalysis/java/javaBuildDepsParser.js +339 -0
- package/dist/scaAnalysis/python/analysis.js +41 -0
- package/dist/scaAnalysis/python/index.js +10 -0
- package/dist/scaAnalysis/ruby/analysis.js +226 -0
- package/dist/scaAnalysis/ruby/index.js +10 -0
- package/dist/scan/autoDetection.js +50 -1
- package/dist/scan/fileUtils.js +80 -1
- package/dist/scan/formatScanOutput.js +213 -0
- package/dist/scan/help.js +3 -1
- package/dist/scan/models/groupedResultsModel.js +2 -1
- package/dist/scan/models/scanResultsModel.js +3 -1
- package/dist/scan/populateProjectIdAndProjectName.js +2 -1
- package/dist/scan/scan.js +6 -99
- package/dist/scan/scanConfig.js +6 -1
- package/dist/scan/scanController.js +26 -7
- package/dist/scan/scanResults.js +20 -20
- package/dist/utils/commonApi.js +4 -1
- package/dist/utils/oraWrapper.js +5 -1
- package/package.json +12 -7
- package/src/audit/autodetection/autoDetectLanguage.ts +40 -0
- package/src/audit/catalogueApplication/catalogueApplication.js +3 -16
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +11 -8
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +17 -5
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +76 -3
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +122 -40
- package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +15 -11
- package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +29 -0
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +12 -3
- package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +16 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +3 -3
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +87 -65
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +78 -25
- package/src/commands/audit/auditConfig.ts +12 -3
- package/src/commands/audit/auditController.ts +9 -3
- package/src/commands/audit/processAudit.ts +4 -1
- package/src/commands/scan/processScan.js +10 -4
- package/src/commands/scan/sca/scaAnalysis.js +83 -0
- package/src/common/HTTPClient.js +65 -25
- package/src/common/errorHandling.ts +14 -22
- package/src/common/versionChecker.ts +1 -1
- package/src/constants/constants.js +24 -2
- package/src/constants/locales.js +33 -50
- package/src/constants.js +22 -0
- package/src/lambda/analytics.ts +9 -0
- package/src/lambda/arn.ts +2 -1
- package/src/lambda/lambda.ts +37 -17
- package/src/lambda/types.ts +35 -0
- package/src/lambda/utils.ts +2 -7
- package/src/scaAnalysis/common/formatMessage.js +38 -0
- package/src/scaAnalysis/common/treeUpload.js +30 -0
- package/src/scaAnalysis/go/goAnalysis.js +19 -0
- package/src/scaAnalysis/go/goParseDeps.js +203 -0
- package/src/scaAnalysis/go/goReadDepFile.js +32 -0
- package/src/scaAnalysis/java/analysis.js +142 -0
- package/src/scaAnalysis/java/index.js +21 -0
- package/src/scaAnalysis/java/javaBuildDepsParser.js +404 -0
- package/src/scaAnalysis/python/analysis.js +48 -0
- package/src/scaAnalysis/python/index.js +11 -0
- package/src/scaAnalysis/ruby/analysis.js +282 -0
- package/src/scaAnalysis/ruby/index.js +11 -0
- package/src/scan/autoDetection.js +58 -1
- package/src/scan/fileUtils.js +99 -1
- package/src/scan/formatScanOutput.ts +249 -0
- package/src/scan/help.js +3 -1
- package/src/scan/models/groupedResultsModel.ts +7 -5
- package/src/scan/models/resultContentModel.ts +2 -2
- package/src/scan/models/scanResultsModel.ts +5 -2
- package/src/scan/populateProjectIdAndProjectName.js +3 -1
- package/src/scan/scan.ts +8 -136
- package/src/scan/scanConfig.js +5 -1
- package/src/scan/scanController.js +30 -10
- package/src/scan/scanResults.js +31 -18
- package/src/utils/commonApi.js +4 -1
- package/src/utils/oraWrapper.js +6 -1
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
|
|
3
|
+
const readAndParseGemfile = projectPath => {
|
|
4
|
+
const fileName = filePathForWindows(projectPath + '/Gemfile')
|
|
5
|
+
const gemFile = fs.readFileSync(fileName, 'utf8')
|
|
6
|
+
const rubyArray = gemFile.split('\n')
|
|
7
|
+
|
|
8
|
+
let filteredRubyDep = rubyArray.filter(element => {
|
|
9
|
+
return (
|
|
10
|
+
!element.includes('#') &&
|
|
11
|
+
element.includes('gem') &&
|
|
12
|
+
!element.includes('source')
|
|
13
|
+
)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
for (let i = 0; i < filteredRubyDep.length; i++) {
|
|
17
|
+
filteredRubyDep[i] = filteredRubyDep[i].trim()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return filteredRubyDep
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const readAndParseGemLockFile = projectPath => {
|
|
24
|
+
const fileName = filePathForWindows(projectPath + '/Gemfile.lock')
|
|
25
|
+
const lockFile = fs.readFileSync(fileName, 'utf8')
|
|
26
|
+
const dependencyRegEx = /^\s*([A-Za-z0-9.!@#$%\-^&*_+]*)\s*(\((.*?)\))/
|
|
27
|
+
|
|
28
|
+
const lines = lockFile.split('\n')
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
dependencies: getDirectDependencies(lines, dependencyRegEx),
|
|
32
|
+
runtimeDetails: getLockFileRuntimeInfo(lines),
|
|
33
|
+
sources: getSourceArray(lines, dependencyRegEx)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const nonDependencyKeys = (line, sourceObject) => {
|
|
38
|
+
const GEMFILE_KEY_VALUE = /^\s*([^:(]*)\s*\s*(.*)/
|
|
39
|
+
let parts = GEMFILE_KEY_VALUE.exec(line)
|
|
40
|
+
let key = parts[1].trim()
|
|
41
|
+
let value = parts[2] || ''
|
|
42
|
+
|
|
43
|
+
sourceObject[key] = value
|
|
44
|
+
return sourceObject
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const populateResolveAndPlatform = (version, sourceObject) => {
|
|
48
|
+
const depArr = version.split('-')
|
|
49
|
+
sourceObject.resolved = depArr[0]
|
|
50
|
+
sourceObject.platform = depArr.length > 1 ? depArr[1] : 'UNSPECIFIED'
|
|
51
|
+
return sourceObject
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const isUpperCase = str => {
|
|
55
|
+
return str === str.toUpperCase()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const getDirectDependencies = (lines, dependencyRegEx) => {
|
|
59
|
+
const dependencies = {}
|
|
60
|
+
|
|
61
|
+
let depIndex = 0
|
|
62
|
+
for (let i = 0; i < lines.length; i++) {
|
|
63
|
+
if (lines[i] === 'DEPENDENCIES') {
|
|
64
|
+
depIndex = i
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const getDepArray = lines.slice(depIndex)
|
|
68
|
+
|
|
69
|
+
for (let j = 1; j < getDepArray.length; j++) {
|
|
70
|
+
const element = getDepArray[j]
|
|
71
|
+
if (!isUpperCase(element)) {
|
|
72
|
+
const isDependencyWithVersion = dependencyRegEx.test(element)
|
|
73
|
+
if (isDependencyWithVersion) {
|
|
74
|
+
const dependency = dependencyRegEx.exec(element)
|
|
75
|
+
let name = dependency[1]
|
|
76
|
+
name = name.replace('!', '')
|
|
77
|
+
dependencies[name.trim()] = dependency[3]
|
|
78
|
+
} else {
|
|
79
|
+
let name = element
|
|
80
|
+
name = name.replace('!', ' ')
|
|
81
|
+
dependencies[name.trim()] = 'UNSPECIFIED'
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return dependencies
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const getLockFileRuntimeInfo = lines => {
|
|
90
|
+
let rubVersionIndex = 0
|
|
91
|
+
for (let i = 0; i < lines.length; i++) {
|
|
92
|
+
if (lines[i] === 'RUBY VERSION') {
|
|
93
|
+
rubVersionIndex = i
|
|
94
|
+
break
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const runtimeDetails = {}
|
|
99
|
+
if (rubVersionIndex !== 0) {
|
|
100
|
+
const getRubyVersionArray = lines.slice(rubVersionIndex)
|
|
101
|
+
|
|
102
|
+
for (let element of getRubyVersionArray) {
|
|
103
|
+
if (!isUpperCase(element)) {
|
|
104
|
+
runtimeDetails['version'] = getVersion(element)
|
|
105
|
+
runtimeDetails['patchLevel'] = getPatchLevel(element)
|
|
106
|
+
|
|
107
|
+
if (element.includes('engine')) {
|
|
108
|
+
let splitElement = element.split(' ')
|
|
109
|
+
runtimeDetails[splitElement[0]] = splitElement[1]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return runtimeDetails
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const getVersion = element => {
|
|
118
|
+
const versionRegex = /^([ruby\s0-9.*]+)/
|
|
119
|
+
if (versionRegex.test(element)) {
|
|
120
|
+
let version = versionRegex.exec(element)[0]
|
|
121
|
+
|
|
122
|
+
if (version.includes('ruby')) {
|
|
123
|
+
return trimWhiteSpace(version.replace('ruby', ''))
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const getPatchLevel = element => {
|
|
129
|
+
const patchLevelRegex = /(p\d+)/
|
|
130
|
+
if (patchLevelRegex.test(element)) {
|
|
131
|
+
return patchLevelRegex.exec(element)[0]
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const formatSourceArr = sourceArr => {
|
|
136
|
+
return sourceArr.map(element => {
|
|
137
|
+
if (element.sourceType === 'GIT') {
|
|
138
|
+
delete element.specs
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (element.sourceType === 'GEM') {
|
|
142
|
+
delete element.branch
|
|
143
|
+
delete element.revision
|
|
144
|
+
delete element.depthLevel
|
|
145
|
+
delete element.specs
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (element.sourceType === 'PATH') {
|
|
149
|
+
delete element.branch
|
|
150
|
+
delete element.revision
|
|
151
|
+
delete element.depthLevel
|
|
152
|
+
delete element.specs
|
|
153
|
+
delete element.platform
|
|
154
|
+
}
|
|
155
|
+
return element
|
|
156
|
+
})
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const getSourceArray = (lines, dependencyRegEx) => {
|
|
160
|
+
const sourceObject = {
|
|
161
|
+
dependencies: {}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const whitespaceRegx = /^(\s*)/
|
|
165
|
+
let index = 0
|
|
166
|
+
|
|
167
|
+
let line = 0
|
|
168
|
+
const sources = []
|
|
169
|
+
while ((line = lines[index++]) !== undefined) {
|
|
170
|
+
let currentWS = whitespaceRegx.exec(line)[1].length
|
|
171
|
+
if (!line.includes(' bundler (')) {
|
|
172
|
+
if (currentWS === 0 && !line.includes(':') && line !== '') {
|
|
173
|
+
sourceObject.sourceType = line
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (currentWS !== 0 && line.includes(':')) {
|
|
177
|
+
nonDependencyKeys(line, sourceObject)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (currentWS > 2) {
|
|
181
|
+
let nexlineWS = whitespaceRegx.exec(lines[index])[1].length
|
|
182
|
+
sourceObject.dependencies = buildSourceDependencyWithVersion(
|
|
183
|
+
whitespaceRegx,
|
|
184
|
+
dependencyRegEx,
|
|
185
|
+
line,
|
|
186
|
+
currentWS,
|
|
187
|
+
sourceObject.name,
|
|
188
|
+
sourceObject.dependencies
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
if (currentWS === 4 && sourceObject.depthLevel === undefined) {
|
|
192
|
+
const dependency = dependencyRegEx.exec(line)
|
|
193
|
+
sourceObject.name = dependency[1]
|
|
194
|
+
sourceObject.depthLevel = currentWS
|
|
195
|
+
populateResolveAndPlatform(dependency[3], sourceObject)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (currentWS === 4 && sourceObject.depthLevel) {
|
|
199
|
+
// create new Parent
|
|
200
|
+
const dependency = dependencyRegEx.exec(line)
|
|
201
|
+
sourceObject.name = dependency[1]
|
|
202
|
+
sourceObject.depthLevel = currentWS
|
|
203
|
+
populateResolveAndPlatform(dependency[3], sourceObject)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (
|
|
207
|
+
(currentWS === 4 && nexlineWS === 4) ||
|
|
208
|
+
(currentWS === 6 && nexlineWS === 4) ||
|
|
209
|
+
nexlineWS === ''
|
|
210
|
+
) {
|
|
211
|
+
let newObj = {}
|
|
212
|
+
newObj = JSON.parse(JSON.stringify(sourceObject))
|
|
213
|
+
sources.push(newObj)
|
|
214
|
+
sourceObject.dependencies = {}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return formatSourceArr(sources)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const buildSourceDependencyWithVersion = (
|
|
223
|
+
whitespaceRegx,
|
|
224
|
+
dependencyRegEx,
|
|
225
|
+
line,
|
|
226
|
+
currentWhiteSpace,
|
|
227
|
+
name,
|
|
228
|
+
dependencies
|
|
229
|
+
) => {
|
|
230
|
+
const isDependencyWithVersion = dependencyRegEx.test(line)
|
|
231
|
+
|
|
232
|
+
if (currentWhiteSpace === 6) {
|
|
233
|
+
const dependency = dependencyRegEx.exec(line)
|
|
234
|
+
if (isDependencyWithVersion) {
|
|
235
|
+
if (name !== dependency[1]) {
|
|
236
|
+
dependencies[dependency[1]] = dependency[3]
|
|
237
|
+
}
|
|
238
|
+
} else {
|
|
239
|
+
dependencies[line.trim()] = 'UNSPECIFIED'
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return dependencies
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const getRubyDeps = config => {
|
|
247
|
+
try {
|
|
248
|
+
const parsedGem = readAndParseGemfile(config.projectPath)
|
|
249
|
+
const parsedLock = readAndParseGemLockFile(config.projectPath)
|
|
250
|
+
|
|
251
|
+
return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock }
|
|
252
|
+
} catch (err) {
|
|
253
|
+
console.log(err.message)
|
|
254
|
+
process.exit(1)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const trimWhiteSpace = string => {
|
|
259
|
+
return string.replace(/\s+/g, '')
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const filePathForWindows = path => {
|
|
263
|
+
if (process.platform === 'win32') {
|
|
264
|
+
path = path.replace(/\//g, '\\')
|
|
265
|
+
}
|
|
266
|
+
return path
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
module.exports = {
|
|
270
|
+
getRubyDeps,
|
|
271
|
+
readAndParseGemfile,
|
|
272
|
+
readAndParseGemLockFile,
|
|
273
|
+
nonDependencyKeys,
|
|
274
|
+
populateResolveAndPlatform,
|
|
275
|
+
isUpperCase,
|
|
276
|
+
getDirectDependencies,
|
|
277
|
+
getLockFileRuntimeInfo,
|
|
278
|
+
getVersion,
|
|
279
|
+
getPatchLevel,
|
|
280
|
+
formatSourceArr,
|
|
281
|
+
getSourceArray
|
|
282
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const { getRubyDeps } = require('./analysis')
|
|
2
|
+
const { createRubyTSMessage } = require('../common/formatMessage')
|
|
3
|
+
|
|
4
|
+
const rubyAnalysis = (config, languageFiles) => {
|
|
5
|
+
const rubyDeps = getRubyDeps(config, languageFiles.RUBY)
|
|
6
|
+
return createRubyTSMessage(rubyDeps)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
rubyAnalysis
|
|
11
|
+
}
|
|
@@ -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()
|
|
@@ -12,6 +14,11 @@ const autoDetectFileAndLanguage = async configToUse => {
|
|
|
12
14
|
process.exit(1)
|
|
13
15
|
}
|
|
14
16
|
|
|
17
|
+
if (fileFinder.fileIsEmpty(entries[0])) {
|
|
18
|
+
console.log(i18n.__('scanFileIsEmpty'))
|
|
19
|
+
process.exit(1)
|
|
20
|
+
}
|
|
21
|
+
|
|
15
22
|
configToUse.file = entries[0]
|
|
16
23
|
if (configToUse.name === undefined) {
|
|
17
24
|
configToUse.name = entries[0]
|
|
@@ -21,6 +28,38 @@ const autoDetectFileAndLanguage = async configToUse => {
|
|
|
21
28
|
}
|
|
22
29
|
}
|
|
23
30
|
|
|
31
|
+
const autoDetectAuditFilesAndLanguages = async () => {
|
|
32
|
+
let languagesFound = []
|
|
33
|
+
console.log(i18n.__('searchingAuditFileDirectory', process.cwd()))
|
|
34
|
+
|
|
35
|
+
await fileFinder.findFilesJava(languagesFound)
|
|
36
|
+
await fileFinder.findFilesJavascript(languagesFound)
|
|
37
|
+
await fileFinder.findFilesPython(languagesFound)
|
|
38
|
+
await fileFinder.findFilesGo(languagesFound)
|
|
39
|
+
await fileFinder.findFilesPhp(languagesFound)
|
|
40
|
+
await fileFinder.findFilesRuby(languagesFound)
|
|
41
|
+
|
|
42
|
+
if (languagesFound.length === 1) {
|
|
43
|
+
return languagesFound
|
|
44
|
+
} else {
|
|
45
|
+
console.log(
|
|
46
|
+
'found multiple languages, please specify one using --file to run SCA analysis'
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const manualDetectAuditFilesAndLanguages = projectPath => {
|
|
52
|
+
let projectRootFilenames = rootFile.getProjectRootFilenames(projectPath)
|
|
53
|
+
let identifiedLanguages =
|
|
54
|
+
languageResolver.deduceLanguageScaAnalysis(projectRootFilenames)
|
|
55
|
+
|
|
56
|
+
if (Object.keys(identifiedLanguages).length === 0) {
|
|
57
|
+
console.log(i18n.__('languageAnalysisNoLanguage', projectPath))
|
|
58
|
+
return []
|
|
59
|
+
}
|
|
60
|
+
return [identifiedLanguages]
|
|
61
|
+
}
|
|
62
|
+
|
|
24
63
|
const hasWhiteSpace = s => {
|
|
25
64
|
const filename = s.split('/').pop()
|
|
26
65
|
return filename.indexOf(' ') >= 0
|
|
@@ -42,7 +81,25 @@ const errorOnFileDetection = entries => {
|
|
|
42
81
|
process.exit(1)
|
|
43
82
|
}
|
|
44
83
|
|
|
84
|
+
const errorOnAuditFileDetection = entries => {
|
|
85
|
+
if (entries.length > 1) {
|
|
86
|
+
console.log(i18n.__('searchingDirectoryScan'))
|
|
87
|
+
for (let file in entries) {
|
|
88
|
+
console.log('-', entries[file])
|
|
89
|
+
}
|
|
90
|
+
console.log('')
|
|
91
|
+
console.log(i18n.__('specifyFileAuditNotFound'))
|
|
92
|
+
} else {
|
|
93
|
+
console.log(i18n.__('noFileFoundScan'))
|
|
94
|
+
console.log('')
|
|
95
|
+
console.log(i18n.__('specifyFileAuditNotFound'))
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
45
99
|
module.exports = {
|
|
46
100
|
autoDetectFileAndLanguage,
|
|
47
|
-
errorOnFileDetection
|
|
101
|
+
errorOnFileDetection,
|
|
102
|
+
autoDetectAuditFilesAndLanguages,
|
|
103
|
+
errorOnAuditFileDetection,
|
|
104
|
+
manualDetectAuditFilesAndLanguages
|
|
48
105
|
}
|
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 {
|
|
@@ -26,8 +110,22 @@ const fileExists = path => {
|
|
|
26
110
|
return fs.existsSync(path)
|
|
27
111
|
}
|
|
28
112
|
|
|
113
|
+
const fileIsEmpty = path => {
|
|
114
|
+
if (fileExists(path) && checkFilePermissions(path)) {
|
|
115
|
+
return fs.readFileSync(path).length === 0
|
|
116
|
+
}
|
|
117
|
+
return false
|
|
118
|
+
}
|
|
119
|
+
|
|
29
120
|
module.exports = {
|
|
30
121
|
findFile,
|
|
31
122
|
fileExists,
|
|
32
|
-
checkFilePermissions
|
|
123
|
+
checkFilePermissions,
|
|
124
|
+
findFilesJava,
|
|
125
|
+
findFilesJavascript,
|
|
126
|
+
findFilesPython,
|
|
127
|
+
findFilesGo,
|
|
128
|
+
findFilesPhp,
|
|
129
|
+
findFilesRuby,
|
|
130
|
+
fileIsEmpty
|
|
33
131
|
}
|