@contrast/contrast 1.0.0 → 1.0.1
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 +2 -0
- package/README.md +120 -47
- package/dist/audit/AnalysisEngine.js +37 -0
- package/dist/audit/catalogueApplication/catalogueApplication.js +36 -0
- package/dist/audit/dotnetAnalysisEngine/index.js +25 -0
- package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +35 -0
- package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +15 -0
- package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +18 -0
- package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +14 -0
- package/dist/audit/dotnetAnalysisEngine/sanitizer.js +9 -0
- package/dist/audit/goAnalysisEngine/index.js +17 -0
- package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +164 -0
- package/dist/audit/goAnalysisEngine/readProjectFileContents.js +21 -0
- package/dist/audit/goAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/javaAnalysisEngine/index.js +34 -0
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +153 -0
- package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +353 -0
- package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +98 -0
- package/dist/audit/javaAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +24 -0
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +24 -0
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +35 -0
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +23 -0
- package/dist/audit/languageAnalysisEngine/commonApi.js +18 -0
- package/dist/audit/languageAnalysisEngine/constants.js +20 -0
- package/dist/audit/languageAnalysisEngine/filterProjectPath.js +20 -0
- package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +25 -0
- package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +39 -0
- package/dist/audit/languageAnalysisEngine/index.js +39 -0
- package/dist/audit/languageAnalysisEngine/langugageAnalysisFactory.js +70 -0
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +121 -0
- package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +17 -0
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +257 -0
- package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +81 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +133 -0
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +41 -0
- package/dist/audit/languageAnalysisEngine/util/capabilities.js +11 -0
- package/dist/audit/languageAnalysisEngine/util/generalAPI.js +39 -0
- package/dist/audit/languageAnalysisEngine/util/requestUtils.js +14 -0
- package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +40 -0
- package/dist/audit/nodeAnalysisEngine/index.js +31 -0
- package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +18 -0
- package/dist/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +51 -0
- package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +18 -0
- package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +17 -0
- package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +14 -0
- package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +24 -0
- package/dist/audit/nodeAnalysisEngine/sanitizer.js +9 -0
- package/dist/audit/phpAnalysisEngine/index.js +23 -0
- package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +52 -0
- package/dist/audit/phpAnalysisEngine/readLockFileContents.js +13 -0
- package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +16 -0
- package/dist/audit/phpAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/pythonAnalysisEngine/index.js +25 -0
- package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +17 -0
- package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +21 -0
- package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +13 -0
- package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +14 -0
- package/dist/audit/pythonAnalysisEngine/sanitizer.js +7 -0
- package/dist/audit/rubyAnalysisEngine/index.js +25 -0
- package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +176 -0
- package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +22 -0
- package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +14 -0
- package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +14 -0
- package/dist/audit/rubyAnalysisEngine/sanitizer.js +6 -0
- package/dist/commands/audit/auditConfig.js +25 -0
- package/dist/commands/audit/auditController.js +31 -0
- package/dist/commands/audit/help.js +52 -0
- package/dist/commands/audit/processAudit.js +18 -0
- package/dist/commands/auth/auth.js +1 -1
- package/dist/commands/scan/processScan.js +19 -5
- package/dist/common/HTTPClient.js +101 -13
- package/dist/common/errorHandling.js +49 -1
- package/dist/common/findLatestCLIVersion.js +23 -0
- package/dist/constants/constants.js +1 -1
- package/dist/constants/lambda.js +32 -4
- package/dist/constants/locales.js +39 -16
- package/dist/constants.js +148 -20
- package/dist/index.js +7 -1
- package/dist/lambda/aws.js +14 -11
- package/dist/lambda/help.js +4 -0
- package/dist/lambda/lambda.js +50 -27
- package/dist/lambda/lambdaUtils.js +72 -0
- package/dist/lambda/logUtils.js +11 -1
- package/dist/lambda/scanDetailCompletion.js +4 -4
- package/dist/lambda/scanRequest.js +11 -5
- package/dist/lambda/utils.js +110 -53
- package/dist/scan/autoDetection.js +0 -32
- package/dist/scan/fileUtils.js +1 -1
- package/dist/scan/help.js +12 -40
- package/dist/scan/populateProjectIdAndProjectName.js +4 -0
- package/dist/scan/saveResults.js +15 -0
- package/dist/scan/scan.js +77 -42
- package/dist/scan/scanConfig.js +20 -0
- package/dist/scan/scanController.js +13 -15
- package/dist/scan/scanResults.js +18 -16
- package/dist/utils/commonApi.js +3 -3
- package/dist/utils/fileUtils.js +31 -0
- package/dist/utils/paramsUtil/commandlineParams.js +1 -20
- package/dist/utils/paramsUtil/genericCommandLineParams.js +12 -0
- package/dist/utils/paramsUtil/paramHandler.js +3 -6
- package/dist/utils/parsedCLIOptions.js +14 -8
- package/package.json +26 -21
- package/src/audit/AnalysisEngine.js +103 -0
- package/src/audit/catalogueApplication/catalogueApplication.js +42 -0
- package/src/audit/dotnetAnalysisEngine/index.js +26 -0
- package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +47 -0
- package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +29 -0
- package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +30 -0
- package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +26 -0
- package/src/audit/dotnetAnalysisEngine/sanitizer.js +11 -0
- package/src/audit/goAnalysisEngine/index.js +18 -0
- package/src/audit/goAnalysisEngine/parseProjectFileContents.js +209 -0
- package/src/audit/goAnalysisEngine/readProjectFileContents.js +31 -0
- package/src/audit/goAnalysisEngine/sanitizer.js +7 -0
- package/src/audit/javaAnalysisEngine/index.js +41 -0
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +222 -0
- package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +420 -0
- package/src/audit/javaAnalysisEngine/readProjectFileContents.js +141 -0
- package/src/audit/javaAnalysisEngine/sanitizer.js +6 -0
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +35 -0
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +41 -0
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +54 -0
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +32 -0
- package/src/audit/languageAnalysisEngine/commonApi.js +20 -0
- package/src/audit/languageAnalysisEngine/constants.js +23 -0
- package/src/audit/languageAnalysisEngine/filterProjectPath.js +21 -0
- package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +41 -0
- package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +72 -0
- package/src/audit/languageAnalysisEngine/index.js +45 -0
- package/src/audit/languageAnalysisEngine/langugageAnalysisFactory.js +94 -0
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +177 -0
- package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +27 -0
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +303 -0
- package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +124 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.js +190 -0
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +51 -0
- package/src/audit/languageAnalysisEngine/util/capabilities.js +12 -0
- package/src/audit/languageAnalysisEngine/util/generalAPI.js +43 -0
- package/src/audit/languageAnalysisEngine/util/requestUtils.js +17 -0
- package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +49 -0
- package/src/audit/nodeAnalysisEngine/index.js +35 -0
- package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +20 -0
- package/src/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +63 -0
- package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +26 -0
- package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +23 -0
- package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +27 -0
- package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +36 -0
- package/src/audit/nodeAnalysisEngine/sanitizer.js +11 -0
- package/src/audit/phpAnalysisEngine/index.js +27 -0
- package/src/audit/phpAnalysisEngine/parseLockFileContents.js +60 -0
- package/src/audit/phpAnalysisEngine/readLockFileContents.js +14 -0
- package/src/audit/phpAnalysisEngine/readProjectFileContents.js +25 -0
- package/src/audit/phpAnalysisEngine/sanitizer.js +4 -0
- package/src/audit/pythonAnalysisEngine/index.js +55 -0
- package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +23 -0
- package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +33 -0
- package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +16 -0
- package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +22 -0
- package/src/audit/pythonAnalysisEngine/sanitizer.js +9 -0
- package/src/audit/rubyAnalysisEngine/index.js +30 -0
- package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +215 -0
- package/src/audit/rubyAnalysisEngine/parsedGemfile.js +39 -0
- package/src/audit/rubyAnalysisEngine/readGemfileContents.js +18 -0
- package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +17 -0
- package/src/audit/rubyAnalysisEngine/sanitizer.js +8 -0
- package/src/commands/audit/auditConfig.ts +30 -0
- package/src/commands/audit/auditController.ts +31 -0
- package/src/commands/audit/help.ts +48 -0
- package/src/commands/audit/processAudit.ts +19 -0
- package/src/commands/auth/auth.js +1 -1
- package/src/commands/scan/processScan.js +20 -5
- package/src/common/HTTPClient.js +136 -14
- package/src/common/errorHandling.ts +56 -1
- package/src/common/findLatestCLIVersion.ts +27 -0
- package/src/constants/constants.js +1 -1
- package/src/constants/lambda.js +45 -4
- package/src/constants/locales.js +48 -20
- package/src/constants.js +168 -22
- package/src/index.ts +9 -2
- package/src/lambda/aws.ts +13 -12
- package/src/lambda/help.ts +4 -0
- package/src/lambda/lambda.ts +53 -34
- package/src/lambda/lambdaUtils.ts +111 -0
- package/src/lambda/logUtils.ts +19 -1
- package/src/lambda/scanDetailCompletion.ts +4 -4
- package/src/lambda/scanRequest.ts +13 -11
- package/src/lambda/utils.ts +149 -81
- package/src/scan/autoDetection.js +0 -29
- package/src/scan/fileUtils.js +1 -1
- package/src/scan/help.js +12 -45
- package/src/scan/populateProjectIdAndProjectName.js +4 -0
- package/src/scan/saveResults.js +15 -0
- package/src/scan/scan.js +95 -59
- package/src/scan/scanConfig.js +29 -0
- package/src/scan/scanController.js +13 -13
- package/src/scan/scanResults.js +21 -19
- package/src/utils/commonApi.js +2 -3
- package/src/utils/paramsUtil/commandlineParams.js +1 -26
- package/src/utils/paramsUtil/paramHandler.js +3 -7
- package/src/utils/parsedCLIOptions.js +11 -9
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 'AnalysisEngine' type represents a simple state machine that can be used
|
|
3
|
+
* to move through a list of steps sequentially to analyze a project. Consumers
|
|
4
|
+
* construct their own steps and add them to the state machine in their desired
|
|
5
|
+
* order. Upon completion the state machine can callback to the consumer that
|
|
6
|
+
* originally invoked them with the results of the analysis.
|
|
7
|
+
*/
|
|
8
|
+
class AnalysisEngine {
|
|
9
|
+
/**
|
|
10
|
+
* Constructor that creates a new state machine instance. Accepts an optional
|
|
11
|
+
* argument that initializes the internal state.
|
|
12
|
+
*
|
|
13
|
+
* @param {Object} initAnalysis - state used to initialize internal state
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const ae = new AnalysisEngine()
|
|
17
|
+
* const ae = new AnalysisEngine({ someInfo: [1, 2, 3] })
|
|
18
|
+
*/
|
|
19
|
+
constructor(initAnalysis = {}) {
|
|
20
|
+
this.analyzers = []
|
|
21
|
+
this.analysis = { ...initAnalysis }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Takes either a function or a list of functions and adds them in sequential
|
|
26
|
+
* order to a list. The list will be executed at a later time as the steps of
|
|
27
|
+
* the state machine.
|
|
28
|
+
*
|
|
29
|
+
* Functions must follow the signature (analysis, next) where:
|
|
30
|
+
* 'analysis' is an object that represents the current internal state
|
|
31
|
+
* 'next' is a function to be invoked when the step is complete
|
|
32
|
+
*
|
|
33
|
+
* The function signature of 'next' is (err) where:
|
|
34
|
+
* 'err' is an Error that occurred during the previous step invoked
|
|
35
|
+
*
|
|
36
|
+
* @param {function(analysis: object, next: function)|function[]} analyzer -
|
|
37
|
+
* the analyzer(s) to be added to the list of steps in sequential order
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* const myAnalyzer = (analysis, next) => {
|
|
41
|
+
* // Perform business logic
|
|
42
|
+
* // Add results to 'analysis'
|
|
43
|
+
* analysis.result = ...
|
|
44
|
+
*
|
|
45
|
+
* // Signal the next analyzer/step to be invoked
|
|
46
|
+
* next()
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* ae.use(myAnalyzer)
|
|
50
|
+
*/
|
|
51
|
+
use(analyzer) {
|
|
52
|
+
if (Array.isArray(analyzer)) {
|
|
53
|
+
this.analyzers = [...this.analyzers, ...analyzer]
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this.analyzers.push(analyzer)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Starts the execution of the state machine given the steps it is to use.
|
|
62
|
+
* When complete it callbacks back to the consumer that invoked it. The
|
|
63
|
+
* callbacks signature is (err, analysis) where:
|
|
64
|
+
* 'err' is an Error from one of the steps that prevented completion
|
|
65
|
+
* 'analysis' is the final internal state
|
|
66
|
+
*
|
|
67
|
+
* @param {function(err: Error, analysis: object)} callback - callback to be
|
|
68
|
+
* invoked when state machine complete or fails prematurely
|
|
69
|
+
* @param config:object containing config - needed for Java analysis - optional for other languages
|
|
70
|
+
*/
|
|
71
|
+
analyze(callback, config) {
|
|
72
|
+
let i = 0
|
|
73
|
+
|
|
74
|
+
const next = err => {
|
|
75
|
+
// If one of the analyzers encountered an error then callback
|
|
76
|
+
if (err) {
|
|
77
|
+
return setImmediate(() => callback(err, this.analysis))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// If there are no more analyzers to invoke then callback
|
|
81
|
+
if (i >= this.analyzers.length) {
|
|
82
|
+
return setImmediate(() => callback(null, this.analysis))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Invoke the next analyzer
|
|
86
|
+
const analyzer = this.analyzers[i]
|
|
87
|
+
i++
|
|
88
|
+
|
|
89
|
+
setImmediate(() => {
|
|
90
|
+
// Protect ourselves from any uncaught errors thrown by analyzers
|
|
91
|
+
try {
|
|
92
|
+
analyzer(this.analysis, next, config)
|
|
93
|
+
} catch (uncaughtErr) {
|
|
94
|
+
next(uncaughtErr)
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
next()
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
module.exports = exports = AnalysisEngine
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const i18n = require('i18n')
|
|
2
|
+
const { getHttpClient, handleResponseErrors } = require('../../utils/commonApi')
|
|
3
|
+
|
|
4
|
+
const locationOfApp = (config, appId) => {
|
|
5
|
+
return `${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${appId}`
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const displaySuccessMessage = (config, appId) => {
|
|
9
|
+
console.log(
|
|
10
|
+
'\n **************************' +
|
|
11
|
+
i18n.__('successHeader') +
|
|
12
|
+
'************************** \n'
|
|
13
|
+
)
|
|
14
|
+
console.log('\n' + i18n.__('catalogueSuccessCommand') + appId + '\n')
|
|
15
|
+
console.log(locationOfApp(config, appId))
|
|
16
|
+
console.log(
|
|
17
|
+
'\n *********************************************************** \n'
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const catalogueApplication = async config => {
|
|
22
|
+
const client = getHttpClient(config)
|
|
23
|
+
let appId
|
|
24
|
+
await client
|
|
25
|
+
.catalogueCommand(config)
|
|
26
|
+
.then(res => {
|
|
27
|
+
if (res.statusCode === 201) {
|
|
28
|
+
displaySuccessMessage(config, res.body.application.app_id)
|
|
29
|
+
appId = res.body.application.app_id
|
|
30
|
+
} else {
|
|
31
|
+
handleResponseErrors(res, 'catalogue')
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
.catch(err => {
|
|
35
|
+
console.log(err)
|
|
36
|
+
})
|
|
37
|
+
return appId
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = {
|
|
41
|
+
catalogueApplication: catalogueApplication
|
|
42
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const AnalysisEngine = require('../AnalysisEngine')
|
|
2
|
+
const readProjectFileContents = require('./readProjectFileContents')
|
|
3
|
+
const parseProjectFileContents = require('./parseProjectFileContents')
|
|
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, dotnet: {} })
|
|
11
|
+
ae.use([
|
|
12
|
+
readProjectFileContents,
|
|
13
|
+
parseProjectFileContents,
|
|
14
|
+
readLockFileContents,
|
|
15
|
+
parseLockFileContents,
|
|
16
|
+
sanitizer
|
|
17
|
+
])
|
|
18
|
+
|
|
19
|
+
ae.analyze((err, analysis) => {
|
|
20
|
+
if (err) {
|
|
21
|
+
callback(new Error(i18n.__('dotnetAnalysisFailure') + err.message))
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
callback(null, analysis)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const i18n = require('i18n')
|
|
2
|
+
|
|
3
|
+
module.exports = exports = ({ language: { lockFilePath }, dotnet }, next) => {
|
|
4
|
+
const { rawLockFileContents } = dotnet
|
|
5
|
+
|
|
6
|
+
// If we never read the lock file then pass priority
|
|
7
|
+
if (!rawLockFileContents) {
|
|
8
|
+
next()
|
|
9
|
+
|
|
10
|
+
return
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
let count = 0 // Used to test if some nodes are deleted
|
|
15
|
+
dotnet.lockFile = JSON.parse(rawLockFileContents)
|
|
16
|
+
|
|
17
|
+
for (const dependenciesNode in dotnet.lockFile.dependencies) {
|
|
18
|
+
for (const innerNode in dotnet.lockFile.dependencies[dependenciesNode]) {
|
|
19
|
+
const nodeValidation = JSON.stringify(
|
|
20
|
+
dotnet.lockFile.dependencies[dependenciesNode][innerNode]
|
|
21
|
+
)
|
|
22
|
+
if (nodeValidation.includes('"type":"Project"')) {
|
|
23
|
+
count += 1
|
|
24
|
+
delete dotnet.lockFile.dependencies[dependenciesNode][innerNode]
|
|
25
|
+
dotnet.additionalInfo = 'dependenciesNote'
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// If dependencies removed wait for json to be displayed and flag warning
|
|
31
|
+
if (count > 0) {
|
|
32
|
+
const multiLevelProjectWarning = () => {
|
|
33
|
+
console.log('')
|
|
34
|
+
console.log(i18n.__('dependenciesNote'))
|
|
35
|
+
}
|
|
36
|
+
setTimeout(multiLevelProjectWarning, 7000)
|
|
37
|
+
}
|
|
38
|
+
} catch (err) {
|
|
39
|
+
next(
|
|
40
|
+
new Error(i18n.__('dotnetParseLockfile', lockFilePath) + `${err.message}`)
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
next()
|
|
47
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const xml2js = require('xml2js')
|
|
2
|
+
const i18n = require('i18n')
|
|
3
|
+
|
|
4
|
+
module.exports = exports = (
|
|
5
|
+
{ language: { projectFilePath }, dotnet },
|
|
6
|
+
next
|
|
7
|
+
) => {
|
|
8
|
+
const { rawProjectFileContents } = dotnet
|
|
9
|
+
|
|
10
|
+
// Read the .NET project file contents. We are reading into memory presuming
|
|
11
|
+
// that the contents of the file aren't large which may be bad... Could look
|
|
12
|
+
// into streaming in the future
|
|
13
|
+
// explicitArray: false - to not abuse of arrays, with this option we are able to read JSON properties in an easier way
|
|
14
|
+
// mergeAttrs: true - to merge attributes and child elements as properties of the parent
|
|
15
|
+
const parser = new xml2js.Parser({ explicitArray: false, mergeAttrs: true })
|
|
16
|
+
parser.parseString(rawProjectFileContents, (err, projectFileXML) => {
|
|
17
|
+
if (err) {
|
|
18
|
+
next(
|
|
19
|
+
new Error(i18n.__('dotnetParseProjectFile', projectFilePath) + `${err}`)
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
dotnet.projectFile = projectFileXML
|
|
26
|
+
|
|
27
|
+
next()
|
|
28
|
+
})
|
|
29
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const i18n = require('i18n')
|
|
3
|
+
|
|
4
|
+
module.exports = exports = (analysis, next) => {
|
|
5
|
+
const {
|
|
6
|
+
language: { lockFilePath },
|
|
7
|
+
dotnet
|
|
8
|
+
} = analysis
|
|
9
|
+
|
|
10
|
+
// Make sure to check to see if there was a lock file detected as its not
|
|
11
|
+
// required
|
|
12
|
+
if (!lockFilePath) {
|
|
13
|
+
next()
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// we're working on the assumtion that a dotNet project will only ever have one lock file
|
|
18
|
+
//while other language may have more
|
|
19
|
+
try {
|
|
20
|
+
dotnet.rawLockFileContents = fs.readFileSync(lockFilePath)
|
|
21
|
+
} catch (err) {
|
|
22
|
+
next(
|
|
23
|
+
new Error(i18n.__('dotnetReadLockfile', lockFilePath) + `${err.message}`)
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
next()
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const i18n = require('i18n')
|
|
3
|
+
|
|
4
|
+
module.exports = exports = (analysis, next) => {
|
|
5
|
+
const {
|
|
6
|
+
language: { projectFilePath },
|
|
7
|
+
dotnet
|
|
8
|
+
} = analysis
|
|
9
|
+
|
|
10
|
+
// Read the .NET project file contents. We are reading into memory presuming
|
|
11
|
+
// that the contents of the file aren't large which may be bad... Could look
|
|
12
|
+
// into streaming in the future
|
|
13
|
+
try {
|
|
14
|
+
dotnet.rawProjectFileContents = fs.readFileSync(projectFilePath)
|
|
15
|
+
} catch (err) {
|
|
16
|
+
next(
|
|
17
|
+
new Error(
|
|
18
|
+
i18n.__('dotnetReadProjectFile', projectFilePath) + `${err.message}`
|
|
19
|
+
)
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
next()
|
|
26
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module.exports = exports = ({ dotnet }, next) => {
|
|
2
|
+
// Remove anything sensitive or unnecessary from being sent to the backend as
|
|
3
|
+
// a result of our .NET project analysis
|
|
4
|
+
delete dotnet.rawProjectFileContents
|
|
5
|
+
delete dotnet.parsedProjectFileContents
|
|
6
|
+
delete dotnet.projectFileXML
|
|
7
|
+
delete dotnet.packageReferences
|
|
8
|
+
delete dotnet.rawLockFileContents
|
|
9
|
+
|
|
10
|
+
next()
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const AnalysisEngine = require('../AnalysisEngine')
|
|
2
|
+
const readProjectFileContents = require('./readProjectFileContents')
|
|
3
|
+
const parseProjectFileContents = require('./parseProjectFileContents')
|
|
4
|
+
const sanitizer = require('./sanitizer')
|
|
5
|
+
const i18n = require('i18n')
|
|
6
|
+
|
|
7
|
+
module.exports = exports = (language, config, callback) => {
|
|
8
|
+
const ae = new AnalysisEngine({ language, config, go: {} })
|
|
9
|
+
ae.use([readProjectFileContents, parseProjectFileContents, sanitizer])
|
|
10
|
+
|
|
11
|
+
ae.analyze((err, analysis) => {
|
|
12
|
+
if (err) {
|
|
13
|
+
callback(new Error(i18n.__('goAnalysisError') + `${err.message}`))
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
callback(null, analysis)
|
|
17
|
+
})
|
|
18
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
const i18n = require('i18n')
|
|
2
|
+
const crypto = require('crypto')
|
|
3
|
+
|
|
4
|
+
module.exports = exports = ({ go }, next) => {
|
|
5
|
+
const { modGraphOutput } = go
|
|
6
|
+
try {
|
|
7
|
+
go.goDependencyTrees = parseGo(modGraphOutput)
|
|
8
|
+
} catch (err) {
|
|
9
|
+
next(new Error(i18n.__('goParseProjectFile') + `${err.message}`))
|
|
10
|
+
return
|
|
11
|
+
}
|
|
12
|
+
next()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const splitAllLinesIntoArray = modGraphOutput => {
|
|
16
|
+
return modGraphOutput.split(/\r\n|\r|\n/)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const parseGo = modGraphOutput => {
|
|
20
|
+
let splitLines = splitAllLinesIntoArray(modGraphOutput)
|
|
21
|
+
const directDepNames = getDirectDepNames(splitLines)
|
|
22
|
+
const uniqueTransitiveDepNames = getAllUniqueTransitiveDepNames(
|
|
23
|
+
splitLines,
|
|
24
|
+
directDepNames
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
let rootNodes = createRootNodes(splitLines)
|
|
28
|
+
|
|
29
|
+
createTransitiveDeps(uniqueTransitiveDepNames, splitLines, rootNodes)
|
|
30
|
+
|
|
31
|
+
//console.log(rootNodes)
|
|
32
|
+
|
|
33
|
+
return rootNodes
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const getAllDepsOfADepAsEdge = (dep, deps) => {
|
|
37
|
+
let edges = {}
|
|
38
|
+
|
|
39
|
+
const depRows = deps.filter(line => {
|
|
40
|
+
return line.startsWith(dep)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
depRows.forEach(dep => {
|
|
44
|
+
const edgeName = dep.split(' ')[1]
|
|
45
|
+
edges[edgeName] = edgeName
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
return edges
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const getAllDepsOfADepAsName = (dep, deps) => {
|
|
52
|
+
let edges = []
|
|
53
|
+
|
|
54
|
+
const depRows = deps.filter(line => {
|
|
55
|
+
return line.startsWith(dep)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
depRows.forEach(dep => {
|
|
59
|
+
const edgeName = dep.split(' ')[1]
|
|
60
|
+
edges.push(edgeName)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
return edges
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const createRootNodes = deps => {
|
|
67
|
+
let rootDep = {}
|
|
68
|
+
const rootDeps = getRootDeps(deps)
|
|
69
|
+
|
|
70
|
+
const edges = rootDeps.map(dep => {
|
|
71
|
+
return dep.split(' ')[1]
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
rootDep[rootDeps[0].split(' ')[0]] = {}
|
|
75
|
+
|
|
76
|
+
edges.forEach(edge => {
|
|
77
|
+
const splitEdge = edge.split('@')
|
|
78
|
+
const splitGroupName = splitEdge[0].split('/')
|
|
79
|
+
const name = splitGroupName.pop()
|
|
80
|
+
const lastSlash = splitEdge[0].lastIndexOf('/')
|
|
81
|
+
let group = splitEdge[0].substring(0, lastSlash)
|
|
82
|
+
const hash = getHash(splitEdge[0])
|
|
83
|
+
|
|
84
|
+
group = checkGroupExists(group, name)
|
|
85
|
+
|
|
86
|
+
//get the edges of the root dependency
|
|
87
|
+
const edgesOfDep = getAllDepsOfADepAsEdge(edge, deps)
|
|
88
|
+
|
|
89
|
+
rootDep[rootDeps[0].split(' ')[0]][edge] = {
|
|
90
|
+
artifactID: name,
|
|
91
|
+
group: group,
|
|
92
|
+
version: splitEdge[1],
|
|
93
|
+
scope: '"compile',
|
|
94
|
+
type: 'direct',
|
|
95
|
+
hash: hash,
|
|
96
|
+
edges: edgesOfDep
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
return rootDep
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const getRootDeps = deps => {
|
|
103
|
+
const rootDeps = deps.filter(dep => {
|
|
104
|
+
const parentDep = dep.split(' ')[0]
|
|
105
|
+
if (parentDep.split('@v').length === 1) {
|
|
106
|
+
return dep
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
return rootDeps
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const getHash = library => {
|
|
113
|
+
let shaSum = crypto.createHash('sha1')
|
|
114
|
+
shaSum.update(library)
|
|
115
|
+
return shaSum.digest('hex')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const getDirectDepNames = deps => {
|
|
119
|
+
const directDepNames = []
|
|
120
|
+
|
|
121
|
+
deps.forEach(dep => {
|
|
122
|
+
const parentDep = dep.split(' ')[0]
|
|
123
|
+
if (parentDep.split('@v').length === 1) {
|
|
124
|
+
dep.split(' ')[1] !== undefined
|
|
125
|
+
? directDepNames.push(dep.split(' ')[1])
|
|
126
|
+
: null
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
return directDepNames
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const getAllUniqueTransitiveDepNames = (deps, directDepNames) => {
|
|
133
|
+
let uniqueDeps = []
|
|
134
|
+
|
|
135
|
+
deps.forEach(dep => {
|
|
136
|
+
const parentDep = dep.split(' ')[0]
|
|
137
|
+
if (parentDep.split('@v').length !== 1) {
|
|
138
|
+
if (!directDepNames.includes(parentDep)) {
|
|
139
|
+
if (!uniqueDeps.includes(parentDep)) {
|
|
140
|
+
parentDep.length > 1 ? uniqueDeps.push(parentDep) : null
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
return uniqueDeps
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const checkGroupExists = (group, name) => {
|
|
149
|
+
if (group === null || group === '') {
|
|
150
|
+
return name
|
|
151
|
+
}
|
|
152
|
+
return group
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const createTransitiveDeps = (transitiveDeps, splitLines, rootNodes) => {
|
|
156
|
+
transitiveDeps.forEach(dep => {
|
|
157
|
+
//create transitive dep
|
|
158
|
+
const splitEdge = dep.split('@')
|
|
159
|
+
const splitGroupName = splitEdge[0].split('/')
|
|
160
|
+
const name = splitGroupName.pop()
|
|
161
|
+
const lastSlash = splitEdge[0].lastIndexOf('/')
|
|
162
|
+
let group = splitEdge[0].substring(0, lastSlash)
|
|
163
|
+
const hash = getHash(splitEdge[0])
|
|
164
|
+
|
|
165
|
+
group = checkGroupExists(group, name)
|
|
166
|
+
|
|
167
|
+
const transitiveDep = {
|
|
168
|
+
artifactID: name,
|
|
169
|
+
group: group,
|
|
170
|
+
version: splitEdge[1],
|
|
171
|
+
scope: 'compile',
|
|
172
|
+
type: 'transitive',
|
|
173
|
+
hash: hash,
|
|
174
|
+
edges: {}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
//add edges to transitiveDep
|
|
178
|
+
const edges = getAllDepsOfADepAsEdge(dep, splitLines)
|
|
179
|
+
transitiveDep.edges = edges
|
|
180
|
+
|
|
181
|
+
//add all edges as a transitive dependency to rootNodes
|
|
182
|
+
const edgesAsName = getAllDepsOfADepAsName(dep, splitLines)
|
|
183
|
+
|
|
184
|
+
edgesAsName.forEach(dep => {
|
|
185
|
+
const splitEdge = dep.split('@')
|
|
186
|
+
const splitGroupName = splitEdge[0].split('/')
|
|
187
|
+
const name = splitGroupName.pop()
|
|
188
|
+
const lastSlash = splitEdge[0].lastIndexOf('/')
|
|
189
|
+
let group = splitEdge[0].substring(0, lastSlash)
|
|
190
|
+
const hash = getHash(splitEdge[0])
|
|
191
|
+
|
|
192
|
+
group = checkGroupExists(group, name)
|
|
193
|
+
|
|
194
|
+
const transitiveDep = {
|
|
195
|
+
artifactID: name,
|
|
196
|
+
group: group,
|
|
197
|
+
version: splitEdge[1],
|
|
198
|
+
scope: 'compile',
|
|
199
|
+
type: 'transitive',
|
|
200
|
+
hash: hash,
|
|
201
|
+
edges: {}
|
|
202
|
+
}
|
|
203
|
+
rootNodes[Object.keys(rootNodes)[0]][dep] = transitiveDep
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
//add transitive dependency to rootNodes
|
|
207
|
+
rootNodes[Object.keys(rootNodes)[0]][dep] = transitiveDep
|
|
208
|
+
})
|
|
209
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const child_process = require('child_process')
|
|
2
|
+
const i18n = require('i18n')
|
|
3
|
+
|
|
4
|
+
module.exports = exports = async (
|
|
5
|
+
{ language: { projectFilePath }, go },
|
|
6
|
+
next
|
|
7
|
+
) => {
|
|
8
|
+
let cmdStdout
|
|
9
|
+
let cwd
|
|
10
|
+
try {
|
|
11
|
+
cwd = projectFilePath.replace('go.mod', '')
|
|
12
|
+
// A sample of this output can be found
|
|
13
|
+
// in the go test folder data/goModGraphResults.text
|
|
14
|
+
cmdStdout = child_process.execSync('go mod graph', { cwd })
|
|
15
|
+
|
|
16
|
+
go.modGraphOutput = cmdStdout.toString()
|
|
17
|
+
|
|
18
|
+
next()
|
|
19
|
+
} catch (err) {
|
|
20
|
+
if (err.message === 'spawnSync /bin/sh ENOENT') {
|
|
21
|
+
err.message =
|
|
22
|
+
'\n\n*************** No transitive dependencies ***************\n\nWe are unable to build a dependency tree view from your repository as there were no transitive dependencies found.'
|
|
23
|
+
}
|
|
24
|
+
next(
|
|
25
|
+
new Error(
|
|
26
|
+
i18n.__('goReadProjectFile', cwd, `${err.message ? err.message : ''}`)
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const AnalysisEngine = require('../AnalysisEngine')
|
|
2
|
+
|
|
3
|
+
const readProjectFileContents = require('./readProjectFileContents')
|
|
4
|
+
const parseMavenProjectFileContents = require('./parseMavenProjectFileContents')
|
|
5
|
+
const parseProjectFileContents = require('./parseProjectFileContents')
|
|
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, java: {} })
|
|
11
|
+
|
|
12
|
+
// Remove ".kts" from filename to look the same as a Gradle projectFileName so we can support Kotlin
|
|
13
|
+
language.projectFilePath = language.projectFilePath.replace(
|
|
14
|
+
'build.gradle.kts',
|
|
15
|
+
'build.gradle'
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
if (config['beta_unified_java_parser']) {
|
|
19
|
+
console.log('Using new parser...')
|
|
20
|
+
ae.use([readProjectFileContents, parseProjectFileContents, sanitizer])
|
|
21
|
+
} else if (
|
|
22
|
+
language.projectFilePath.endsWith('pom.xml') &&
|
|
23
|
+
!config['beta_unified_java_parser']
|
|
24
|
+
) {
|
|
25
|
+
ae.use([readProjectFileContents, parseMavenProjectFileContents, sanitizer])
|
|
26
|
+
} else {
|
|
27
|
+
ae.use([
|
|
28
|
+
readProjectFileContents,
|
|
29
|
+
parseMavenProjectFileContents,
|
|
30
|
+
parseProjectFileContents,
|
|
31
|
+
sanitizer
|
|
32
|
+
])
|
|
33
|
+
}
|
|
34
|
+
ae.analyze((err, analysis) => {
|
|
35
|
+
if (err) {
|
|
36
|
+
console.log(i18n.__('javaAnalysisError'), err.message)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
callback(null, analysis, config)
|
|
40
|
+
}, config)
|
|
41
|
+
}
|