@trustify-da/trustify-da-javascript-client 0.2.4-ea.13
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/LICENSE +201 -0
- package/README.md +482 -0
- package/config/config.properties +1 -0
- package/dist/package.json +106 -0
- package/dist/src/analysis.d.ts +43 -0
- package/dist/src/analysis.js +252 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +102 -0
- package/dist/src/cyclone_dx_sbom.d.ts +77 -0
- package/dist/src/cyclone_dx_sbom.js +244 -0
- package/dist/src/index.d.ts +82 -0
- package/dist/src/index.js +194 -0
- package/dist/src/oci_image/images.d.ts +99 -0
- package/dist/src/oci_image/images.js +263 -0
- package/dist/src/oci_image/platform.d.ts +59 -0
- package/dist/src/oci_image/platform.js +138 -0
- package/dist/src/oci_image/utils.d.ts +42 -0
- package/dist/src/oci_image/utils.js +496 -0
- package/dist/src/provider.d.ts +29 -0
- package/dist/src/provider.js +47 -0
- package/dist/src/providers/base_java.d.ts +85 -0
- package/dist/src/providers/base_java.js +191 -0
- package/dist/src/providers/base_javascript.d.ts +127 -0
- package/dist/src/providers/base_javascript.js +350 -0
- package/dist/src/providers/golang_gomodules.d.ts +42 -0
- package/dist/src/providers/golang_gomodules.js +403 -0
- package/dist/src/providers/java_gradle.d.ts +35 -0
- package/dist/src/providers/java_gradle.js +399 -0
- package/dist/src/providers/java_gradle_groovy.d.ts +7 -0
- package/dist/src/providers/java_gradle_groovy.js +19 -0
- package/dist/src/providers/java_gradle_kotlin.d.ts +11 -0
- package/dist/src/providers/java_gradle_kotlin.js +23 -0
- package/dist/src/providers/java_maven.d.ts +52 -0
- package/dist/src/providers/java_maven.js +263 -0
- package/dist/src/providers/javascript_npm.d.ts +4 -0
- package/dist/src/providers/javascript_npm.js +15 -0
- package/dist/src/providers/javascript_pnpm.d.ts +5 -0
- package/dist/src/providers/javascript_pnpm.js +22 -0
- package/dist/src/providers/javascript_yarn.d.ts +11 -0
- package/dist/src/providers/javascript_yarn.js +39 -0
- package/dist/src/providers/manifest.d.ts +11 -0
- package/dist/src/providers/manifest.js +48 -0
- package/dist/src/providers/processors/yarn_berry_processor.d.ts +41 -0
- package/dist/src/providers/processors/yarn_berry_processor.js +130 -0
- package/dist/src/providers/processors/yarn_classic_processor.d.ts +37 -0
- package/dist/src/providers/processors/yarn_classic_processor.js +109 -0
- package/dist/src/providers/processors/yarn_processor.d.ts +9 -0
- package/dist/src/providers/processors/yarn_processor.js +20 -0
- package/dist/src/providers/python_controller.d.ts +31 -0
- package/dist/src/providers/python_controller.js +406 -0
- package/dist/src/providers/python_pip.d.ts +35 -0
- package/dist/src/providers/python_pip.js +227 -0
- package/dist/src/sbom.d.ts +59 -0
- package/dist/src/sbom.js +84 -0
- package/dist/src/tools.d.ts +74 -0
- package/dist/src/tools.js +159 -0
- package/package.json +106 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { EOL } from 'os';
|
|
4
|
+
import TOML from 'fast-toml';
|
|
5
|
+
import Sbom from '../sbom.js';
|
|
6
|
+
import Base_java, { ecosystem_gradle } from "./base_java.js";
|
|
7
|
+
/** @typedef {import('../provider.js').Provider} */
|
|
8
|
+
/** @typedef {import('../provider.js').Provided} Provided */
|
|
9
|
+
const ROOT_PROJECT_KEY_NAME = "root-project";
|
|
10
|
+
const TRUSTIFY_DA_IGNORE_REGEX_LINE = /.*\s?exhortignore\s*$/g;
|
|
11
|
+
const TRUSTIFY_DA_IGNORE_REGEX = /\/\/\s?exhortignore/;
|
|
12
|
+
/**
|
|
13
|
+
* Check if the dependency marked for exclusion has libs notation , so if it's true the rest of coordinates( GAV) should be fetched from TOML file.
|
|
14
|
+
* @param {string} depToBeIgnored
|
|
15
|
+
* @return {boolean} returns if the dependency type has library notation or not
|
|
16
|
+
*/
|
|
17
|
+
function depHasLibsNotation(depToBeIgnored) {
|
|
18
|
+
const regex = new RegExp(":", "g");
|
|
19
|
+
return (depToBeIgnored.trim().startsWith("library(") || depToBeIgnored.trim().includes("libs."))
|
|
20
|
+
&& (depToBeIgnored.match(regex) || []).length <= 1;
|
|
21
|
+
}
|
|
22
|
+
function stripString(depPart) {
|
|
23
|
+
return depPart.replaceAll(/["']/g, "");
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* This class provides common functionality for Groovy and Kotlin DSL files.
|
|
27
|
+
*/
|
|
28
|
+
export default class Java_gradle extends Base_java {
|
|
29
|
+
constructor() {
|
|
30
|
+
super('gradle', 'gradlew' + (process.platform === 'win32' ? '.bat' : ''));
|
|
31
|
+
}
|
|
32
|
+
_getManifestName() {
|
|
33
|
+
throw new Error('implement getManifestName method');
|
|
34
|
+
}
|
|
35
|
+
_parseAliasForLibsNotation() {
|
|
36
|
+
throw new Error('implement parseAliasForLibsNotation method');
|
|
37
|
+
}
|
|
38
|
+
_extractDepToBeIgnored() {
|
|
39
|
+
throw new Error('implement extractDepToBeIgnored method');
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @param {string} manifestName - the subject manifest name-type
|
|
43
|
+
* @returns {boolean} - return true if the manifest name-type is the supported type (example build.gradle)
|
|
44
|
+
*/
|
|
45
|
+
isSupported(manifestName) {
|
|
46
|
+
return this._getManifestName() === manifestName;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @param {string} manifestDir - the directory where the manifest lies
|
|
50
|
+
*/
|
|
51
|
+
validateLockFile() { return true; }
|
|
52
|
+
/**
|
|
53
|
+
* Provide content and content type for stack analysis.
|
|
54
|
+
* @param {string} manifest - the manifest path or name
|
|
55
|
+
* @param {{}} [opts={}] - optional various options to pass along the application
|
|
56
|
+
* @returns {Provided}
|
|
57
|
+
*/
|
|
58
|
+
provideStack(manifest, opts = {}) {
|
|
59
|
+
return {
|
|
60
|
+
ecosystem: ecosystem_gradle,
|
|
61
|
+
content: this.#createSbomStackAnalysis(manifest, opts),
|
|
62
|
+
contentType: 'application/vnd.cyclonedx+json'
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Provide content and content type for maven-maven component analysis.
|
|
67
|
+
* @param {string} manifest - path to pom.xml for component report
|
|
68
|
+
* @param {{}} [opts={}] - optional various options to pass along the application
|
|
69
|
+
* @returns {Provided}
|
|
70
|
+
*/
|
|
71
|
+
provideComponent(manifest, opts = {}) {
|
|
72
|
+
return {
|
|
73
|
+
ecosystem: ecosystem_gradle,
|
|
74
|
+
content: this.#getSbomForComponentAnalysis(manifest, opts),
|
|
75
|
+
contentType: 'application/vnd.cyclonedx+json'
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* @param {string} line - the line to parse
|
|
80
|
+
* @returns {number} the depth of the dependency in the tree starting from 1. -1 if the line is not a dependency.
|
|
81
|
+
* @private
|
|
82
|
+
*/
|
|
83
|
+
#getIndentationLevel(line) {
|
|
84
|
+
// If it is level 1
|
|
85
|
+
let match = line.match(/^[\\+-]/);
|
|
86
|
+
if (match) {
|
|
87
|
+
return 1;
|
|
88
|
+
}
|
|
89
|
+
// Count the groups of 4 spaces preceded by a pipe or 5 spaces
|
|
90
|
+
match = line.match(/\| {4}| {5}/g);
|
|
91
|
+
if (!match) {
|
|
92
|
+
return -1;
|
|
93
|
+
}
|
|
94
|
+
return match.length + 1;
|
|
95
|
+
}
|
|
96
|
+
#prepareLinesForParsingDependencyTree(lines) {
|
|
97
|
+
return lines
|
|
98
|
+
.filter(dep => dep.trim() !== "" && !dep.endsWith(" FAILED"))
|
|
99
|
+
.map(dependency => {
|
|
100
|
+
// Calculate depth from original line
|
|
101
|
+
const depth = this.#getIndentationLevel(dependency);
|
|
102
|
+
// Now process the dependency line
|
|
103
|
+
let processedLine = dependency.replaceAll("|", "");
|
|
104
|
+
processedLine = processedLine.replaceAll(/\\---|\+---/g, "");
|
|
105
|
+
processedLine = processedLine.replaceAll(/:(.*):(.*) -> (.*)$/g, ":$1:$3");
|
|
106
|
+
processedLine = processedLine.replaceAll(/:(.*)\W*->\W*(.*)$/g, ":$1:$2");
|
|
107
|
+
processedLine = processedLine.replaceAll(/(.*):(.*):(.*)$/g, "$1:$2:jar:$3");
|
|
108
|
+
processedLine = processedLine.replaceAll(/(n)$/g, "");
|
|
109
|
+
processedLine = processedLine.replace(/\s*\(\*\)$/, '').trim();
|
|
110
|
+
// Return both the processed line and its depth
|
|
111
|
+
return {
|
|
112
|
+
line: `${processedLine}:compile`,
|
|
113
|
+
depth: depth
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Process the dependency tree and add dependencies to the SBOM
|
|
119
|
+
* @param {string[]} config - the configuration lines to process
|
|
120
|
+
* @param {Object} parentPurl - the parent package URL
|
|
121
|
+
* @param {Sbom} sbom - the SBOM object to add dependencies to
|
|
122
|
+
* @param {Set} processedDeps - set of already processed dependencies
|
|
123
|
+
* @param {string} scope - the dependency scope
|
|
124
|
+
* @private
|
|
125
|
+
*/
|
|
126
|
+
#processDependencyTree(config, parentPurl, sbom, processedDeps, scope) {
|
|
127
|
+
const processedLines = this.#prepareLinesForParsingDependencyTree(config);
|
|
128
|
+
let parentStack = [parentPurl];
|
|
129
|
+
for (const { line, depth } of processedLines) {
|
|
130
|
+
if (line) {
|
|
131
|
+
const lastDepth = parentStack.length - 1;
|
|
132
|
+
if (depth <= lastDepth) {
|
|
133
|
+
// Going up - pop parents until we reach the correct level
|
|
134
|
+
parentStack = parentStack.slice(0, depth);
|
|
135
|
+
}
|
|
136
|
+
const currentParent = parentStack[depth - 1];
|
|
137
|
+
const purl = this.parseDep(line);
|
|
138
|
+
purl.scope = scope;
|
|
139
|
+
// Create a unique key for this dependency
|
|
140
|
+
const depKey = `${currentParent.namespace}:${currentParent.name}:${currentParent.version}->${purl.namespace}:${purl.name}:${purl.version}`;
|
|
141
|
+
// Add dependency to SBOM if not already processed
|
|
142
|
+
if (!processedDeps.has(depKey)) {
|
|
143
|
+
processedDeps.add(depKey);
|
|
144
|
+
sbom.addDependency(currentParent, purl, scope);
|
|
145
|
+
}
|
|
146
|
+
parentStack.push(purl);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create a Dot Graph dependency tree for a manifest path.
|
|
152
|
+
* @param {string} manifest - path for pom.xml
|
|
153
|
+
* @param {{}} [opts={}] - optional various options to pass along the application
|
|
154
|
+
* @returns {string} the Dot Graph content
|
|
155
|
+
* @private
|
|
156
|
+
*/
|
|
157
|
+
#buildSbom(content, properties, manifestPath, opts = {}) {
|
|
158
|
+
let sbom = new Sbom();
|
|
159
|
+
let root = `${properties.group}:${properties[ROOT_PROJECT_KEY_NAME].match(/Root project '(.+)'/)[1]}:jar:${properties.version}`;
|
|
160
|
+
let rootPurl = this.parseDep(root);
|
|
161
|
+
sbom.addRoot(rootPurl);
|
|
162
|
+
let ignoredDeps = this.#getIgnoredDeps(manifestPath);
|
|
163
|
+
const [runtimeConfig, compileConfig] = this.#extractConfigurations(content);
|
|
164
|
+
const processedDeps = new Set();
|
|
165
|
+
this.#processDependencyTree(runtimeConfig, rootPurl, sbom, processedDeps, 'required');
|
|
166
|
+
this.#processDependencyTree(compileConfig, rootPurl, sbom, processedDeps, 'optional');
|
|
167
|
+
return sbom.filterIgnoredDepsIncludingVersion(ignoredDeps).getAsJsonString(opts);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Create a Dot Graph dependency tree for a manifest path.
|
|
171
|
+
* @param {string} manifest - path for pom.xml
|
|
172
|
+
* @param {{}} [opts={}] - optional various options to pass along the application
|
|
173
|
+
* @returns {string} the Dot Graph content
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
#createSbomStackAnalysis(manifest, opts = {}) {
|
|
177
|
+
let content = this.#getDependencies(manifest, opts);
|
|
178
|
+
let properties = this.#extractProperties(manifest, opts);
|
|
179
|
+
// read dependency tree from temp file
|
|
180
|
+
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
|
|
181
|
+
console.log("Dependency tree that will be used as input for creating the BOM =>" + EOL + EOL + content);
|
|
182
|
+
}
|
|
183
|
+
let sbom = this.#buildSbom(content, properties, manifest, opts);
|
|
184
|
+
return sbom;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
*
|
|
188
|
+
* @param {string} manifestPath - path to build.gradle.
|
|
189
|
+
* @param {Object} opts - contains various options settings from client.
|
|
190
|
+
* @return {{Object}} an object that contains all gradle properties
|
|
191
|
+
*/
|
|
192
|
+
#extractProperties(manifestPath, opts) {
|
|
193
|
+
let properties = {};
|
|
194
|
+
let propertiesContent = this.#getProperties(manifestPath, opts);
|
|
195
|
+
let regExpMatchArray = propertiesContent.match(/([^:]+):\s+(.+)/g);
|
|
196
|
+
for (let i = 0; i < regExpMatchArray.length - 1; i++) {
|
|
197
|
+
let parts = regExpMatchArray[i].split(":");
|
|
198
|
+
properties[parts[0].trim()] = parts[1].trim();
|
|
199
|
+
}
|
|
200
|
+
let regExpMatchArray1 = propertiesContent.match(/Root project '(.+)'/);
|
|
201
|
+
if (regExpMatchArray1[0]) {
|
|
202
|
+
properties[ROOT_PROJECT_KEY_NAME] = regExpMatchArray1[0];
|
|
203
|
+
}
|
|
204
|
+
return properties;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
*
|
|
208
|
+
* @param manifestPath - path to build.gradle
|
|
209
|
+
* @param {Object} opts - contains various options settings from client.
|
|
210
|
+
* @return {string} string content of the properties
|
|
211
|
+
*/
|
|
212
|
+
#getProperties(manifestPath, opts) {
|
|
213
|
+
let gradle = this.selectToolBinary(manifestPath, opts);
|
|
214
|
+
try {
|
|
215
|
+
let properties = this._invokeCommand(gradle, ['properties'], { cwd: path.dirname(manifestPath) });
|
|
216
|
+
return properties.toString();
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
throw new Error(`Couldn't get properties of ${this._getManifestName()} file , Error message returned from gradle binary => ${EOL} ${error.message}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Create a dependency list for a manifest content.
|
|
224
|
+
* @param {{}} [opts={}] - optional various options to pass along the application
|
|
225
|
+
* @returns {string} - sbom string of the direct dependencies of build.gradle
|
|
226
|
+
* @private
|
|
227
|
+
*/
|
|
228
|
+
#getSbomForComponentAnalysis(manifestPath, opts = {}) {
|
|
229
|
+
let content = this.#getDependencies(manifestPath, opts);
|
|
230
|
+
let properties = this.#extractProperties(manifestPath, opts);
|
|
231
|
+
let sbom = this.#buildDirectDependenciesSbom(content, properties, manifestPath, opts);
|
|
232
|
+
return sbom;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get a list of dependencies from gradle dependencies command.
|
|
236
|
+
* @param {string} manifest - path for build.gradle
|
|
237
|
+
* @returns {string} Multi-line string contain all dependencies from gradle dependencies command
|
|
238
|
+
* @private
|
|
239
|
+
*/
|
|
240
|
+
#getDependencies(manifest, opts = {}) {
|
|
241
|
+
const gradle = this.selectToolBinary(manifest, opts);
|
|
242
|
+
try {
|
|
243
|
+
const commandResult = this._invokeCommand(gradle, ['dependencies'], { cwd: path.dirname(manifest) });
|
|
244
|
+
return commandResult.toString();
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
throw new Error(`Couldn't run gradle dependencies command, error message returned from gradle binary => ${EOL} ${error.message}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Extracts runtime and compile configurations from the dependency tree
|
|
252
|
+
* @param {string} content - the dependency tree content
|
|
253
|
+
* @returns {[string[], string[]]} tuple of [runtimeConfig, compileConfig]
|
|
254
|
+
* @private
|
|
255
|
+
*/
|
|
256
|
+
#extractConfigurations(content) {
|
|
257
|
+
const lines = content.split(EOL);
|
|
258
|
+
const configs = {
|
|
259
|
+
runtimeClasspath: [],
|
|
260
|
+
compileClasspath: []
|
|
261
|
+
};
|
|
262
|
+
let currentConfig = null;
|
|
263
|
+
let collecting = false;
|
|
264
|
+
for (const line of lines) {
|
|
265
|
+
// Check for configuration start
|
|
266
|
+
if (line.startsWith('runtimeClasspath')) {
|
|
267
|
+
currentConfig = 'runtimeClasspath';
|
|
268
|
+
collecting = true;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
else if (line.startsWith('compileClasspath')) {
|
|
272
|
+
currentConfig = 'compileClasspath';
|
|
273
|
+
collecting = true;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
// If we're not collecting or no config is set, skip
|
|
277
|
+
if (!collecting || !currentConfig) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
// Check for end of configuration
|
|
281
|
+
if (line.trim() === '') {
|
|
282
|
+
collecting = false;
|
|
283
|
+
currentConfig = null;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
// Add line to current configuration
|
|
287
|
+
configs[currentConfig].push(line);
|
|
288
|
+
}
|
|
289
|
+
return [configs.runtimeClasspath, configs.compileClasspath];
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
*
|
|
293
|
+
* @param content {string} - content of the dependency tree received from gradle dependencies command
|
|
294
|
+
* @param properties {Object} - properties of the gradle project.
|
|
295
|
+
* @return {string} return sbom json string of the build.gradle manifest file
|
|
296
|
+
*/
|
|
297
|
+
#buildDirectDependenciesSbom(content, properties, manifestPath, opts = {}) {
|
|
298
|
+
let sbom = new Sbom();
|
|
299
|
+
let root = `${properties.group}:${properties[ROOT_PROJECT_KEY_NAME].match(/Root project '(.+)'/)[1]}:jar:${properties.version}`;
|
|
300
|
+
let rootPurl = this.parseDep(root);
|
|
301
|
+
sbom.addRoot(rootPurl);
|
|
302
|
+
let ignoredDeps = this.#getIgnoredDeps(manifestPath);
|
|
303
|
+
const [runtimeConfig, compileConfig] = this.#extractConfigurations(content);
|
|
304
|
+
let directDependencies = new Map();
|
|
305
|
+
this.#processDirectDependencies(runtimeConfig, directDependencies, 'required');
|
|
306
|
+
this.#processDirectDependencies(compileConfig, directDependencies, 'optional');
|
|
307
|
+
directDependencies.forEach((scope, dep) => {
|
|
308
|
+
const purl = this.parseDep(dep);
|
|
309
|
+
purl.scope = scope;
|
|
310
|
+
sbom.addDependency(rootPurl, purl, scope);
|
|
311
|
+
});
|
|
312
|
+
return sbom.filterIgnoredDepsIncludingVersion(ignoredDeps).getAsJsonString(opts);
|
|
313
|
+
}
|
|
314
|
+
#processDirectDependencies(config, directDependencies, scope) {
|
|
315
|
+
const lines = this.#prepareLinesForParsingDependencyTree(config);
|
|
316
|
+
lines.forEach(({ line, depth }) => {
|
|
317
|
+
if (depth === 1 && !directDependencies.has(line)) {
|
|
318
|
+
directDependencies.set(line, scope);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* This method gets build.gradle manifest, and extracts from it all artifacts marks for exclusion using an //exhortignore comment.
|
|
324
|
+
* @param {string} manifestPath the build.gradle manifest path
|
|
325
|
+
* @return {string[]} an array with all dependencies to ignore - contains 'stringified' purls as elements
|
|
326
|
+
* @private
|
|
327
|
+
*/
|
|
328
|
+
#getIgnoredDeps(manifestPath) {
|
|
329
|
+
let buildGradleLines = fs.readFileSync(manifestPath).toString().split(EOL);
|
|
330
|
+
let ignored = buildGradleLines.filter(line => line && line.match(TRUSTIFY_DA_IGNORE_REGEX_LINE))
|
|
331
|
+
.map(line => line.indexOf("/*") === -1 ? line : line.substring(0, line.indexOf("/*")))
|
|
332
|
+
.map(line => line.trim().substring(0, line.trim().search(TRUSTIFY_DA_IGNORE_REGEX)));
|
|
333
|
+
let depsToIgnore = new Array;
|
|
334
|
+
ignored.forEach(depToBeIgnored => {
|
|
335
|
+
let ignoredDepInfo;
|
|
336
|
+
if (depHasLibsNotation(depToBeIgnored)) {
|
|
337
|
+
ignoredDepInfo = this.#getDepFromLibsNotation(depToBeIgnored, manifestPath);
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
ignoredDepInfo = this.#getDependencyFromStringOrMapNotation(depToBeIgnored);
|
|
341
|
+
}
|
|
342
|
+
if (ignoredDepInfo) {
|
|
343
|
+
depsToIgnore.push(ignoredDepInfo);
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
return depsToIgnore;
|
|
347
|
+
}
|
|
348
|
+
#getDepFromLibsNotation(depToBeIgnored, manifestPath) {
|
|
349
|
+
// Extract everything after "libs."
|
|
350
|
+
let alias = depToBeIgnored.substring(depToBeIgnored.indexOf("libs.") + "libs.".length).trim();
|
|
351
|
+
alias = this._parseAliasForLibsNotation(alias);
|
|
352
|
+
// Read and parse the TOML file
|
|
353
|
+
let pathOfToml = path.join(path.dirname(manifestPath), "gradle", "libs.versions.toml");
|
|
354
|
+
const tomlString = fs.readFileSync(pathOfToml).toString();
|
|
355
|
+
let tomlObject = TOML.parse(tomlString);
|
|
356
|
+
let groupPlusArtifactObject = tomlObject.libraries[alias];
|
|
357
|
+
let parts = groupPlusArtifactObject.module.split(":");
|
|
358
|
+
let groupId = parts[0];
|
|
359
|
+
let artifactId = parts[1];
|
|
360
|
+
let versionRef = groupPlusArtifactObject.version.ref;
|
|
361
|
+
let version = tomlObject.versions[versionRef];
|
|
362
|
+
return groupId && artifactId && version ? this.toPurl(groupId, artifactId, version).toString() : undefined;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Gets a dependency line of type string/map notation from build.gradle, extract the coordinates from it and returns string purl
|
|
366
|
+
* @param depToBeIgnored
|
|
367
|
+
* @return {string|undefined} string of a purl format of the extracted coordinates.
|
|
368
|
+
*/
|
|
369
|
+
#getDependencyFromStringOrMapNotation(depToBeIgnored) {
|
|
370
|
+
// dependency line is of form MapNotation
|
|
371
|
+
if (depToBeIgnored.includes("group:") && depToBeIgnored.includes("name:") && depToBeIgnored.includes("version:")) {
|
|
372
|
+
let matchedKeyValues = depToBeIgnored.match(/(group|name|version):\s*['"](.*?)['"]/g);
|
|
373
|
+
let coordinates = {};
|
|
374
|
+
for (let coordinatePairIndex in matchedKeyValues) {
|
|
375
|
+
let keyValue = matchedKeyValues[coordinatePairIndex].split(":");
|
|
376
|
+
coordinates[keyValue[0].trim()] = stripString(keyValue[1].trim());
|
|
377
|
+
}
|
|
378
|
+
return this.toPurl(coordinates.group, coordinates.name, coordinates.version).toString();
|
|
379
|
+
// Dependency line is of form String Notation
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
let depParts;
|
|
383
|
+
const depToBeIgnoredMatch = this._extractDepToBeIgnored(depToBeIgnored);
|
|
384
|
+
if (depToBeIgnoredMatch) {
|
|
385
|
+
depParts = depToBeIgnoredMatch.split(":");
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
depParts = depToBeIgnored.split(":");
|
|
389
|
+
}
|
|
390
|
+
if (depParts.length === 3) {
|
|
391
|
+
let groupId = stripString(depParts[0]);
|
|
392
|
+
let artifactId = stripString(depParts[1]);
|
|
393
|
+
let version = stripString(depParts[2]);
|
|
394
|
+
return this.toPurl(groupId, artifactId, version).toString();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return undefined;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export default class Java_gradle_groovy extends Java_gradle {
|
|
2
|
+
_getManifestName(): string;
|
|
3
|
+
_parseAliasForLibsNotation(alias: any): any;
|
|
4
|
+
_extractDepToBeIgnored(dep: any): any;
|
|
5
|
+
}
|
|
6
|
+
export type Provided = import('../provider').Provided;
|
|
7
|
+
import Java_gradle from './java_gradle.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Java_gradle from './java_gradle.js';
|
|
2
|
+
/** @typedef {import('../provider').Provider} */
|
|
3
|
+
/** @typedef {import('../provider').Provided} Provided */
|
|
4
|
+
const GROOVY_DEP_REGEX = /^[a-zA-Z]+\s/;
|
|
5
|
+
const GRADLE_GROOVY_FILE = "build.gradle";
|
|
6
|
+
export default class Java_gradle_groovy extends Java_gradle {
|
|
7
|
+
_getManifestName() {
|
|
8
|
+
return GRADLE_GROOVY_FILE;
|
|
9
|
+
}
|
|
10
|
+
_parseAliasForLibsNotation(alias) {
|
|
11
|
+
return alias.replace(".", "-");
|
|
12
|
+
}
|
|
13
|
+
_extractDepToBeIgnored(dep) {
|
|
14
|
+
if (dep.match(GROOVY_DEP_REGEX)) {
|
|
15
|
+
return dep.split(" ")[1];
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export default class Java_gradle_kotlin extends Java_gradle {
|
|
2
|
+
/**
|
|
3
|
+
* @param {string} manifestName - the subject manifest name-type
|
|
4
|
+
* @returns {boolean} - return true if `pom.xml` is the manifest name-type
|
|
5
|
+
*/
|
|
6
|
+
_getManifestName(): boolean;
|
|
7
|
+
_parseAliasForLibsNotation(alias: any): any;
|
|
8
|
+
_extractDepToBeIgnored(dep: any): string | null;
|
|
9
|
+
}
|
|
10
|
+
export type Provided = import('../provider').Provided;
|
|
11
|
+
import Java_gradle from './java_gradle.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import Java_gradle from './java_gradle.js';
|
|
2
|
+
/** @typedef {import('../provider').Provider} */
|
|
3
|
+
/** @typedef {import('../provider').Provided} Provided */
|
|
4
|
+
const KOTLIN_DEP_REGEX = /^[a-zA-Z]+\s?\((.*)\)/;
|
|
5
|
+
const GRADLE_KOTLIN_FILE = "build.gradle.kts";
|
|
6
|
+
export default class Java_gradle_kotlin extends Java_gradle {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} manifestName - the subject manifest name-type
|
|
9
|
+
* @returns {boolean} - return true if `pom.xml` is the manifest name-type
|
|
10
|
+
*/
|
|
11
|
+
_getManifestName() {
|
|
12
|
+
return GRADLE_KOTLIN_FILE;
|
|
13
|
+
}
|
|
14
|
+
_parseAliasForLibsNotation(alias) {
|
|
15
|
+
return alias.replace(".", "-").replace(")", "");
|
|
16
|
+
}
|
|
17
|
+
_extractDepToBeIgnored(dep) {
|
|
18
|
+
if (dep.match(KOTLIN_DEP_REGEX)) {
|
|
19
|
+
return KOTLIN_DEP_REGEX.exec(dep)[1];
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** @typedef {import('../provider').Provider} */
|
|
2
|
+
/** @typedef {import('../provider').Provided} Provided */
|
|
3
|
+
/** @typedef {{name: string, version: string}} Package */
|
|
4
|
+
/** @typedef {{groupId: string, artifactId: string, version: string, scope: string, ignore: boolean}} Dependency */
|
|
5
|
+
export default class Java_maven extends Base_java {
|
|
6
|
+
constructor();
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} manifestName - the subject manifest name-type
|
|
9
|
+
* @returns {boolean} - return true if `pom.xml` is the manifest name-type
|
|
10
|
+
*/
|
|
11
|
+
isSupported(manifestName: string): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* @param {string} manifestDir - the directory where the manifest lies
|
|
14
|
+
*/
|
|
15
|
+
validateLockFile(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Provide content and content type for maven-maven stack analysis.
|
|
18
|
+
* @param {string} manifest - the manifest path or name
|
|
19
|
+
* @param {{}} [opts={}] - optional various options to pass along the application
|
|
20
|
+
* @returns {Provided}
|
|
21
|
+
*/
|
|
22
|
+
provideStack(manifest: string, opts?: {} | undefined): Provided;
|
|
23
|
+
/**
|
|
24
|
+
* Provide content and content type for maven-maven component analysis.
|
|
25
|
+
* @param {string} manifest - path to the manifest file
|
|
26
|
+
* @param {{}} [opts={}] - optional various options to pass along the application
|
|
27
|
+
* @returns {Provided}
|
|
28
|
+
*/
|
|
29
|
+
provideComponent(manifest: string, opts?: {} | undefined): Provided;
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* @param {String} textGraphList Text graph String of the manifest
|
|
33
|
+
* @param {[String]} ignoredDeps List of ignored dependencies to be omitted from sbom
|
|
34
|
+
* @return {String} formatted sbom Json String with all dependencies
|
|
35
|
+
*/
|
|
36
|
+
createSbomFileFromTextFormat(textGraphList: string, ignoredDeps: [string], opts: any): string;
|
|
37
|
+
#private;
|
|
38
|
+
}
|
|
39
|
+
export type Java_maven = import('../provider').Provider;
|
|
40
|
+
export type Provided = import('../provider').Provided;
|
|
41
|
+
export type Package = {
|
|
42
|
+
name: string;
|
|
43
|
+
version: string;
|
|
44
|
+
};
|
|
45
|
+
export type Dependency = {
|
|
46
|
+
groupId: string;
|
|
47
|
+
artifactId: string;
|
|
48
|
+
version: string;
|
|
49
|
+
scope: string;
|
|
50
|
+
ignore: boolean;
|
|
51
|
+
};
|
|
52
|
+
import Base_java from "./base_java.js";
|