@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.
Files changed (201) hide show
  1. package/.prettierignore +2 -0
  2. package/README.md +120 -47
  3. package/dist/audit/AnalysisEngine.js +37 -0
  4. package/dist/audit/catalogueApplication/catalogueApplication.js +36 -0
  5. package/dist/audit/dotnetAnalysisEngine/index.js +25 -0
  6. package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +35 -0
  7. package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +15 -0
  8. package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +18 -0
  9. package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +14 -0
  10. package/dist/audit/dotnetAnalysisEngine/sanitizer.js +9 -0
  11. package/dist/audit/goAnalysisEngine/index.js +17 -0
  12. package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +164 -0
  13. package/dist/audit/goAnalysisEngine/readProjectFileContents.js +21 -0
  14. package/dist/audit/goAnalysisEngine/sanitizer.js +5 -0
  15. package/dist/audit/javaAnalysisEngine/index.js +34 -0
  16. package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +153 -0
  17. package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +353 -0
  18. package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +98 -0
  19. package/dist/audit/javaAnalysisEngine/sanitizer.js +5 -0
  20. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +24 -0
  21. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +24 -0
  22. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +35 -0
  23. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +23 -0
  24. package/dist/audit/languageAnalysisEngine/commonApi.js +18 -0
  25. package/dist/audit/languageAnalysisEngine/constants.js +20 -0
  26. package/dist/audit/languageAnalysisEngine/filterProjectPath.js +20 -0
  27. package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +25 -0
  28. package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +39 -0
  29. package/dist/audit/languageAnalysisEngine/index.js +39 -0
  30. package/dist/audit/languageAnalysisEngine/langugageAnalysisFactory.js +70 -0
  31. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +121 -0
  32. package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +17 -0
  33. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +257 -0
  34. package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +81 -0
  35. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +133 -0
  36. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +41 -0
  37. package/dist/audit/languageAnalysisEngine/util/capabilities.js +11 -0
  38. package/dist/audit/languageAnalysisEngine/util/generalAPI.js +39 -0
  39. package/dist/audit/languageAnalysisEngine/util/requestUtils.js +14 -0
  40. package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +40 -0
  41. package/dist/audit/nodeAnalysisEngine/index.js +31 -0
  42. package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +18 -0
  43. package/dist/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +51 -0
  44. package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +18 -0
  45. package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +17 -0
  46. package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +14 -0
  47. package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +24 -0
  48. package/dist/audit/nodeAnalysisEngine/sanitizer.js +9 -0
  49. package/dist/audit/phpAnalysisEngine/index.js +23 -0
  50. package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +52 -0
  51. package/dist/audit/phpAnalysisEngine/readLockFileContents.js +13 -0
  52. package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +16 -0
  53. package/dist/audit/phpAnalysisEngine/sanitizer.js +5 -0
  54. package/dist/audit/pythonAnalysisEngine/index.js +25 -0
  55. package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +17 -0
  56. package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +21 -0
  57. package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +13 -0
  58. package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +14 -0
  59. package/dist/audit/pythonAnalysisEngine/sanitizer.js +7 -0
  60. package/dist/audit/rubyAnalysisEngine/index.js +25 -0
  61. package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +176 -0
  62. package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +22 -0
  63. package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +14 -0
  64. package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +14 -0
  65. package/dist/audit/rubyAnalysisEngine/sanitizer.js +6 -0
  66. package/dist/commands/audit/auditConfig.js +25 -0
  67. package/dist/commands/audit/auditController.js +31 -0
  68. package/dist/commands/audit/help.js +52 -0
  69. package/dist/commands/audit/processAudit.js +18 -0
  70. package/dist/commands/auth/auth.js +1 -1
  71. package/dist/commands/scan/processScan.js +19 -5
  72. package/dist/common/HTTPClient.js +101 -13
  73. package/dist/common/errorHandling.js +49 -1
  74. package/dist/common/findLatestCLIVersion.js +23 -0
  75. package/dist/constants/constants.js +1 -1
  76. package/dist/constants/lambda.js +32 -4
  77. package/dist/constants/locales.js +39 -16
  78. package/dist/constants.js +148 -20
  79. package/dist/index.js +7 -1
  80. package/dist/lambda/aws.js +14 -11
  81. package/dist/lambda/help.js +4 -0
  82. package/dist/lambda/lambda.js +50 -27
  83. package/dist/lambda/lambdaUtils.js +72 -0
  84. package/dist/lambda/logUtils.js +11 -1
  85. package/dist/lambda/scanDetailCompletion.js +4 -4
  86. package/dist/lambda/scanRequest.js +11 -5
  87. package/dist/lambda/utils.js +110 -53
  88. package/dist/scan/autoDetection.js +0 -32
  89. package/dist/scan/fileUtils.js +1 -1
  90. package/dist/scan/help.js +12 -40
  91. package/dist/scan/populateProjectIdAndProjectName.js +4 -0
  92. package/dist/scan/saveResults.js +15 -0
  93. package/dist/scan/scan.js +77 -42
  94. package/dist/scan/scanConfig.js +20 -0
  95. package/dist/scan/scanController.js +13 -15
  96. package/dist/scan/scanResults.js +18 -16
  97. package/dist/utils/commonApi.js +3 -3
  98. package/dist/utils/fileUtils.js +31 -0
  99. package/dist/utils/paramsUtil/commandlineParams.js +1 -20
  100. package/dist/utils/paramsUtil/genericCommandLineParams.js +12 -0
  101. package/dist/utils/paramsUtil/paramHandler.js +3 -6
  102. package/dist/utils/parsedCLIOptions.js +14 -8
  103. package/package.json +26 -21
  104. package/src/audit/AnalysisEngine.js +103 -0
  105. package/src/audit/catalogueApplication/catalogueApplication.js +42 -0
  106. package/src/audit/dotnetAnalysisEngine/index.js +26 -0
  107. package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +47 -0
  108. package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +29 -0
  109. package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +30 -0
  110. package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +26 -0
  111. package/src/audit/dotnetAnalysisEngine/sanitizer.js +11 -0
  112. package/src/audit/goAnalysisEngine/index.js +18 -0
  113. package/src/audit/goAnalysisEngine/parseProjectFileContents.js +209 -0
  114. package/src/audit/goAnalysisEngine/readProjectFileContents.js +31 -0
  115. package/src/audit/goAnalysisEngine/sanitizer.js +7 -0
  116. package/src/audit/javaAnalysisEngine/index.js +41 -0
  117. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +222 -0
  118. package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +420 -0
  119. package/src/audit/javaAnalysisEngine/readProjectFileContents.js +141 -0
  120. package/src/audit/javaAnalysisEngine/sanitizer.js +6 -0
  121. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +35 -0
  122. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +41 -0
  123. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +54 -0
  124. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +32 -0
  125. package/src/audit/languageAnalysisEngine/commonApi.js +20 -0
  126. package/src/audit/languageAnalysisEngine/constants.js +23 -0
  127. package/src/audit/languageAnalysisEngine/filterProjectPath.js +21 -0
  128. package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +41 -0
  129. package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +72 -0
  130. package/src/audit/languageAnalysisEngine/index.js +45 -0
  131. package/src/audit/languageAnalysisEngine/langugageAnalysisFactory.js +94 -0
  132. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +177 -0
  133. package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +27 -0
  134. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +303 -0
  135. package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +124 -0
  136. package/src/audit/languageAnalysisEngine/report/reportingFeature.js +190 -0
  137. package/src/audit/languageAnalysisEngine/sendSnapshot.js +51 -0
  138. package/src/audit/languageAnalysisEngine/util/capabilities.js +12 -0
  139. package/src/audit/languageAnalysisEngine/util/generalAPI.js +43 -0
  140. package/src/audit/languageAnalysisEngine/util/requestUtils.js +17 -0
  141. package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +49 -0
  142. package/src/audit/nodeAnalysisEngine/index.js +35 -0
  143. package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +20 -0
  144. package/src/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +63 -0
  145. package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +26 -0
  146. package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +23 -0
  147. package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +27 -0
  148. package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +36 -0
  149. package/src/audit/nodeAnalysisEngine/sanitizer.js +11 -0
  150. package/src/audit/phpAnalysisEngine/index.js +27 -0
  151. package/src/audit/phpAnalysisEngine/parseLockFileContents.js +60 -0
  152. package/src/audit/phpAnalysisEngine/readLockFileContents.js +14 -0
  153. package/src/audit/phpAnalysisEngine/readProjectFileContents.js +25 -0
  154. package/src/audit/phpAnalysisEngine/sanitizer.js +4 -0
  155. package/src/audit/pythonAnalysisEngine/index.js +55 -0
  156. package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +23 -0
  157. package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +33 -0
  158. package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +16 -0
  159. package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +22 -0
  160. package/src/audit/pythonAnalysisEngine/sanitizer.js +9 -0
  161. package/src/audit/rubyAnalysisEngine/index.js +30 -0
  162. package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +215 -0
  163. package/src/audit/rubyAnalysisEngine/parsedGemfile.js +39 -0
  164. package/src/audit/rubyAnalysisEngine/readGemfileContents.js +18 -0
  165. package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +17 -0
  166. package/src/audit/rubyAnalysisEngine/sanitizer.js +8 -0
  167. package/src/commands/audit/auditConfig.ts +30 -0
  168. package/src/commands/audit/auditController.ts +31 -0
  169. package/src/commands/audit/help.ts +48 -0
  170. package/src/commands/audit/processAudit.ts +19 -0
  171. package/src/commands/auth/auth.js +1 -1
  172. package/src/commands/scan/processScan.js +20 -5
  173. package/src/common/HTTPClient.js +136 -14
  174. package/src/common/errorHandling.ts +56 -1
  175. package/src/common/findLatestCLIVersion.ts +27 -0
  176. package/src/constants/constants.js +1 -1
  177. package/src/constants/lambda.js +45 -4
  178. package/src/constants/locales.js +48 -20
  179. package/src/constants.js +168 -22
  180. package/src/index.ts +9 -2
  181. package/src/lambda/aws.ts +13 -12
  182. package/src/lambda/help.ts +4 -0
  183. package/src/lambda/lambda.ts +53 -34
  184. package/src/lambda/lambdaUtils.ts +111 -0
  185. package/src/lambda/logUtils.ts +19 -1
  186. package/src/lambda/scanDetailCompletion.ts +4 -4
  187. package/src/lambda/scanRequest.ts +13 -11
  188. package/src/lambda/utils.ts +149 -81
  189. package/src/scan/autoDetection.js +0 -29
  190. package/src/scan/fileUtils.js +1 -1
  191. package/src/scan/help.js +12 -45
  192. package/src/scan/populateProjectIdAndProjectName.js +4 -0
  193. package/src/scan/saveResults.js +15 -0
  194. package/src/scan/scan.js +95 -59
  195. package/src/scan/scanConfig.js +29 -0
  196. package/src/scan/scanController.js +13 -13
  197. package/src/scan/scanResults.js +21 -19
  198. package/src/utils/commonApi.js +2 -3
  199. package/src/utils/paramsUtil/commandlineParams.js +1 -26
  200. package/src/utils/paramsUtil/paramHandler.js +3 -7
  201. package/src/utils/parsedCLIOptions.js +11 -9
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ const i18n = require('i18n');
3
+ module.exports = exports = ({ language: { projectFilePath }, java }, next) => {
4
+ const { mvnDependancyTreeOutput } = java;
5
+ if (projectFilePath.endsWith('pom.xml')) {
6
+ try {
7
+ java.mavenDependencyTrees = parseMvn(mvnDependancyTreeOutput);
8
+ next();
9
+ }
10
+ catch (err) {
11
+ next(new Error(i18n.__('javaParseProjectFile') + `${err.message}`));
12
+ return;
13
+ }
14
+ }
15
+ else {
16
+ next();
17
+ }
18
+ };
19
+ const hasVersion = key => {
20
+ var regex = RegExp('[0-9].[0-9]');
21
+ return regex.test(key);
22
+ };
23
+ const formatKeyName = value => {
24
+ let tempArr = value.split(':');
25
+ let versionIndex = undefined;
26
+ for (let i = 0; i < tempArr.length; i++) {
27
+ if (hasVersion(tempArr[i])) {
28
+ versionIndex = i;
29
+ }
30
+ }
31
+ return tempArr[0] + '/' + tempArr[1] + '@' + tempArr[versionIndex];
32
+ };
33
+ const shaveConsoleOutputUntilItFindsFirsDigraphMention = mvnDependancyTreeOutput => {
34
+ return mvnDependancyTreeOutput.substring(mvnDependancyTreeOutput.indexOf('digraph'));
35
+ };
36
+ const getDigraphObjInfo = editedOutput => {
37
+ let digraphObj = editedOutput.split('digraph');
38
+ return digraphObj.filter(v => v != '');
39
+ };
40
+ const createDigraphObjKey = element => {
41
+ let formatObjKey = element.substring(0, element.indexOf('{'));
42
+ formatObjKey = formatObjKey.replace(/"/g, '');
43
+ formatObjKey = formatObjKey.replace('{', '');
44
+ formatObjKey = formatObjKey.trim();
45
+ return formatObjKey;
46
+ };
47
+ const turnDigraphDependanciesIntoArrOfInnerDep = digraphObj => {
48
+ let depRow = digraphObj.substring(digraphObj.indexOf('{'), digraphObj.indexOf('}') + 1);
49
+ depRow = depRow.replace(/\[INFO\]/g, '');
50
+ depRow = depRow.replace(/\n/g, '');
51
+ depRow = depRow.replace(/\{/g, '');
52
+ depRow = depRow.replace(/\}/g, '');
53
+ depRow = depRow.replace(/\"/g, '');
54
+ return depRow.split(';').map(s => s.trim());
55
+ };
56
+ const createOuterDependanciesAndType = (digraphObjKey, arrOfInnerDep) => {
57
+ let leftKey;
58
+ let rightKey;
59
+ let newDepNode;
60
+ const list = [];
61
+ arrOfInnerDep.forEach(element => {
62
+ leftKey = element.substring(0, element.indexOf(' -'));
63
+ rightKey = element.substring(element.indexOf('>') + 2);
64
+ if (leftKey === digraphObjKey) {
65
+ if (hasVersion(rightKey)) {
66
+ let rightKeyArr = rightKey.split(':');
67
+ newDepNode = {
68
+ [rightKey]: {
69
+ group: rightKeyArr[0],
70
+ artifactID: rightKeyArr[1],
71
+ packaging: rightKeyArr[2],
72
+ version: rightKeyArr[3],
73
+ scope: rightKeyArr[4],
74
+ type: 'direct',
75
+ parent: leftKey,
76
+ edges: {}
77
+ }
78
+ };
79
+ list.push(newDepNode);
80
+ }
81
+ }
82
+ if (hasVersion(leftKey) &&
83
+ hasVersion(rightKey) &&
84
+ !(leftKey === digraphObjKey)) {
85
+ let rightKeyArr = rightKey.split(':');
86
+ newDepNode = {
87
+ [rightKey]: {
88
+ group: rightKeyArr[0],
89
+ artifactID: rightKeyArr[1],
90
+ packaging: rightKeyArr[2],
91
+ version: rightKeyArr[3],
92
+ scope: rightKeyArr[4],
93
+ type: 'transitive',
94
+ parent: leftKey,
95
+ edges: {}
96
+ }
97
+ };
98
+ list.push(newDepNode);
99
+ }
100
+ });
101
+ return list;
102
+ };
103
+ const createEdges = (digraphObjKey, listOuterDep) => {
104
+ listOuterDep.forEach(element => {
105
+ const key = Object.keys(element).toString();
106
+ const childParentRef = element[key].parent;
107
+ if (childParentRef !== digraphObjKey) {
108
+ listOuterDep.forEach(i => {
109
+ let parentKey = Object.keys(i).toString();
110
+ if (childParentRef === parentKey) {
111
+ i[parentKey].edges[formatKeyName(key)] = formatKeyName(key);
112
+ }
113
+ });
114
+ }
115
+ });
116
+ return listOuterDep;
117
+ };
118
+ const extractFromArrAndFinalParse = listWithEdges => {
119
+ let finalObj = {};
120
+ listWithEdges.forEach(element => {
121
+ const key = Object.keys(element).toString();
122
+ const parsedKey = formatKeyName(key);
123
+ delete element[key].parent;
124
+ finalObj[parsedKey] = element[key];
125
+ });
126
+ return finalObj;
127
+ };
128
+ const dependancyValueCreationOrganiser = (digraphObjKey, digraph) => {
129
+ const arrOfInnerDep = turnDigraphDependanciesIntoArrOfInnerDep(digraph);
130
+ const listOuterDep = createOuterDependanciesAndType(digraphObjKey, arrOfInnerDep);
131
+ const listWithEdges = createEdges(digraphObjKey, listOuterDep);
132
+ const finishDepObj = extractFromArrAndFinalParse(listWithEdges);
133
+ return finishDepObj;
134
+ };
135
+ const parseMvn = mvnDependancyTreeOutput => {
136
+ let parsedDepObj = {};
137
+ let editedOutput = shaveConsoleOutputUntilItFindsFirsDigraphMention(mvnDependancyTreeOutput);
138
+ let digraphObjArray = getDigraphObjInfo(editedOutput);
139
+ digraphObjArray.forEach(digraph => {
140
+ const digraphObjKey = createDigraphObjKey(digraph);
141
+ parsedDepObj[digraphObjKey] = dependancyValueCreationOrganiser(digraphObjKey, digraph);
142
+ });
143
+ return parsedDepObj;
144
+ };
145
+ exports.shaveConsoleOutputUntilItFindsFirsDigraphMention = shaveConsoleOutputUntilItFindsFirsDigraphMention;
146
+ exports.getDigraphObjInfo = getDigraphObjInfo;
147
+ exports.createDigraphObjKey = createDigraphObjKey;
148
+ exports.turnDigraphDependanciesIntoArrOfInnerDep = turnDigraphDependanciesIntoArrOfInnerDep;
149
+ exports.hasVersion = hasVersion;
150
+ exports.formatKeyName = formatKeyName;
151
+ exports.createOuterDependanciesAndType = createOuterDependanciesAndType;
152
+ exports.extractFromArrAndFinalParse = extractFromArrAndFinalParse;
153
+ exports.createEdges = createEdges;
@@ -0,0 +1,353 @@
1
+ "use strict";
2
+ const i18n = require('i18n');
3
+ let projectType = '';
4
+ const StringBuilder = require('string-builder');
5
+ let sb = new StringBuilder();
6
+ module.exports = exports = ({ language: { projectFilePath }, java }, next, config) => {
7
+ const { mvnDependancyTreeOutput } = java;
8
+ if (projectFilePath.endsWith('build.gradle') ||
9
+ projectFilePath.endsWith('pom.xml')) {
10
+ if (projectFilePath.endsWith('build.gradle')) {
11
+ projectType = 'Gradle';
12
+ }
13
+ else {
14
+ projectType = 'Maven';
15
+ }
16
+ try {
17
+ java.mavenDependencyTrees = parseGradle(mvnDependancyTreeOutput, config);
18
+ next();
19
+ }
20
+ catch (err) {
21
+ next(new Error(i18n.__('javaParseProjectFile') + `${err.message}`));
22
+ return;
23
+ }
24
+ }
25
+ else {
26
+ next();
27
+ }
28
+ };
29
+ const preParser = shavedOutput => {
30
+ let obj = [];
31
+ for (let dep in shavedOutput) {
32
+ obj.push(shavedOutput[dep]
33
+ .replace('+-', '+---')
34
+ .replace('[INFO]', '')
35
+ .replace('\\-', '\\---')
36
+ .replace(':jar:', ':')
37
+ .replace(':test', '')
38
+ .replace(':compile', '')
39
+ .replace(' +', '+')
40
+ .replace(' |', '|')
41
+ .replace(' \\', '\\')
42
+ .replace(':runtime', ''));
43
+ }
44
+ let depTree = [];
45
+ for (let x in obj) {
46
+ let nodeLevel = computeRelationToLastElement(obj[x]);
47
+ let notLastLevel = obj[x].startsWith('|') ||
48
+ obj[x].startsWith('+') ||
49
+ obj[x].startsWith('\\');
50
+ if (notLastLevel) {
51
+ if (nodeLevel === 0) {
52
+ depTree.push(obj[x]);
53
+ }
54
+ else {
55
+ let level = computeLevel(nodeLevel);
56
+ let validatedLevel = addIndentation(nodeLevel === 2 ? 5 : level, obj[x]);
57
+ depTree.push(validatedLevel);
58
+ }
59
+ }
60
+ else {
61
+ let level = computeLevel(nodeLevel);
62
+ let validatedLevel = addIndentation(nodeLevel === 3 ? 5 : level, obj[x]);
63
+ depTree.push(validatedLevel);
64
+ }
65
+ }
66
+ return depTree;
67
+ };
68
+ const shaveOutput = gradleDependencyTreeOutput => {
69
+ let shavedOutput = gradleDependencyTreeOutput.split('\n');
70
+ if (projectType === 'Maven') {
71
+ shavedOutput = preParser(shavedOutput);
72
+ }
73
+ let obj = [];
74
+ for (let key in shavedOutput) {
75
+ if (shavedOutput[key].includes('project :')) {
76
+ }
77
+ else if (shavedOutput[key].includes('+---') ||
78
+ shavedOutput[key].includes('\\---')) {
79
+ obj.push(shavedOutput[key]);
80
+ }
81
+ }
82
+ return obj;
83
+ };
84
+ const computeIndentation = element => {
85
+ let hasPlus = element.includes('+');
86
+ let hasSlash = element.includes('\\');
87
+ if (hasPlus) {
88
+ return element.substring(element.indexOf('+'));
89
+ }
90
+ if (hasSlash) {
91
+ return element.substring(element.indexOf('\\'));
92
+ }
93
+ };
94
+ const computeLevel = nodeLevel => {
95
+ let num = [5, 8, 11, 14, 17, 20];
96
+ for (let z in num) {
97
+ if (num[z] === nodeLevel) {
98
+ let n = parseInt(z);
99
+ return 5 * (n + 2);
100
+ }
101
+ }
102
+ };
103
+ const addIndentation = (number, str) => {
104
+ str = computeIndentation(str);
105
+ sb.clear();
106
+ for (let j = 0; j < number; j++) {
107
+ sb.append(' ');
108
+ }
109
+ sb.append(str);
110
+ return sb.toString();
111
+ };
112
+ const computeRelationToLastElement = element => {
113
+ let hasPlus = element.includes('+---');
114
+ let hasSlash = element.includes('\\---');
115
+ if (hasPlus) {
116
+ return element.split('+---')[0].length;
117
+ }
118
+ if (hasSlash) {
119
+ return element.split('\\---')[0].length;
120
+ }
121
+ };
122
+ const stripElement = element => {
123
+ return element
124
+ .replace(/[|]/g, '')
125
+ .replace('+---', '')
126
+ .replace('\\---', '')
127
+ .replace(/[' ']/g, '')
128
+ .replace('(c)', '')
129
+ .replace('->', '@')
130
+ .replace('(*)', '');
131
+ };
132
+ const checkVersion = element => {
133
+ let version = element.split(':');
134
+ return version[version.length - 1];
135
+ };
136
+ const createElement = (element, isRoot) => {
137
+ let tree;
138
+ let cleanElement = stripElement(element);
139
+ let splitGroupName = cleanElement.split(':');
140
+ let validateVersion = false;
141
+ if (!element.includes('->')) {
142
+ validateVersion = true;
143
+ }
144
+ tree = {
145
+ artifactID: splitGroupName[1],
146
+ group: splitGroupName[0],
147
+ version: validateVersion
148
+ ? checkVersion(cleanElement)
149
+ : splitGroupName[splitGroupName.length - 1],
150
+ scope: 'compile',
151
+ type: isRoot ? 'direct' : 'transitive',
152
+ edges: {}
153
+ };
154
+ return tree;
155
+ };
156
+ const getElementHeader = element => {
157
+ let elementHeader = stripElement(element);
158
+ elementHeader = elementHeader.replace(':', '/');
159
+ elementHeader = elementHeader.replace(':', '@');
160
+ return elementHeader;
161
+ };
162
+ const buildElement = (element, rootElement, parentOfCurrent, tree, isRoot) => {
163
+ let childElement = createElement(element, isRoot);
164
+ let elementHeader = getElementHeader(element);
165
+ let levelsArray = [rootElement, parentOfCurrent];
166
+ const treeNode = getNestedObject(tree, levelsArray);
167
+ const rootNode = getNestedObject(tree, [rootElement]);
168
+ if (!rootNode.hasOwnProperty(elementHeader)) {
169
+ tree[rootElement][elementHeader] = childElement;
170
+ }
171
+ treeNode.edges[elementHeader] = elementHeader;
172
+ };
173
+ const hasChildren = (nextNodeLevel, nodeLevel) => {
174
+ if (nextNodeLevel > nodeLevel) {
175
+ return true;
176
+ }
177
+ };
178
+ const lastChild = (nextNodeLevel, nodeLevel) => {
179
+ if (nextNodeLevel < nodeLevel) {
180
+ return true;
181
+ }
182
+ };
183
+ const calculateLevels = (nextNodeLevel, nodeLevel) => {
184
+ return (nodeLevel - nextNodeLevel) / 5;
185
+ };
186
+ const buildTree = shavedOutput => {
187
+ let tree = {};
188
+ let rootElement;
189
+ let levelNodes = [];
190
+ shavedOutput.forEach((element, index) => {
191
+ if (index === 0) {
192
+ let cleanElement = stripElement(element);
193
+ let elementHeader = getElementHeader(cleanElement);
194
+ let splitElement = element.split(' ');
195
+ let splitGroupName = splitElement[1].split(':');
196
+ let validateVersion = false;
197
+ if (!element.includes('->')) {
198
+ validateVersion = true;
199
+ }
200
+ tree[splitGroupName[0]] = {};
201
+ tree[splitGroupName[0]][elementHeader] = {
202
+ artifactID: splitGroupName[1],
203
+ group: splitGroupName[0],
204
+ version: validateVersion
205
+ ? checkVersion(cleanElement)
206
+ : splitElement[splitElement.length - 1],
207
+ scope: 'compile',
208
+ type: 'direct',
209
+ edges: {}
210
+ };
211
+ rootElement = splitGroupName[0];
212
+ levelNodes.push(elementHeader);
213
+ }
214
+ if (shavedOutput.length - 1 === index) {
215
+ const parentOfCurrent = levelNodes[levelNodes.length - 1];
216
+ let nodeLevel = computeRelationToLastElement(element);
217
+ let validateVersion = false;
218
+ if (!element.includes('->')) {
219
+ validateVersion = true;
220
+ }
221
+ if (nodeLevel === 0) {
222
+ let cleanElement = stripElement(element);
223
+ let elementHeader = getElementHeader(cleanElement);
224
+ let splitElement = element.split(' ');
225
+ let splitGroupName = splitElement[1].split(':');
226
+ tree[rootElement][elementHeader] = {
227
+ artifactID: splitGroupName[1],
228
+ group: splitGroupName[0],
229
+ version: validateVersion
230
+ ? checkVersion(cleanElement)
231
+ : splitElement[splitElement.length - 1],
232
+ scope: 'compile',
233
+ type: 'direct',
234
+ edges: {}
235
+ };
236
+ }
237
+ else {
238
+ buildElement(element, rootElement, parentOfCurrent, tree);
239
+ }
240
+ }
241
+ if (index >= 1 && index < shavedOutput.length - 1) {
242
+ let nodeLevel = computeRelationToLastElement(element);
243
+ let nextNodeLevel = computeRelationToLastElement(shavedOutput[index + 1]);
244
+ const parentOfCurrent = levelNodes[levelNodes.length - 1];
245
+ let isRoot = false;
246
+ if (nodeLevel === 0) {
247
+ isRoot = true;
248
+ }
249
+ if (isRoot) {
250
+ let cleanElement = stripElement(element);
251
+ let elementHeader = getElementHeader(cleanElement);
252
+ let splitElement = element.split(' ');
253
+ let splitGroupName = splitElement[1].split(':');
254
+ let validateVersion = false;
255
+ if (!element.includes('->')) {
256
+ validateVersion = true;
257
+ }
258
+ tree[rootElement][elementHeader] = {
259
+ artifactID: splitGroupName[1],
260
+ group: splitGroupName[0],
261
+ version: validateVersion
262
+ ? checkVersion(cleanElement)
263
+ : splitElement[splitElement.length - 1],
264
+ scope: 'compile',
265
+ type: 'direct',
266
+ edges: {}
267
+ };
268
+ levelNodes.push(elementHeader);
269
+ return;
270
+ }
271
+ let elementHeader = getElementHeader(element);
272
+ buildElement(element, rootElement, parentOfCurrent, tree, isRoot);
273
+ if (hasChildren(nextNodeLevel, nodeLevel)) {
274
+ buildElement(element, rootElement, parentOfCurrent, tree, isRoot);
275
+ levelNodes.push(elementHeader);
276
+ }
277
+ if (lastChild(nextNodeLevel, nodeLevel)) {
278
+ let levelDifference = calculateLevels(nextNodeLevel, nodeLevel);
279
+ if (levelDifference === 0) {
280
+ levelNodes.pop();
281
+ }
282
+ else {
283
+ let i;
284
+ for (i = 0; i < levelDifference; i++) {
285
+ levelNodes.pop();
286
+ }
287
+ }
288
+ }
289
+ }
290
+ });
291
+ return tree;
292
+ };
293
+ const getNestedObject = (nestedObj, pathArr) => {
294
+ return pathArr.reduce((obj, key) => (obj && obj[key] !== 'undefined' ? obj[key] : undefined), nestedObj);
295
+ };
296
+ const parseSubProject = shavedOutput => {
297
+ let obj = [];
298
+ for (let key in shavedOutput) {
299
+ if (!shavedOutput[key].includes('project')) {
300
+ obj.push(shavedOutput[key]);
301
+ }
302
+ }
303
+ return obj;
304
+ };
305
+ const validateIndentation = shavedOutput => {
306
+ let validatedTree = [];
307
+ shavedOutput.forEach((element, index) => {
308
+ let nextNodeLevel;
309
+ let nodeLevel = computeRelationToLastElement(element);
310
+ if (shavedOutput[index + 1] !== undefined) {
311
+ nextNodeLevel = computeRelationToLastElement(shavedOutput[index + 1]);
312
+ }
313
+ if (index === 0) {
314
+ validatedTree.push(shavedOutput[index]);
315
+ validatedTree.push(shavedOutput[index + 1]);
316
+ }
317
+ else if (nextNodeLevel > nodeLevel + 5) {
318
+ return;
319
+ }
320
+ else {
321
+ validatedTree.push(shavedOutput[index + 1]);
322
+ }
323
+ });
324
+ validatedTree.pop();
325
+ return validatedTree;
326
+ };
327
+ const parseGradle = (gradleDependencyTreeOutput, config) => {
328
+ let shavedOutput = shaveOutput(gradleDependencyTreeOutput);
329
+ if (config.subProject) {
330
+ let subProject = parseSubProject(shavedOutput);
331
+ let validatedOutput = validateIndentation(subProject);
332
+ return buildTree(validatedOutput);
333
+ }
334
+ else {
335
+ let validatedOutput = validateIndentation(shavedOutput);
336
+ return buildTree(validatedOutput);
337
+ }
338
+ };
339
+ exports.shaveOutput = shaveOutput;
340
+ exports.validateIndentation = validateIndentation;
341
+ exports.stripElement = stripElement;
342
+ exports.getElementHeader = getElementHeader;
343
+ exports.createElement = createElement;
344
+ exports.parseGradle = parseGradle;
345
+ exports.computeRelationToLastElement = computeRelationToLastElement;
346
+ exports.hasChildren = hasChildren;
347
+ exports.lastChild = lastChild;
348
+ exports.calculateLevels = calculateLevels;
349
+ exports.buildElement = buildElement;
350
+ exports.checkVersion = checkVersion;
351
+ exports.computeIndentation = computeIndentation;
352
+ exports.computeLevel = computeLevel;
353
+ exports.addIndentation = addIndentation;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ const child_process = require('child_process');
3
+ const fs = require('fs');
4
+ const i18n = require('i18n');
5
+ const path = require('path');
6
+ module.exports = exports = ({ language: { projectFilePath }, java }, next, config) => {
7
+ let cmdStdout;
8
+ let cwd;
9
+ let timeout;
10
+ let javaProject = '';
11
+ let mvn_settings = '';
12
+ const maven = 'Maven';
13
+ const gradle = 'Gradle';
14
+ try {
15
+ if (projectFilePath.includes('pom.xml')) {
16
+ javaProject = maven;
17
+ cwd = projectFilePath.replace('pom.xml', '');
18
+ }
19
+ else if (projectFilePath.includes('build.gradle')) {
20
+ javaProject = gradle;
21
+ cwd = projectFilePath.replace('build.gradle', '');
22
+ }
23
+ timeout = 960000;
24
+ if (javaProject === maven) {
25
+ if (config.mavenSettingsPath) {
26
+ mvn_settings = ' -s ' + config.mavenSettingsPath;
27
+ }
28
+ if (config.betaUnifiedJavaParser) {
29
+ cmdStdout = child_process.execSync('mvn dependency:tree -B' + mvn_settings, {
30
+ cwd,
31
+ timeout
32
+ });
33
+ }
34
+ else {
35
+ cmdStdout = child_process.execSync('mvn dependency:tree -DoutputType=dot -B' + mvn_settings, {
36
+ cwd,
37
+ timeout
38
+ });
39
+ }
40
+ java.mvnDependancyTreeOutput = cmdStdout.toString();
41
+ }
42
+ else if (javaProject === gradle) {
43
+ if (config.subProject) {
44
+ cmdStdout = child_process.execSync('.' +
45
+ path.sep +
46
+ 'gradlew :' +
47
+ config.subProject +
48
+ ':dependencies --configuration runtimeClasspath', {
49
+ cwd,
50
+ timeout
51
+ });
52
+ }
53
+ else {
54
+ cmdStdout = child_process.execSync('.' +
55
+ path.sep +
56
+ 'gradlew dependencies --configuration runtimeClasspath', {
57
+ cwd,
58
+ timeout
59
+ });
60
+ }
61
+ if (cmdStdout
62
+ .toString()
63
+ .includes("runtimeClasspath - Runtime classpath of source set 'main'.\n" +
64
+ 'No dependencies')) {
65
+ cmdStdout = child_process.execSync('.' + path.sep + 'gradlew dependencies', {
66
+ cwd,
67
+ timeout
68
+ });
69
+ }
70
+ java.mvnDependancyTreeOutput = cmdStdout.toString();
71
+ }
72
+ next();
73
+ }
74
+ catch (err) {
75
+ if (javaProject === maven) {
76
+ try {
77
+ child_process.execSync('mvn --version', {
78
+ cwd,
79
+ timeout
80
+ });
81
+ next(new Error(i18n.__('mavenDependencyTreeNonZero', cwd, `${err.message}`)));
82
+ }
83
+ catch (mvnErr) {
84
+ next(new Error(i18n.__('mavenNotInstalledError', cwd, `${mvnErr.message}`)));
85
+ }
86
+ }
87
+ else if (javaProject === gradle) {
88
+ if (fs.existsSync(cwd + 'gradlew') ||
89
+ fs.existsSync(cwd + 'gradlew.bat')) {
90
+ next(new Error(i18n.__('gradleDependencyTreeNonZero', cwd, `${err.message}`)));
91
+ }
92
+ else {
93
+ next(new Error(i18n.__('gradleWrapperUnavailable', cwd, `${err.message}`)));
94
+ }
95
+ }
96
+ return;
97
+ }
98
+ };
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ module.exports = exports = ({ java }, next) => {
3
+ delete java.mvnDependancyTreeOutput;
4
+ next();
5
+ };
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ const i18n = require('i18n');
3
+ module.exports = exports = (analysis, next) => {
4
+ const { languageAnalysis } = analysis;
5
+ try {
6
+ checkForMultipleIdentifiedLanguages(languageAnalysis.identifiedLanguages);
7
+ }
8
+ catch (err) {
9
+ next(err);
10
+ return;
11
+ }
12
+ next();
13
+ };
14
+ const checkForMultipleIdentifiedLanguages = identifiedLanguages => {
15
+ if (Object.keys(identifiedLanguages).length > 1) {
16
+ let errMsg = i18n.__('languageAnalysisMultipleLanguages1');
17
+ for (const [language, { projectFilenames }] of Object.entries(identifiedLanguages)) {
18
+ errMsg += `\t${language}: ${projectFilenames.join(', ')}\n`;
19
+ }
20
+ errMsg += i18n.__('languageAnalysisMultipleLanguages2', "'project_path'");
21
+ throw new Error(errMsg);
22
+ }
23
+ };
24
+ exports.checkForMultipleIdentifiedLanguages = checkForMultipleIdentifiedLanguages;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ const i18n = require('i18n');
3
+ module.exports = exports = (analysis, next) => {
4
+ const { languageAnalysis } = analysis;
5
+ try {
6
+ checkForMultipleIdentifiedProjectFiles(languageAnalysis.identifiedLanguages);
7
+ }
8
+ catch (err) {
9
+ next(err);
10
+ return;
11
+ }
12
+ next();
13
+ };
14
+ const checkForMultipleIdentifiedProjectFiles = identifiedLanguages => {
15
+ if (Object.keys(identifiedLanguages).length == 1) {
16
+ let { projectFilenames } = Object.values(identifiedLanguages)[0];
17
+ if (projectFilenames.length > 1) {
18
+ const [language] = Object.keys(identifiedLanguages);
19
+ projectFilenames = projectFilenames.join(', ');
20
+ throw new Error(i18n.__('languageAnalysisProjectFiles', language, projectFilenames, "'project_path'"));
21
+ }
22
+ }
23
+ };
24
+ exports.checkForMultipleIdentifiedProjectFiles = checkForMultipleIdentifiedProjectFiles;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ const i18n = require('i18n');
3
+ module.exports = exports = (analysis, next) => {
4
+ try {
5
+ const { languageAnalysis } = analysis;
6
+ if (Object.getOwnPropertyNames(languageAnalysis.identifiedLanguages)[0] ===
7
+ 'JAVA' ||
8
+ Object.getOwnPropertyNames(languageAnalysis.identifiedLanguages)[0] ===
9
+ 'GO') {
10
+ next();
11
+ return;
12
+ }
13
+ checkForLockFile(languageAnalysis.identifiedLanguages);
14
+ }
15
+ catch (err) {
16
+ next(err);
17
+ return;
18
+ }
19
+ next();
20
+ return;
21
+ };
22
+ const checkForLockFile = identifiedLanguages => {
23
+ if (Object.keys(identifiedLanguages).length == 1) {
24
+ let { lockFilenames } = Object.values(identifiedLanguages)[0];
25
+ if (lockFilenames.length == 0) {
26
+ const [language] = Object.keys(identifiedLanguages);
27
+ throw new Error(i18n.__('languageAnalysisHasNoLockFile', language));
28
+ }
29
+ if (lockFilenames.length > 1) {
30
+ const [language] = Object.keys(identifiedLanguages);
31
+ throw new Error(i18n.__('languageAnalysisHasMultipleLockFiles', language, String(lockFilenames)));
32
+ }
33
+ }
34
+ };
35
+ exports.checkForLockFile = checkForLockFile;