@contrast/contrast 1.0.8 → 1.0.9
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/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +3 -12
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +88 -53
- package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +4 -3
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +58 -11
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +38 -5
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +6 -30
- package/dist/audit/save.js +21 -13
- package/dist/commands/audit/auditConfig.js +0 -16
- package/dist/commands/audit/auditController.js +1 -10
- package/dist/commands/audit/help.js +7 -24
- package/dist/commands/audit/processAudit.js +1 -7
- package/dist/commands/audit/saveFile.js +2 -2
- package/dist/commands/scan/sca/scaAnalysis.js +22 -9
- package/dist/common/HTTPClient.js +8 -8
- package/dist/constants/constants.js +7 -2
- package/dist/constants/locales.js +24 -30
- package/dist/constants.js +11 -9
- package/dist/index.js +54 -45
- package/dist/lambda/lambda.js +5 -2
- package/dist/sbom/generateSbom.js +2 -2
- package/dist/scaAnalysis/common/formatMessage.js +7 -1
- package/dist/scaAnalysis/common/treeUpload.js +4 -5
- package/dist/scaAnalysis/dotnet/analysis.js +43 -0
- package/dist/scaAnalysis/dotnet/index.js +10 -0
- package/dist/scaAnalysis/javascript/analysis.js +4 -7
- package/dist/scaAnalysis/javascript/index.js +14 -5
- package/dist/scaAnalysis/php/analysis.js +14 -33
- package/dist/scaAnalysis/php/index.js +11 -4
- package/dist/scaAnalysis/ruby/analysis.js +2 -10
- package/dist/scan/autoDetection.js +18 -21
- package/dist/scan/fileUtils.js +31 -12
- package/dist/scan/formatScanOutput.js +3 -3
- package/dist/scan/scanConfig.js +2 -2
- package/dist/utils/getConfig.js +1 -6
- package/package.json +2 -3
- package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +3 -32
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +128 -68
- package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +11 -5
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +41 -19
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +43 -4
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +6 -32
- package/src/audit/save.js +32 -16
- package/src/commands/audit/auditConfig.ts +0 -25
- package/src/commands/audit/auditController.ts +0 -11
- package/src/commands/audit/help.ts +7 -24
- package/src/commands/audit/processAudit.ts +1 -7
- package/src/commands/audit/saveFile.ts +2 -2
- package/src/commands/scan/processScan.js +0 -1
- package/src/commands/scan/sca/scaAnalysis.js +28 -13
- package/src/common/HTTPClient.js +9 -9
- package/src/constants/constants.js +9 -3
- package/src/constants/locales.js +47 -35
- package/src/constants.js +12 -10
- package/src/index.ts +76 -66
- package/src/lambda/lambda.ts +5 -2
- package/src/lambda/types.ts +1 -0
- package/src/sbom/generateSbom.ts +2 -2
- package/src/scaAnalysis/common/formatMessage.js +8 -1
- package/src/scaAnalysis/common/treeUpload.js +4 -5
- package/src/scaAnalysis/dotnet/analysis.js +54 -0
- package/src/scaAnalysis/dotnet/index.js +11 -0
- package/src/scaAnalysis/javascript/analysis.js +6 -7
- package/src/scaAnalysis/javascript/index.js +23 -7
- package/src/scaAnalysis/php/analysis.js +15 -35
- package/src/scaAnalysis/php/index.js +15 -4
- package/src/scaAnalysis/ruby/analysis.js +2 -11
- package/src/scan/autoDetection.js +18 -24
- package/src/scan/fileUtils.js +33 -12
- package/src/scan/formatScanOutput.ts +3 -3
- package/src/scan/scanConfig.js +2 -4
- package/src/utils/getConfig.ts +1 -12
- package/dist/audit/AnalysisEngine.js +0 -37
- package/dist/audit/autodetection/autoDetectLanguage.js +0 -32
- package/dist/audit/dotnetAnalysisEngine/index.js +0 -25
- package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -35
- package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -15
- package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -18
- package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -14
- package/dist/audit/dotnetAnalysisEngine/sanitizer.js +0 -9
- package/dist/audit/goAnalysisEngine/index.js +0 -17
- package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +0 -164
- package/dist/audit/goAnalysisEngine/readProjectFileContents.js +0 -21
- package/dist/audit/goAnalysisEngine/sanitizer.js +0 -5
- package/dist/audit/javaAnalysisEngine/index.js +0 -34
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -155
- package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -353
- package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +0 -98
- package/dist/audit/javaAnalysisEngine/sanitizer.js +0 -5
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -25
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -25
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -35
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -24
- package/dist/audit/languageAnalysisEngine/constants.js +0 -20
- package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -25
- package/dist/audit/languageAnalysisEngine/index.js +0 -39
- package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -66
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -166
- package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -40
- package/dist/audit/nodeAnalysisEngine/index.js +0 -31
- package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -18
- package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -18
- package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -17
- package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -14
- package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -24
- package/dist/audit/nodeAnalysisEngine/sanitizer.js +0 -9
- package/dist/audit/phpAnalysisEngine/index.js +0 -23
- package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +0 -52
- package/dist/audit/phpAnalysisEngine/readLockFileContents.js +0 -13
- package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +0 -16
- package/dist/audit/phpAnalysisEngine/sanitizer.js +0 -5
- package/dist/audit/pythonAnalysisEngine/index.js +0 -25
- package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -17
- package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -21
- package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -13
- package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -14
- package/dist/audit/pythonAnalysisEngine/sanitizer.js +0 -7
- package/dist/audit/rubyAnalysisEngine/index.js +0 -25
- package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -176
- package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +0 -22
- package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +0 -14
- package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -14
- package/dist/audit/rubyAnalysisEngine/sanitizer.js +0 -6
- package/src/audit/AnalysisEngine.js +0 -103
- package/src/audit/autodetection/autoDetectLanguage.ts +0 -40
- package/src/audit/dotnetAnalysisEngine/index.js +0 -26
- package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -47
- package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -29
- package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -30
- package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -26
- package/src/audit/dotnetAnalysisEngine/sanitizer.js +0 -11
- package/src/audit/goAnalysisEngine/index.js +0 -18
- package/src/audit/goAnalysisEngine/parseProjectFileContents.js +0 -209
- package/src/audit/goAnalysisEngine/readProjectFileContents.js +0 -31
- package/src/audit/goAnalysisEngine/sanitizer.js +0 -7
- package/src/audit/javaAnalysisEngine/index.js +0 -41
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -225
- package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -420
- package/src/audit/javaAnalysisEngine/readProjectFileContents.js +0 -141
- package/src/audit/javaAnalysisEngine/sanitizer.js +0 -6
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -36
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -42
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -54
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -33
- package/src/audit/languageAnalysisEngine/constants.js +0 -23
- package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -41
- package/src/audit/languageAnalysisEngine/index.js +0 -45
- package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -96
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -251
- package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -49
- package/src/audit/nodeAnalysisEngine/index.js +0 -35
- package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -20
- package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -26
- package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -23
- package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -27
- package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -36
- package/src/audit/nodeAnalysisEngine/sanitizer.js +0 -11
- package/src/audit/phpAnalysisEngine/index.js +0 -27
- package/src/audit/phpAnalysisEngine/parseLockFileContents.js +0 -60
- package/src/audit/phpAnalysisEngine/readLockFileContents.js +0 -14
- package/src/audit/phpAnalysisEngine/readProjectFileContents.js +0 -25
- package/src/audit/phpAnalysisEngine/sanitizer.js +0 -4
- package/src/audit/pythonAnalysisEngine/index.js +0 -55
- package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -23
- package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -33
- package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -16
- package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -22
- package/src/audit/pythonAnalysisEngine/sanitizer.js +0 -9
- package/src/audit/rubyAnalysisEngine/index.js +0 -30
- package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -215
- package/src/audit/rubyAnalysisEngine/parsedGemfile.js +0 -39
- package/src/audit/rubyAnalysisEngine/readGemfileContents.js +0 -18
- package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -17
- package/src/audit/rubyAnalysisEngine/sanitizer.js +0 -8
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const yaml = require('js-yaml')
|
|
3
|
-
const i18n = require('i18n')
|
|
4
|
-
|
|
5
|
-
module.exports = exports = ({ language: { lockFilePath }, node }, next) => {
|
|
6
|
-
// check if the lockFilePath is populated and if it is check to
|
|
7
|
-
// see if it has the package-lock if not then go on to next handler
|
|
8
|
-
if (!lockFilePath || !lockFilePath.includes('yarn.lock')) {
|
|
9
|
-
next()
|
|
10
|
-
return
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
try {
|
|
14
|
-
node.rawYarnLockFileContents = fs.readFileSync(lockFilePath, 'utf8')
|
|
15
|
-
node.yarnVersion = 1
|
|
16
|
-
|
|
17
|
-
if (
|
|
18
|
-
!node.rawYarnLockFileContents.includes('lockfile v1') ||
|
|
19
|
-
node.rawYarnLockFileContents.includes('__metadata')
|
|
20
|
-
) {
|
|
21
|
-
node.rawYarnLockFileContents = yaml.load(
|
|
22
|
-
fs.readFileSync(lockFilePath, 'utf8')
|
|
23
|
-
)
|
|
24
|
-
node.yarnVersion = 2
|
|
25
|
-
}
|
|
26
|
-
} catch (err) {
|
|
27
|
-
next(
|
|
28
|
-
new Error(
|
|
29
|
-
i18n.__('nodeReadYarnLockFileError', lockFilePath) + `${err.message}`
|
|
30
|
-
)
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
return
|
|
34
|
-
}
|
|
35
|
-
next()
|
|
36
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
module.exports = exports = ({ node }, next) => {
|
|
2
|
-
// Remove anything sensitive or unnecessary from being sent to the backend as
|
|
3
|
-
// a result of our NODE project analysis
|
|
4
|
-
delete node.rawProjectFileContents
|
|
5
|
-
delete node.projectFileJSON
|
|
6
|
-
delete node.projectLockFileJSON
|
|
7
|
-
delete node.rawLockFileContents
|
|
8
|
-
delete node.rawYarnLockFileContents
|
|
9
|
-
|
|
10
|
-
next()
|
|
11
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const AnalysisEngine = require('../AnalysisEngine')
|
|
2
|
-
|
|
3
|
-
const readProjectFileContents = require('./readProjectFileContents')
|
|
4
|
-
const readLockFileContents = require('./readLockFileContents')
|
|
5
|
-
const parseLockFileContents = require('./parseLockFileContents')
|
|
6
|
-
const sanitizer = require('./sanitizer')
|
|
7
|
-
const i18n = require('i18n')
|
|
8
|
-
|
|
9
|
-
module.exports = exports = (language, config, callback) => {
|
|
10
|
-
const ae = new AnalysisEngine({ language, config, php: {} })
|
|
11
|
-
|
|
12
|
-
ae.use([
|
|
13
|
-
readProjectFileContents,
|
|
14
|
-
readLockFileContents,
|
|
15
|
-
parseLockFileContents,
|
|
16
|
-
sanitizer
|
|
17
|
-
])
|
|
18
|
-
|
|
19
|
-
ae.analyze((err, analysis) => {
|
|
20
|
-
if (err) {
|
|
21
|
-
callback(new Error(i18n.__('phpAnalysisFailure') + `${err.message}`))
|
|
22
|
-
return
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
callback(null, analysis)
|
|
26
|
-
})
|
|
27
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
const i18n = require('i18n')
|
|
2
|
-
const _ = require('lodash')
|
|
3
|
-
module.exports = exports = ({ language: { lockFilePath }, php }, next) => {
|
|
4
|
-
try {
|
|
5
|
-
php.lockFile = php.rawLockFileContents
|
|
6
|
-
let packages = _.keyBy(php.lockFile.packages, 'name')
|
|
7
|
-
let packagesDev = _.keyBy(php.lockFile['packages-dev'], 'name')
|
|
8
|
-
php.lockFile.dependencies = _.merge(packages, packagesDev)
|
|
9
|
-
|
|
10
|
-
const listOfTopDep = Object.keys(php.lockFile.dependencies)
|
|
11
|
-
|
|
12
|
-
Object.entries(php.lockFile.dependencies).forEach(([key, value]) => {
|
|
13
|
-
if (value.require) {
|
|
14
|
-
const listOfRequiresDep = Object.keys(value.require)
|
|
15
|
-
listOfRequiresDep.forEach(dep => {
|
|
16
|
-
if (!listOfTopDep.includes(dep)) {
|
|
17
|
-
addChildDepToLockFileAsOwnObj(value['require'], dep)
|
|
18
|
-
}
|
|
19
|
-
})
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (value['require-dev']) {
|
|
23
|
-
const listOfRequiresDep = Object.keys(value['require-dev'])
|
|
24
|
-
listOfRequiresDep.forEach(dep => {
|
|
25
|
-
if (!listOfTopDep.includes(dep)) {
|
|
26
|
-
addChildDepToLockFileAsOwnObj(value['require-dev'], dep)
|
|
27
|
-
}
|
|
28
|
-
})
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
formatParentDepToLockFile()
|
|
33
|
-
} catch (err) {
|
|
34
|
-
next(
|
|
35
|
-
new Error(
|
|
36
|
-
i18n.__('phpParseComposerLock', lockFilePath) + `${err.message}`
|
|
37
|
-
)
|
|
38
|
-
)
|
|
39
|
-
return
|
|
40
|
-
}
|
|
41
|
-
next()
|
|
42
|
-
|
|
43
|
-
function addChildDepToLockFileAsOwnObj(depObj, key) {
|
|
44
|
-
php.lockFile.dependencies[key] = { version: depObj[key] }
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function formatParentDepToLockFile() {
|
|
48
|
-
for (const [key, value] of Object.entries(php.lockFile.dependencies)) {
|
|
49
|
-
let requires = {}
|
|
50
|
-
for (const [childKey, childValue] of Object.entries(value)) {
|
|
51
|
-
if (childKey === 'require' || childKey === 'require-dev') {
|
|
52
|
-
requires = _.merge(requires, childValue)
|
|
53
|
-
php.lockFile.dependencies[key].requires = requires
|
|
54
|
-
delete php.lockFile.dependencies[key].require
|
|
55
|
-
delete php.lockFile.dependencies[key]['require-dev']
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const i18n = require('i18n')
|
|
3
|
-
|
|
4
|
-
module.exports = exports = ({ language: { lockFilePath }, php }, next) => {
|
|
5
|
-
try {
|
|
6
|
-
php.rawLockFileContents = JSON.parse(fs.readFileSync(lockFilePath))
|
|
7
|
-
} catch (err) {
|
|
8
|
-
next(new Error(i18n.__('phpReadError', lockFilePath) + `${err.message}`))
|
|
9
|
-
|
|
10
|
-
return
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
next()
|
|
14
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const i18n = require('i18n')
|
|
3
|
-
// all node references are because we're using that engine in the backend
|
|
4
|
-
// so complying with the already existing node format
|
|
5
|
-
module.exports = exports = (analysis, next) => {
|
|
6
|
-
const {
|
|
7
|
-
language: { projectFilePath },
|
|
8
|
-
php
|
|
9
|
-
} = analysis
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
php.composerJSON = JSON.parse(fs.readFileSync(projectFilePath, 'utf8'))
|
|
13
|
-
php.composerJSON.dependencies = php.composerJSON.require
|
|
14
|
-
php.composerJSON.devDependencies = php.composerJSON['require-dev']
|
|
15
|
-
} catch (err) {
|
|
16
|
-
next(
|
|
17
|
-
new Error(
|
|
18
|
-
i18n.__('phpReadProjectFileError', projectFilePath) + `${err.message}`
|
|
19
|
-
)
|
|
20
|
-
)
|
|
21
|
-
return
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
next()
|
|
25
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
const AnalysisEngine = require('./../AnalysisEngine')
|
|
2
|
-
|
|
3
|
-
const readPythonProjectFileContents = require('./readPythonProjectFileContents')
|
|
4
|
-
const readPipfileLockFileContents = require('./readPipfileLockFileContents')
|
|
5
|
-
const parseProjectFileContents = require('./parseProjectFileContents')
|
|
6
|
-
const parsePipfileLockContents = require('./parsePipfileLockContents')
|
|
7
|
-
const sanitizer = require('./sanitizer')
|
|
8
|
-
const i18n = require('i18n')
|
|
9
|
-
|
|
10
|
-
module.exports = exports = (language, config, callback) => {
|
|
11
|
-
const ae = new AnalysisEngine({ language, config, python: {} })
|
|
12
|
-
|
|
13
|
-
// python's dependancy management is a bit of a wild west.
|
|
14
|
-
|
|
15
|
-
// in general there is a requirements.txt but there can also be a test-requirements.txt
|
|
16
|
-
// and/or dev-requirements.txt. plus the versions in all of those files do not need
|
|
17
|
-
// to be specified meaning that when the file is run it can have different dependancies
|
|
18
|
-
// per environment. If the user runs pip freeze it updates the requirements to the exact
|
|
19
|
-
// versions running in their local solo environment. We might need to do this or get the
|
|
20
|
-
// customer to do this for more accurate results.
|
|
21
|
-
|
|
22
|
-
// pip has a ultility module that can be run pipdeptree that will give a dependancy tree
|
|
23
|
-
// but this is a package that needs to be installed.
|
|
24
|
-
|
|
25
|
-
// there is also pipenv that produces pipfile and pipfile.lock that helps managed dependancies
|
|
26
|
-
// to be the same across all the environements. if pipfile.lock is found as well as a requirements.txt
|
|
27
|
-
// then pipfile.lock superceeds the requirements.
|
|
28
|
-
|
|
29
|
-
// pipenv graph can create a dependancy tree but to run that we have to
|
|
30
|
-
// 1) know if pipenv is used to manage python env
|
|
31
|
-
// 2) what the name of their pipenv is called
|
|
32
|
-
// 3) run the command
|
|
33
|
-
// 4)scrape and parse the console output
|
|
34
|
-
|
|
35
|
-
// For a breakdown of more python packaging https://realpython.com/pipenv-guide/ is a good guide
|
|
36
|
-
// and https://medium.com/python-pandemonium/better-python-dependency-and-package-management-b5d8ea29dff1
|
|
37
|
-
|
|
38
|
-
ae.use([
|
|
39
|
-
readPythonProjectFileContents,
|
|
40
|
-
parseProjectFileContents,
|
|
41
|
-
readPipfileLockFileContents,
|
|
42
|
-
parsePipfileLockContents,
|
|
43
|
-
sanitizer
|
|
44
|
-
])
|
|
45
|
-
|
|
46
|
-
ae.analyze((err, analysis) => {
|
|
47
|
-
if (err) {
|
|
48
|
-
callback(
|
|
49
|
-
new Error(i18n.__('pythonAnalysisEngineError') + `${err.message}`)
|
|
50
|
-
)
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
callback(null, analysis)
|
|
54
|
-
})
|
|
55
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
const i18n = require('i18n')
|
|
2
|
-
|
|
3
|
-
module.exports = exports = ({ language: { lockFilePath }, python }, next) => {
|
|
4
|
-
if (python.rawLockFileContents === undefined) {
|
|
5
|
-
return next()
|
|
6
|
-
}
|
|
7
|
-
try {
|
|
8
|
-
let parsedPipLock = JSON.parse(python.rawLockFileContents)
|
|
9
|
-
parsedPipLock['defaults'] = parsedPipLock['default']
|
|
10
|
-
python.pipfileLock = parsedPipLock
|
|
11
|
-
} catch (err) {
|
|
12
|
-
next(
|
|
13
|
-
new Error(
|
|
14
|
-
i18n.__(
|
|
15
|
-
'pythonAnalysisEnginePipError',
|
|
16
|
-
lockFilePath ? lockFilePath : 'undefined'
|
|
17
|
-
) + `${err.message}`
|
|
18
|
-
)
|
|
19
|
-
)
|
|
20
|
-
return
|
|
21
|
-
}
|
|
22
|
-
next()
|
|
23
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
const multiReplace = require('string-multiple-replace')
|
|
2
|
-
const i18n = require('i18n')
|
|
3
|
-
|
|
4
|
-
module.exports = exports = ({ python }, next) => {
|
|
5
|
-
const { rawProjectFileContents } = python
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
const matcherObj = { '"': '' }
|
|
9
|
-
const sequencer = ['"']
|
|
10
|
-
const parsedPipfile = multiReplace(
|
|
11
|
-
rawProjectFileContents,
|
|
12
|
-
matcherObj,
|
|
13
|
-
sequencer
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
const pythonArray = parsedPipfile.split('\n')
|
|
17
|
-
|
|
18
|
-
python.pipfilDependanceies = pythonArray.filter(element => {
|
|
19
|
-
return element != '' && !element.includes('#')
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
next()
|
|
23
|
-
} catch (err) {
|
|
24
|
-
next(
|
|
25
|
-
new Error(
|
|
26
|
-
i18n.__('pythonAnalysisParseProjectFileError', rawProjectFileContents) +
|
|
27
|
-
`${err.message}`
|
|
28
|
-
)
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const i18n = require('i18n')
|
|
3
|
-
|
|
4
|
-
module.exports = exports = ({ language: { lockFilePath }, python }, next) => {
|
|
5
|
-
try {
|
|
6
|
-
python.rawLockFileContents = fs.readFileSync(lockFilePath)
|
|
7
|
-
} catch (err) {
|
|
8
|
-
next(
|
|
9
|
-
new Error(
|
|
10
|
-
i18n.__('pythonAnalysisReadPipFileError', lockFilePath) +
|
|
11
|
-
`${err.message}`
|
|
12
|
-
)
|
|
13
|
-
)
|
|
14
|
-
}
|
|
15
|
-
next()
|
|
16
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const i18n = require('i18n')
|
|
3
|
-
|
|
4
|
-
module.exports = exports = (
|
|
5
|
-
{ language: { projectFilePath }, python },
|
|
6
|
-
next
|
|
7
|
-
) => {
|
|
8
|
-
try {
|
|
9
|
-
//project file Contents points to requirements.txt for python
|
|
10
|
-
python.rawProjectFileContents = fs.readFileSync(projectFilePath, 'utf8')
|
|
11
|
-
|
|
12
|
-
next()
|
|
13
|
-
} catch (err) {
|
|
14
|
-
next(
|
|
15
|
-
new Error(
|
|
16
|
-
i18n.__('pythonAnalysisReadPythonProjectFileError', projectFilePath) +
|
|
17
|
-
`${err.message}`
|
|
18
|
-
)
|
|
19
|
-
)
|
|
20
|
-
return
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
module.exports = exports = ({ python }, next) => {
|
|
2
|
-
// Remove anything sensitive or unnecessary from being sent to the backend as
|
|
3
|
-
// a result of our Python project analysis
|
|
4
|
-
delete python.rawProjectFileContents
|
|
5
|
-
delete python.rawLockFileContents
|
|
6
|
-
delete python.pipfileLock.default
|
|
7
|
-
|
|
8
|
-
next()
|
|
9
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
const AnalysisEngine = require('./../AnalysisEngine')
|
|
2
|
-
|
|
3
|
-
const readGemfileContents = require('./readGemfileContents')
|
|
4
|
-
const readGemfileLockContents = require('./readGemfileLockContents')
|
|
5
|
-
const parsedGemfile = require('./parsedGemfile')
|
|
6
|
-
const parseGemfileLockFileContents = require('./parseGemfileLockContents')
|
|
7
|
-
const sanitizer = require('./sanitizer')
|
|
8
|
-
const i18n = require('i18n')
|
|
9
|
-
|
|
10
|
-
module.exports = exports = (language, config, callback) => {
|
|
11
|
-
const ae = new AnalysisEngine({ language, config, ruby: {} })
|
|
12
|
-
|
|
13
|
-
// Ruby dependency management is mostly handled by bundler which creates
|
|
14
|
-
// Gemfile and Gemfile.lock. This project will only pick up on those
|
|
15
|
-
ae.use([
|
|
16
|
-
readGemfileContents,
|
|
17
|
-
parsedGemfile,
|
|
18
|
-
readGemfileLockContents,
|
|
19
|
-
parseGemfileLockFileContents,
|
|
20
|
-
sanitizer
|
|
21
|
-
])
|
|
22
|
-
|
|
23
|
-
ae.analyze((err, analysis) => {
|
|
24
|
-
if (err) {
|
|
25
|
-
callback(new Error(i18n.__('rubyAnalysisEngineError') + `${err.message}`))
|
|
26
|
-
return
|
|
27
|
-
}
|
|
28
|
-
callback(null, analysis)
|
|
29
|
-
})
|
|
30
|
-
}
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
const whitespaceRegx = /^(\s*)/
|
|
2
|
-
let index = 0
|
|
3
|
-
const depReg = /^\s*([A-Za-z0-9.!@#$%\-^&*_+]*)\s*(\((.*?)\))/
|
|
4
|
-
const i18n = require('i18n')
|
|
5
|
-
|
|
6
|
-
const GEMFILE_KEY_VALUE = /^\s*([^:(]*)\s*\:*\s*(.*)/ // eslint-disable-line
|
|
7
|
-
let rubyObj = {}
|
|
8
|
-
rubyObj.dependencies = {}
|
|
9
|
-
|
|
10
|
-
module.exports = exports = ({ ruby }, next) => {
|
|
11
|
-
const { rawLockFileContents } = ruby
|
|
12
|
-
let lines = rawLockFileContents.split('\n')
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
ruby.gemfileLock = {}
|
|
16
|
-
getDirectDepencies(lines, ruby.gemfileLock)
|
|
17
|
-
getRubyVersion(lines, ruby.gemfileLock)
|
|
18
|
-
getSourceArr(lines, ruby.gemfileLock)
|
|
19
|
-
next()
|
|
20
|
-
} catch (err) {
|
|
21
|
-
next(
|
|
22
|
-
new Error(
|
|
23
|
-
i18n.__('rubyAnalysisEngineParsedGemLockFileError') + `${err.message}`
|
|
24
|
-
)
|
|
25
|
-
)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const populateSourceType = (line, rubyObj) => {
|
|
30
|
-
// sourceType has 0 WS and isn't null
|
|
31
|
-
return (rubyObj.sourceType = line)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const nonDependencyKeys = (line, rubyObj) => {
|
|
35
|
-
let parts = GEMFILE_KEY_VALUE.exec(line)
|
|
36
|
-
let key = parts[1].trim()
|
|
37
|
-
let value = parts[2] || ''
|
|
38
|
-
return (rubyObj[key] = value)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const populateResolveAndPlatform = (dependency, rubyObj) => {
|
|
42
|
-
const depArr = dependency.split('-')
|
|
43
|
-
rubyObj.resolved = depArr[0]
|
|
44
|
-
rubyObj.platform = depArr.length > 1 ? depArr[1] : 'UNSPECIFIED'
|
|
45
|
-
return rubyObj
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const isUpperCase = str => {
|
|
49
|
-
return str === str.toUpperCase()
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const getDirectDepencies = (lines, ruby) => {
|
|
53
|
-
let depIndex = 0
|
|
54
|
-
for (let i = 0; i < lines.length; i++) {
|
|
55
|
-
if (lines[i] == 'DEPENDENCIES') {
|
|
56
|
-
depIndex = i
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
const getDepArray = lines.slice(depIndex)
|
|
60
|
-
|
|
61
|
-
ruby.dependencies = {}
|
|
62
|
-
|
|
63
|
-
for (let j = 1; j < getDepArray.length; j++) {
|
|
64
|
-
const element = getDepArray[j]
|
|
65
|
-
if (!isUpperCase(element)) {
|
|
66
|
-
const isDependencyWithVersion = depReg.test(element)
|
|
67
|
-
if (isDependencyWithVersion) {
|
|
68
|
-
const dependency = depReg.exec(element)
|
|
69
|
-
// BF bain!
|
|
70
|
-
let name = dependency[1]
|
|
71
|
-
name = name.replace('!', '')
|
|
72
|
-
//
|
|
73
|
-
ruby.dependencies[name.trim()] = dependency[3]
|
|
74
|
-
} else {
|
|
75
|
-
// BF bain!
|
|
76
|
-
let name = element
|
|
77
|
-
name = name.replace('!', ' ')
|
|
78
|
-
//
|
|
79
|
-
ruby.dependencies[name.trim()] = 'UNSPECIFIED'
|
|
80
|
-
}
|
|
81
|
-
} else {
|
|
82
|
-
return
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const getRubyVersion = (lines, ruby) => {
|
|
88
|
-
let rubVersionIndex = 0
|
|
89
|
-
for (let i = 0; i < lines.length; i++) {
|
|
90
|
-
if (lines[i] == 'RUBY VERSION') {
|
|
91
|
-
rubVersionIndex = i
|
|
92
|
-
break
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (rubVersionIndex !== 0) {
|
|
96
|
-
const getRubyVersionArray = lines.slice(rubVersionIndex)
|
|
97
|
-
|
|
98
|
-
ruby.runtimeDetails = {}
|
|
99
|
-
|
|
100
|
-
for (let j = 1; j < getRubyVersionArray.length; j++) {
|
|
101
|
-
let element = getRubyVersionArray[j]
|
|
102
|
-
if (!isUpperCase(element)) {
|
|
103
|
-
element = element.trim()
|
|
104
|
-
if (/^([ruby\s0-9.*]+)/.test(element)) {
|
|
105
|
-
let splitElement = element.split(' ')
|
|
106
|
-
ruby.runtimeDetails['version'] = splitElement[1]
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (/^([p0-9]+)/.test(element)) {
|
|
110
|
-
ruby.runtimeDetails['patchLevel'] = element.substring(1)
|
|
111
|
-
}
|
|
112
|
-
if (element.includes('engine')) {
|
|
113
|
-
let splitElement = element.split(' ')
|
|
114
|
-
ruby.runtimeDetails[splitElement[0]] = splitElement[1]
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
return
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const formatSourceArr = sourceArr => {
|
|
124
|
-
return sourceArr.map(element => {
|
|
125
|
-
if (element.sourceType === 'GIT') {
|
|
126
|
-
delete element.specs
|
|
127
|
-
}
|
|
128
|
-
if (element.sourceType === 'GEM') {
|
|
129
|
-
delete element.branch
|
|
130
|
-
delete element.revision
|
|
131
|
-
delete element.depthLevel
|
|
132
|
-
delete element.specs
|
|
133
|
-
}
|
|
134
|
-
if (element.sourceType === 'PATH') {
|
|
135
|
-
delete element.branch
|
|
136
|
-
delete element.revision
|
|
137
|
-
delete element.depthLevel
|
|
138
|
-
delete element.specs
|
|
139
|
-
delete element.platform
|
|
140
|
-
}
|
|
141
|
-
return element
|
|
142
|
-
})
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const getSourceArr = (lines, ruby) => {
|
|
146
|
-
let line = 0
|
|
147
|
-
let source = []
|
|
148
|
-
while ((line = lines[index++]) !== undefined) {
|
|
149
|
-
let currentWS = whitespaceRegx.exec(line)[1].length
|
|
150
|
-
// BF bain!
|
|
151
|
-
if (!line.includes(' bundler (')) {
|
|
152
|
-
// populates sourceType
|
|
153
|
-
if (currentWS === 0 && !line.includes(':') && line != '') {
|
|
154
|
-
populateSourceType(line, rubyObj)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// gets top level keys
|
|
158
|
-
if (currentWS !== 0 && line.includes(':')) {
|
|
159
|
-
nonDependencyKeys(line, rubyObj)
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// dep can be parent at 4WS or edge at 6 WS
|
|
163
|
-
if (currentWS > 2) {
|
|
164
|
-
const isDependencyWithVersion = depReg.test(line)
|
|
165
|
-
|
|
166
|
-
let nexlineWS = whitespaceRegx.exec(lines[index])[1].length
|
|
167
|
-
// means its an edge
|
|
168
|
-
if (currentWS === 6) {
|
|
169
|
-
const dependency = depReg.exec(line)
|
|
170
|
-
if (isDependencyWithVersion) {
|
|
171
|
-
if (rubyObj.name !== dependency[1]) {
|
|
172
|
-
rubyObj.dependencies[dependency[1]] = dependency[3]
|
|
173
|
-
}
|
|
174
|
-
} else {
|
|
175
|
-
rubyObj.dependencies[line.trim()] = 'UNSPECIFIED'
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (currentWS === 4 && rubyObj.depthLevel === undefined) {
|
|
180
|
-
const dependency = depReg.exec(line)
|
|
181
|
-
rubyObj.name = dependency[1]
|
|
182
|
-
rubyObj.depthLevel = currentWS
|
|
183
|
-
populateResolveAndPlatform(dependency[3], rubyObj)
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// when dethlevel is defined and WS is 4 then its a new dep
|
|
187
|
-
if (currentWS === 4 && rubyObj.depthLevel) {
|
|
188
|
-
// create new Parent
|
|
189
|
-
const dependency = depReg.exec(line)
|
|
190
|
-
rubyObj.name = dependency[1]
|
|
191
|
-
rubyObj.depthLevel = currentWS
|
|
192
|
-
populateResolveAndPlatform(dependency[3], rubyObj)
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// need to push into array when:
|
|
196
|
-
// parents with no dep
|
|
197
|
-
// dep and nextline is a parent
|
|
198
|
-
// last line
|
|
199
|
-
if (
|
|
200
|
-
(currentWS === 4 && nexlineWS === 4) ||
|
|
201
|
-
(currentWS === 6 && nexlineWS === 4) ||
|
|
202
|
-
nexlineWS == ''
|
|
203
|
-
) {
|
|
204
|
-
let newObj = {}
|
|
205
|
-
newObj = JSON.parse(JSON.stringify(rubyObj))
|
|
206
|
-
source.push(newObj)
|
|
207
|
-
rubyObj.dependencies = {}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
ruby.sources = formatSourceArr(source)
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
exports.getSourceArr = getSourceArr
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
const i18n = require('i18n')
|
|
2
|
-
|
|
3
|
-
module.exports = exports = ({ ruby }, next) => {
|
|
4
|
-
const { rawProjectFileContents } = ruby
|
|
5
|
-
|
|
6
|
-
// Read the ruby requirements file contents.
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
const rubyArray = rawProjectFileContents.split('\n')
|
|
10
|
-
|
|
11
|
-
//give me the gemfiles
|
|
12
|
-
let filteredRubyDep = rubyArray.filter(element => {
|
|
13
|
-
return (
|
|
14
|
-
!element.includes('#') &&
|
|
15
|
-
element.includes('gem') &&
|
|
16
|
-
!element.includes('source')
|
|
17
|
-
)
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
//trim off whitespace
|
|
21
|
-
for (let i = 0; i < filteredRubyDep.length; i++) {
|
|
22
|
-
filteredRubyDep[i] = filteredRubyDep[i].trim()
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
ruby.gemfilesDependanceies = filteredRubyDep
|
|
26
|
-
|
|
27
|
-
next()
|
|
28
|
-
} catch (err) {
|
|
29
|
-
next(
|
|
30
|
-
new Error(
|
|
31
|
-
i18n.__(
|
|
32
|
-
'rubyAnalysisEngineParsedGemFileError',
|
|
33
|
-
rawProjectFileContents
|
|
34
|
-
) + `${err.message}`
|
|
35
|
-
)
|
|
36
|
-
)
|
|
37
|
-
return
|
|
38
|
-
}
|
|
39
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const i18n = require('i18n')
|
|
3
|
-
|
|
4
|
-
module.exports = exports = ({ language: { projectFilePath }, ruby }, next) => {
|
|
5
|
-
try {
|
|
6
|
-
ruby.rawProjectFileContents = fs.readFileSync(projectFilePath, 'utf8')
|
|
7
|
-
|
|
8
|
-
next()
|
|
9
|
-
} catch (err) {
|
|
10
|
-
next(
|
|
11
|
-
new Error(
|
|
12
|
-
i18n.__('rubyAnalysisEngineReadGemFileError', projectFilePath) +
|
|
13
|
-
`${err.message}`
|
|
14
|
-
)
|
|
15
|
-
)
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const i18n = require('i18n')
|
|
3
|
-
|
|
4
|
-
module.exports = exports = ({ language: { lockFilePath }, ruby }, next) => {
|
|
5
|
-
try {
|
|
6
|
-
ruby.rawLockFileContents = fs.readFileSync(lockFilePath, 'utf8')
|
|
7
|
-
next()
|
|
8
|
-
} catch (err) {
|
|
9
|
-
next(
|
|
10
|
-
new Error(
|
|
11
|
-
i18n.__('rubyAnalysisEngineReadGemLockFileError', lockFilePath) +
|
|
12
|
-
`${err.message}`
|
|
13
|
-
)
|
|
14
|
-
)
|
|
15
|
-
return
|
|
16
|
-
}
|
|
17
|
-
}
|