@cyclonedx/cdxgen 9.1.1 → 9.2.0
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/README.md +12 -4
- package/bin/cdxgen.js +16 -4
- package/binary.js +4 -10
- package/data/bom-1.4.schema.json +1605 -0
- package/data/pypi-pkg-aliases.json +487 -485
- package/docker.js +1 -9
- package/index.js +313 -218
- package/package.json +1 -1
- package/utils.js +82 -35
- package/utils.test.js +34 -9
- package/validator.js +199 -0
package/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import Ajv from "ajv";
|
|
2
|
-
import addFormats from "ajv-formats";
|
|
3
1
|
import { platform as _platform, homedir, tmpdir } from "node:os";
|
|
4
|
-
import { basename, join, dirname, sep } from "node:path";
|
|
2
|
+
import { basename, join, dirname, sep, resolve } from "node:path";
|
|
5
3
|
import { parse } from "ssri";
|
|
6
4
|
import {
|
|
7
5
|
lstatSync,
|
|
@@ -91,7 +89,8 @@ import {
|
|
|
91
89
|
parseCsProjAssetsData,
|
|
92
90
|
parseCsPkgLockData,
|
|
93
91
|
parseCsPkgData,
|
|
94
|
-
parseCsProjData
|
|
92
|
+
parseCsProjData,
|
|
93
|
+
DEBUG_MODE
|
|
95
94
|
} from "./utils.js";
|
|
96
95
|
import { spawnSync } from "node:child_process";
|
|
97
96
|
import { fileURLToPath } from "node:url";
|
|
@@ -154,13 +153,6 @@ if (process.env.SWIFT_CMD) {
|
|
|
154
153
|
const SBT_CACHE_DIR =
|
|
155
154
|
process.env.SBT_CACHE_DIR || join(homedir(), ".ivy2", "cache");
|
|
156
155
|
|
|
157
|
-
// Debug mode flag
|
|
158
|
-
const DEBUG_MODE =
|
|
159
|
-
process.env.CDXGEN_DEBUG_MODE === "debug" ||
|
|
160
|
-
process.env.SCAN_DEBUG_MODE === "debug" ||
|
|
161
|
-
process.env.SHIFTLEFT_LOGGING_LEVEL === "debug" ||
|
|
162
|
-
process.env.NODE_ENV === "development";
|
|
163
|
-
|
|
164
156
|
// CycloneDX Hash pattern
|
|
165
157
|
const HASH_PATTERN =
|
|
166
158
|
"^([a-fA-F0-9]{32}|[a-fA-F0-9]{40}|[a-fA-F0-9]{64}|[a-fA-F0-9]{96}|[a-fA-F0-9]{128})$";
|
|
@@ -168,7 +160,16 @@ const HASH_PATTERN =
|
|
|
168
160
|
// Timeout milliseconds. Default 10 mins
|
|
169
161
|
const TIMEOUT_MS = parseInt(process.env.CDXGEN_TIMEOUT_MS) || 10 * 60 * 1000;
|
|
170
162
|
|
|
171
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Creates a default parent component based on the directory name.
|
|
165
|
+
*
|
|
166
|
+
* @param {string} path Directory or file name
|
|
167
|
+
* @param {string} type Package type
|
|
168
|
+
* @returns component object
|
|
169
|
+
*/
|
|
170
|
+
const createDefaultParentComponent = (path, type = "application") => {
|
|
171
|
+
// Expands any relative path such as dot
|
|
172
|
+
path = resolve(path);
|
|
172
173
|
// Create a parent component based on the directory name
|
|
173
174
|
let dirName =
|
|
174
175
|
existsSync(path) && lstatSync(path).isDirectory()
|
|
@@ -182,7 +183,7 @@ const createDefaultParentComponent = (path) => {
|
|
|
182
183
|
type: "application"
|
|
183
184
|
};
|
|
184
185
|
const ppurl = new PackageURL(
|
|
185
|
-
|
|
186
|
+
type,
|
|
186
187
|
parentComponent.group,
|
|
187
188
|
parentComponent.name,
|
|
188
189
|
parentComponent.version,
|
|
@@ -257,6 +258,41 @@ function addDependencies(dependencies) {
|
|
|
257
258
|
return deps_list;
|
|
258
259
|
}
|
|
259
260
|
|
|
261
|
+
const addToolsSection = (options, format) => {
|
|
262
|
+
if (options.specVersion === 1.4) {
|
|
263
|
+
if (format === "json") {
|
|
264
|
+
return [
|
|
265
|
+
{
|
|
266
|
+
vendor: "cyclonedx",
|
|
267
|
+
name: "cdxgen",
|
|
268
|
+
version: _version
|
|
269
|
+
}
|
|
270
|
+
];
|
|
271
|
+
} else {
|
|
272
|
+
return [
|
|
273
|
+
{
|
|
274
|
+
tool: {
|
|
275
|
+
vendor: "cyclonedx",
|
|
276
|
+
name: "cdxgen",
|
|
277
|
+
version: _version
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
];
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
components: [
|
|
285
|
+
{
|
|
286
|
+
group: "@cyclonedx",
|
|
287
|
+
name: "cdxgen",
|
|
288
|
+
version: _version,
|
|
289
|
+
purl: `pkg:npm/%40cyclonedx/cdxgen@${_version}`,
|
|
290
|
+
type: "application",
|
|
291
|
+
"bom-ref": `pkg:npm/@cyclonedx/cdxgen@${_version}`
|
|
292
|
+
}
|
|
293
|
+
]
|
|
294
|
+
};
|
|
295
|
+
};
|
|
260
296
|
/**
|
|
261
297
|
* Function to create metadata block
|
|
262
298
|
*
|
|
@@ -264,20 +300,10 @@ function addDependencies(dependencies) {
|
|
|
264
300
|
function addMetadata(parentComponent = {}, format = "xml", options = {}) {
|
|
265
301
|
// DO NOT fork this project to just change the vendor or author's name
|
|
266
302
|
// Try to contribute to this project by sending PR or filing issues
|
|
303
|
+
const tools = addToolsSection(options, format);
|
|
267
304
|
const metadata = {
|
|
268
305
|
timestamp: new Date().toISOString(),
|
|
269
|
-
tools
|
|
270
|
-
components: [
|
|
271
|
-
{
|
|
272
|
-
group: "@cyclonedx",
|
|
273
|
-
name: "cdxgen",
|
|
274
|
-
version: _version,
|
|
275
|
-
purl: `pkg:npm/%40cyclonedx/cdxgen@${_version}`,
|
|
276
|
-
type: "application",
|
|
277
|
-
"bom-ref": `pkg:npm/%40cyclonedx/cdxgen@${_version}`
|
|
278
|
-
}
|
|
279
|
-
]
|
|
280
|
-
},
|
|
306
|
+
tools,
|
|
281
307
|
authors: [
|
|
282
308
|
{
|
|
283
309
|
author: { name: "Prabhu Subramanian", email: "prabhu@appthreat.com" }
|
|
@@ -286,58 +312,35 @@ function addMetadata(parentComponent = {}, format = "xml", options = {}) {
|
|
|
286
312
|
supplier: undefined
|
|
287
313
|
};
|
|
288
314
|
if (format === "json") {
|
|
289
|
-
metadata.tools =
|
|
290
|
-
components: [
|
|
291
|
-
{
|
|
292
|
-
group: "@cyclonedx",
|
|
293
|
-
name: "cdxgen",
|
|
294
|
-
version: _version,
|
|
295
|
-
purl: `pkg:npm/%40cyclonedx/cdxgen@${_version}`,
|
|
296
|
-
type: "application",
|
|
297
|
-
"bom-ref": `pkg:npm/%40cyclonedx/cdxgen@${_version}`
|
|
298
|
-
}
|
|
299
|
-
]
|
|
300
|
-
};
|
|
315
|
+
metadata.tools = tools;
|
|
301
316
|
metadata.authors = [
|
|
302
317
|
{ name: "Prabhu Subramanian", email: "prabhu@appthreat.com" }
|
|
303
318
|
];
|
|
304
319
|
}
|
|
305
|
-
if (
|
|
306
|
-
parentComponent
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
{
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
// Bug #317 fix
|
|
324
|
-
if (parentComponent && parentComponent.components) {
|
|
325
|
-
firstPComp.components = parentComponent.components;
|
|
326
|
-
}
|
|
327
|
-
if (firstPComp.evidence) {
|
|
328
|
-
delete firstPComp.evidence;
|
|
329
|
-
}
|
|
330
|
-
metadata.component = firstPComp;
|
|
331
|
-
}
|
|
332
|
-
} else {
|
|
333
|
-
// As a fallback, retain the parent component
|
|
334
|
-
if (format === "json") {
|
|
335
|
-
if (parentComponent.evidence) {
|
|
336
|
-
delete parentComponent.evidence;
|
|
320
|
+
if (parentComponent && Object.keys(parentComponent).length) {
|
|
321
|
+
if (parentComponent) {
|
|
322
|
+
delete parentComponent.evidence;
|
|
323
|
+
delete parentComponent._integrity;
|
|
324
|
+
}
|
|
325
|
+
if (parentComponent && parentComponent.components) {
|
|
326
|
+
for (const comp of parentComponent.components) {
|
|
327
|
+
delete comp.evidence;
|
|
328
|
+
delete comp._integrity;
|
|
329
|
+
if (!comp["bom-ref"] && comp.name && comp.type) {
|
|
330
|
+
let fullName =
|
|
331
|
+
comp.group && comp.group.length
|
|
332
|
+
? `${comp.group}/${comp.name}`
|
|
333
|
+
: comp.name;
|
|
334
|
+
if (comp.version && comp.version.length) {
|
|
335
|
+
fullName = `${fullName}@${comp.version}`;
|
|
336
|
+
}
|
|
337
|
+
comp["bom-ref"] = `pkg:${comp.type}/${fullName}`;
|
|
337
338
|
}
|
|
338
|
-
metadata.component = parentComponent;
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
|
+
if (format === "json") {
|
|
342
|
+
metadata.component = parentComponent;
|
|
343
|
+
}
|
|
341
344
|
}
|
|
342
345
|
if (options) {
|
|
343
346
|
const mproperties = [];
|
|
@@ -599,16 +602,6 @@ function addComponent(
|
|
|
599
602
|
if (!ptype && pkg.qualifiers && pkg.qualifiers.type === "jar") {
|
|
600
603
|
ptype = "maven";
|
|
601
604
|
}
|
|
602
|
-
// Skip @types package for npm
|
|
603
|
-
if (
|
|
604
|
-
ptype == "npm" &&
|
|
605
|
-
(group === "types" ||
|
|
606
|
-
group === "@types" ||
|
|
607
|
-
!name ||
|
|
608
|
-
name.startsWith("@types"))
|
|
609
|
-
) {
|
|
610
|
-
return;
|
|
611
|
-
}
|
|
612
605
|
const version = pkg.version;
|
|
613
606
|
if (!version || ["dummy", "ignore"].includes(version)) {
|
|
614
607
|
return;
|
|
@@ -664,10 +657,10 @@ function addComponent(
|
|
|
664
657
|
};
|
|
665
658
|
if (format === "xml") {
|
|
666
659
|
component["@type"] = determinePackageType(pkg);
|
|
667
|
-
component["@bom-ref"] = purlString;
|
|
660
|
+
component["@bom-ref"] = decodeURIComponent(purlString);
|
|
668
661
|
} else {
|
|
669
662
|
component["type"] = determinePackageType(pkg);
|
|
670
|
-
component["bom-ref"] = purlString;
|
|
663
|
+
component["bom-ref"] = decodeURIComponent(purlString);
|
|
671
664
|
}
|
|
672
665
|
if (
|
|
673
666
|
component.externalReferences === undefined ||
|
|
@@ -680,7 +673,11 @@ function addComponent(
|
|
|
680
673
|
// Retain any component properties
|
|
681
674
|
if (format === "json") {
|
|
682
675
|
// Retain evidence
|
|
683
|
-
if (
|
|
676
|
+
if (
|
|
677
|
+
options.specVersion >= 1.5 &&
|
|
678
|
+
pkg.evidence &&
|
|
679
|
+
Object.keys(pkg.evidence).length
|
|
680
|
+
) {
|
|
684
681
|
component.evidence = pkg.evidence;
|
|
685
682
|
}
|
|
686
683
|
if (pkg.properties && pkg.properties.length) {
|
|
@@ -887,7 +884,10 @@ const buildBomXml = (
|
|
|
887
884
|
const bom = create("bom", {
|
|
888
885
|
encoding: "utf-8",
|
|
889
886
|
separateArrayItems: true
|
|
890
|
-
}).att(
|
|
887
|
+
}).att(
|
|
888
|
+
"xmlns",
|
|
889
|
+
`http://cyclonedx.org/schema/bom/${"" + (options.specVersion || 1.5)}`
|
|
890
|
+
);
|
|
891
891
|
bom.att("serialNumber", serialNum);
|
|
892
892
|
bom.att("version", 1);
|
|
893
893
|
const metadata = addMetadata(parentComponent, "xml", options);
|
|
@@ -934,7 +934,7 @@ const buildBomNSData = (options, pkgInfo, ptype, context) => {
|
|
|
934
934
|
allImports = context.allImports;
|
|
935
935
|
}
|
|
936
936
|
const nsMapping = context.nsMapping || {};
|
|
937
|
-
const dependencies = context.dependencies || [];
|
|
937
|
+
const dependencies = !options.requiredOnly ? context.dependencies || [] : [];
|
|
938
938
|
const parentComponent =
|
|
939
939
|
determineParentComponent(options) || context.parentComponent;
|
|
940
940
|
const metadata = addMetadata(parentComponent, "json", options);
|
|
@@ -950,7 +950,7 @@ const buildBomNSData = (options, pkgInfo, ptype, context) => {
|
|
|
950
950
|
// CycloneDX 1.5 Json Template
|
|
951
951
|
const jsonTpl = {
|
|
952
952
|
bomFormat: "CycloneDX",
|
|
953
|
-
specVersion: "1.5",
|
|
953
|
+
specVersion: "" + (options.specVersion || "1.5"),
|
|
954
954
|
serialNumber: serialNum,
|
|
955
955
|
version: 1,
|
|
956
956
|
metadata: metadata,
|
|
@@ -1131,11 +1131,17 @@ export const createJavaBom = async (path, options) => {
|
|
|
1131
1131
|
"Resolve the above maven error. This could be due to the following:\n"
|
|
1132
1132
|
);
|
|
1133
1133
|
if (
|
|
1134
|
-
result.
|
|
1135
|
-
result.
|
|
1136
|
-
"
|
|
1137
|
-
|
|
1138
|
-
|
|
1134
|
+
result.stdout &&
|
|
1135
|
+
(result.stdout.includes("Non-resolvable parent POM") ||
|
|
1136
|
+
result.stdout.includes("points at wrong local POM"))
|
|
1137
|
+
) {
|
|
1138
|
+
console.log(
|
|
1139
|
+
"1. Check if the pom.xml contains valid settings such `parent.relativePath` to make mvn command work from within the sub-directory."
|
|
1140
|
+
);
|
|
1141
|
+
} else if (
|
|
1142
|
+
result.stdout &&
|
|
1143
|
+
(result.stdout.includes("Could not resolve dependencies") ||
|
|
1144
|
+
result.stdout.includes("no dependency information available"))
|
|
1139
1145
|
) {
|
|
1140
1146
|
console.log(
|
|
1141
1147
|
"1. Try building the project with 'mvn package -Dmaven.test.skip=true' using the correct version of Java and maven before invoking cdxgen."
|
|
@@ -1677,6 +1683,7 @@ export const createNodejsBom = async (path, options) => {
|
|
|
1677
1683
|
let manifestFiles = [];
|
|
1678
1684
|
let dependencies = [];
|
|
1679
1685
|
let parentComponent = {};
|
|
1686
|
+
const parentSubComponents = [];
|
|
1680
1687
|
let ppurl = "";
|
|
1681
1688
|
// Docker mode requires special handling
|
|
1682
1689
|
if (["docker", "oci", "os"].includes(options.projectType)) {
|
|
@@ -1811,8 +1818,14 @@ export const createNodejsBom = async (path, options) => {
|
|
|
1811
1818
|
// Parse package-lock.json if available
|
|
1812
1819
|
const parsedList = await parsePkgLock(f);
|
|
1813
1820
|
const dlist = parsedList.pkgList;
|
|
1814
|
-
|
|
1815
|
-
|
|
1821
|
+
const tmpParentComponent = dlist.splice(0, 1)[0] || {};
|
|
1822
|
+
tmpParentComponent.type = "application";
|
|
1823
|
+
// Create a default parent component based on directory name
|
|
1824
|
+
if (!Object.keys(parentComponent).length) {
|
|
1825
|
+
parentComponent = tmpParentComponent;
|
|
1826
|
+
} else {
|
|
1827
|
+
parentSubComponents.push(tmpParentComponent);
|
|
1828
|
+
}
|
|
1816
1829
|
if (dlist && dlist.length) {
|
|
1817
1830
|
pkgList = pkgList.concat(dlist);
|
|
1818
1831
|
}
|
|
@@ -1890,28 +1903,38 @@ export const createNodejsBom = async (path, options) => {
|
|
|
1890
1903
|
if (existsSync(packageJsonF)) {
|
|
1891
1904
|
const pcs = await parsePkgJson(packageJsonF);
|
|
1892
1905
|
if (pcs.length) {
|
|
1893
|
-
|
|
1894
|
-
|
|
1906
|
+
const tmpParentComponent = pcs[0];
|
|
1907
|
+
tmpParentComponent.type = "application";
|
|
1908
|
+
if (!Object.keys(parentComponent).length) {
|
|
1909
|
+
parentComponent = tmpParentComponent;
|
|
1910
|
+
} else {
|
|
1911
|
+
parentSubComponents.push(tmpParentComponent);
|
|
1912
|
+
}
|
|
1895
1913
|
}
|
|
1896
1914
|
} else {
|
|
1897
1915
|
let dirName = dirname(f);
|
|
1898
1916
|
const tmpA = dirName.split(sep);
|
|
1899
1917
|
dirName = tmpA[tmpA.length - 1];
|
|
1900
|
-
|
|
1918
|
+
const tmpParentComponent = {
|
|
1901
1919
|
group: "",
|
|
1902
1920
|
name: dirName,
|
|
1903
1921
|
type: "application"
|
|
1904
1922
|
};
|
|
1905
1923
|
ppurl = new PackageURL(
|
|
1906
1924
|
"npm",
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1925
|
+
tmpParentComponent.group,
|
|
1926
|
+
tmpParentComponent.name,
|
|
1927
|
+
tmpParentComponent.version,
|
|
1910
1928
|
null,
|
|
1911
1929
|
null
|
|
1912
1930
|
).toString();
|
|
1913
|
-
|
|
1914
|
-
|
|
1931
|
+
tmpParentComponent["bom-ref"] = ppurl;
|
|
1932
|
+
tmpParentComponent["purl"] = ppurl;
|
|
1933
|
+
if (!Object.keys(parentComponent).length) {
|
|
1934
|
+
parentComponent = tmpParentComponent;
|
|
1935
|
+
} else {
|
|
1936
|
+
parentSubComponents.push(tmpParentComponent);
|
|
1937
|
+
}
|
|
1915
1938
|
}
|
|
1916
1939
|
// Parse yarn.lock if available. This check is after rush.json since
|
|
1917
1940
|
// rush.js could include yarn.lock :(
|
|
@@ -1970,17 +1993,17 @@ export const createNodejsBom = async (path, options) => {
|
|
|
1970
1993
|
parentComponent
|
|
1971
1994
|
});
|
|
1972
1995
|
}
|
|
1973
|
-
//
|
|
1974
|
-
if (
|
|
1975
|
-
|
|
1976
|
-
allImports,
|
|
1977
|
-
src: path,
|
|
1978
|
-
filename: manifestFiles.join(", "),
|
|
1979
|
-
dependencies,
|
|
1980
|
-
parentComponent
|
|
1981
|
-
});
|
|
1996
|
+
// Retain the components of parent component
|
|
1997
|
+
if (parentSubComponents.length) {
|
|
1998
|
+
parentComponent.components = parentSubComponents;
|
|
1982
1999
|
}
|
|
1983
|
-
return {
|
|
2000
|
+
return buildBomNSData(options, pkgList, "npm", {
|
|
2001
|
+
allImports,
|
|
2002
|
+
src: path,
|
|
2003
|
+
filename: manifestFiles.join(", "),
|
|
2004
|
+
dependencies,
|
|
2005
|
+
parentComponent
|
|
2006
|
+
});
|
|
1984
2007
|
};
|
|
1985
2008
|
|
|
1986
2009
|
/**
|
|
@@ -1995,7 +2018,7 @@ export const createPythonBom = async (path, options) => {
|
|
|
1995
2018
|
let dependencies = [];
|
|
1996
2019
|
let pkgList = [];
|
|
1997
2020
|
const tempDir = mkdtempSync(join(tmpdir(), "cdxgen-venv-"));
|
|
1998
|
-
const parentComponent = createDefaultParentComponent(path);
|
|
2021
|
+
const parentComponent = createDefaultParentComponent(path, "pypi");
|
|
1999
2022
|
const pipenvMode = existsSync(join(path, "Pipfile"));
|
|
2000
2023
|
const poetryFiles = getAllFiles(
|
|
2001
2024
|
path,
|
|
@@ -2103,6 +2126,12 @@ export const createPythonBom = async (path, options) => {
|
|
|
2103
2126
|
pkgList = pkgList.concat(pkgMap.pkgList);
|
|
2104
2127
|
frozen = true;
|
|
2105
2128
|
}
|
|
2129
|
+
if (pkgMap.dependenciesList) {
|
|
2130
|
+
dependencies = mergeDependencies(
|
|
2131
|
+
dependencies,
|
|
2132
|
+
pkgMap.dependenciesList
|
|
2133
|
+
);
|
|
2134
|
+
}
|
|
2106
2135
|
}
|
|
2107
2136
|
// Fallback to parsing manually
|
|
2108
2137
|
if (!pkgList.length || !frozen) {
|
|
@@ -2152,7 +2181,9 @@ export const createPythonBom = async (path, options) => {
|
|
|
2152
2181
|
if (retMap.pkgList && retMap.pkgList.length) {
|
|
2153
2182
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
2154
2183
|
for (const p of retMap.pkgList) {
|
|
2155
|
-
|
|
2184
|
+
if (p.version) {
|
|
2185
|
+
parentDependsOn.push(`pkg:pypi/${p.name}@${p.version}`);
|
|
2186
|
+
}
|
|
2156
2187
|
}
|
|
2157
2188
|
}
|
|
2158
2189
|
if (retMap.dependenciesList) {
|
|
@@ -2567,7 +2598,7 @@ export const createDartBom = async (path, options) => {
|
|
|
2567
2598
|
* @param path to the project
|
|
2568
2599
|
* @param options Parse options from the cli
|
|
2569
2600
|
*/
|
|
2570
|
-
export const createCppBom =
|
|
2601
|
+
export const createCppBom = (path, options) => {
|
|
2571
2602
|
const conanLockFiles = getAllFiles(
|
|
2572
2603
|
path,
|
|
2573
2604
|
(options.multiProject ? "**/" : "") + "conan.lock"
|
|
@@ -2736,7 +2767,7 @@ export const createClojureBom = (path, options) => {
|
|
|
2736
2767
|
* @param path to the project
|
|
2737
2768
|
* @param options Parse options from the cli
|
|
2738
2769
|
*/
|
|
2739
|
-
export const createHaskellBom =
|
|
2770
|
+
export const createHaskellBom = (path, options) => {
|
|
2740
2771
|
const cabalFiles = getAllFiles(
|
|
2741
2772
|
path,
|
|
2742
2773
|
(options.multiProject ? "**/" : "") + "cabal.project.freeze"
|
|
@@ -2767,7 +2798,7 @@ export const createHaskellBom = async (path, options) => {
|
|
|
2767
2798
|
* @param path to the project
|
|
2768
2799
|
* @param options Parse options from the cli
|
|
2769
2800
|
*/
|
|
2770
|
-
export const createElixirBom =
|
|
2801
|
+
export const createElixirBom = (path, options) => {
|
|
2771
2802
|
const mixFiles = getAllFiles(
|
|
2772
2803
|
path,
|
|
2773
2804
|
(options.multiProject ? "**/" : "") + "mix.lock"
|
|
@@ -2798,7 +2829,7 @@ export const createElixirBom = async (path, options) => {
|
|
|
2798
2829
|
* @param path to the project
|
|
2799
2830
|
* @param options Parse options from the cli
|
|
2800
2831
|
*/
|
|
2801
|
-
export const createGitHubBom =
|
|
2832
|
+
export const createGitHubBom = (path, options) => {
|
|
2802
2833
|
const ghactionFiles = getAllFiles(path, ".github/workflows/" + "*.yml");
|
|
2803
2834
|
let pkgList = [];
|
|
2804
2835
|
if (ghactionFiles.length) {
|
|
@@ -2826,7 +2857,7 @@ export const createGitHubBom = async (path, options) => {
|
|
|
2826
2857
|
* @param path to the project
|
|
2827
2858
|
* @param options Parse options from the cli
|
|
2828
2859
|
*/
|
|
2829
|
-
export const createCloudBuildBom =
|
|
2860
|
+
export const createCloudBuildBom = (path, options) => {
|
|
2830
2861
|
const cbFiles = getAllFiles(path, "cloudbuild.yml");
|
|
2831
2862
|
let pkgList = [];
|
|
2832
2863
|
if (cbFiles.length) {
|
|
@@ -2947,7 +2978,7 @@ export const createJenkinsBom = async (path, options) => {
|
|
|
2947
2978
|
* @param path to the project
|
|
2948
2979
|
* @param options Parse options from the cli
|
|
2949
2980
|
*/
|
|
2950
|
-
export const createHelmBom =
|
|
2981
|
+
export const createHelmBom = (path, options) => {
|
|
2951
2982
|
let pkgList = [];
|
|
2952
2983
|
const yamlFiles = getAllFiles(
|
|
2953
2984
|
path,
|
|
@@ -2994,7 +3025,7 @@ export const createSwiftBom = (path, options) => {
|
|
|
2994
3025
|
if (pkgResolvedFiles.length) {
|
|
2995
3026
|
for (const f of pkgResolvedFiles) {
|
|
2996
3027
|
if (!parentComponent || !Object.keys(parentComponent).length) {
|
|
2997
|
-
parentComponent = createDefaultParentComponent(f);
|
|
3028
|
+
parentComponent = createDefaultParentComponent(f, "swift");
|
|
2998
3029
|
}
|
|
2999
3030
|
if (DEBUG_MODE) {
|
|
3000
3031
|
console.log("Parsing", f);
|
|
@@ -3622,13 +3653,15 @@ export const trimComponents = (components, format) => {
|
|
|
3622
3653
|
const filteredComponents = [];
|
|
3623
3654
|
for (const comp of components) {
|
|
3624
3655
|
if (format === "xml" && comp.component) {
|
|
3625
|
-
|
|
3626
|
-
|
|
3656
|
+
const key = comp.component.purl || comp.component["bom-ref"];
|
|
3657
|
+
if (!keyCache[key]) {
|
|
3658
|
+
keyCache[key] = true;
|
|
3627
3659
|
filteredComponents.push(comp);
|
|
3628
3660
|
}
|
|
3629
3661
|
} else {
|
|
3630
|
-
|
|
3631
|
-
|
|
3662
|
+
const key = comp.purl || comp["bom-ref"];
|
|
3663
|
+
if (!keyCache[key]) {
|
|
3664
|
+
keyCache[key] = true;
|
|
3632
3665
|
filteredComponents.push(comp);
|
|
3633
3666
|
}
|
|
3634
3667
|
}
|
|
@@ -3674,7 +3707,7 @@ export const dedupeBom = (
|
|
|
3674
3707
|
),
|
|
3675
3708
|
bomJson: {
|
|
3676
3709
|
bomFormat: "CycloneDX",
|
|
3677
|
-
specVersion: "1.5
|
|
3710
|
+
specVersion: "" + (options.specVersion || 1.5),
|
|
3678
3711
|
serialNumber: serialNum,
|
|
3679
3712
|
version: 1,
|
|
3680
3713
|
metadata: addMetadata(parentComponent, "json", options),
|
|
@@ -3696,7 +3729,8 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3696
3729
|
let dependencies = [];
|
|
3697
3730
|
let componentsXmls = [];
|
|
3698
3731
|
let bomData = undefined;
|
|
3699
|
-
let parentComponent = determineParentComponent(options);
|
|
3732
|
+
let parentComponent = determineParentComponent(options) || {};
|
|
3733
|
+
let parentSubComponents = [];
|
|
3700
3734
|
if (
|
|
3701
3735
|
["docker", "oci", "container"].includes(options.projectType) &&
|
|
3702
3736
|
options.allLayersExplodedDir
|
|
@@ -3747,15 +3781,31 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3747
3781
|
}
|
|
3748
3782
|
components = components.concat(bomData.bomJson.components);
|
|
3749
3783
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3750
|
-
if (
|
|
3751
|
-
|
|
3784
|
+
if (
|
|
3785
|
+
bomData.parentComponent &&
|
|
3786
|
+
Object.keys(bomData.parentComponent).length
|
|
3787
|
+
) {
|
|
3788
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3789
|
+
}
|
|
3790
|
+
if (
|
|
3791
|
+
bomData.parentComponent.components &&
|
|
3792
|
+
bomData.parentComponent.components.length
|
|
3793
|
+
) {
|
|
3794
|
+
parentSubComponents = parentSubComponents.concat(
|
|
3795
|
+
bomData.parentComponent.components
|
|
3796
|
+
);
|
|
3752
3797
|
}
|
|
3753
3798
|
componentsXmls = componentsXmls.concat(
|
|
3754
3799
|
listComponents(options, {}, bomData.bomJson.components, "npm", "xml")
|
|
3755
3800
|
);
|
|
3756
3801
|
}
|
|
3757
3802
|
bomData = await createJavaBom(path, options);
|
|
3758
|
-
if (
|
|
3803
|
+
if (
|
|
3804
|
+
bomData &&
|
|
3805
|
+
bomData.bomJson &&
|
|
3806
|
+
bomData.bomJson.components &&
|
|
3807
|
+
bomData.bomJson.components.length
|
|
3808
|
+
) {
|
|
3759
3809
|
if (DEBUG_MODE) {
|
|
3760
3810
|
console.log(
|
|
3761
3811
|
`Found ${bomData.bomJson.components.length} java packages at ${path}`
|
|
@@ -3763,15 +3813,23 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3763
3813
|
}
|
|
3764
3814
|
components = components.concat(bomData.bomJson.components);
|
|
3765
3815
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3766
|
-
if (
|
|
3767
|
-
|
|
3816
|
+
if (
|
|
3817
|
+
bomData.parentComponent &&
|
|
3818
|
+
Object.keys(bomData.parentComponent).length
|
|
3819
|
+
) {
|
|
3820
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3768
3821
|
}
|
|
3769
3822
|
componentsXmls = componentsXmls.concat(
|
|
3770
3823
|
listComponents(options, {}, bomData.bomJson.components, "maven", "xml")
|
|
3771
3824
|
);
|
|
3772
3825
|
}
|
|
3773
3826
|
bomData = await createPythonBom(path, options);
|
|
3774
|
-
if (
|
|
3827
|
+
if (
|
|
3828
|
+
bomData &&
|
|
3829
|
+
bomData.bomJson &&
|
|
3830
|
+
bomData.bomJson.components &&
|
|
3831
|
+
bomData.bomJson.components.length
|
|
3832
|
+
) {
|
|
3775
3833
|
if (DEBUG_MODE) {
|
|
3776
3834
|
console.log(
|
|
3777
3835
|
`Found ${bomData.bomJson.components.length} python packages at ${path}`
|
|
@@ -3779,15 +3837,23 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3779
3837
|
}
|
|
3780
3838
|
components = components.concat(bomData.bomJson.components);
|
|
3781
3839
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3782
|
-
if (
|
|
3783
|
-
|
|
3840
|
+
if (
|
|
3841
|
+
bomData.parentComponent &&
|
|
3842
|
+
Object.keys(bomData.parentComponent).length
|
|
3843
|
+
) {
|
|
3844
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3784
3845
|
}
|
|
3785
3846
|
componentsXmls = componentsXmls.concat(
|
|
3786
3847
|
listComponents(options, {}, bomData.bomJson.components, "pypi", "xml")
|
|
3787
3848
|
);
|
|
3788
3849
|
}
|
|
3789
3850
|
bomData = await createGoBom(path, options);
|
|
3790
|
-
if (
|
|
3851
|
+
if (
|
|
3852
|
+
bomData &&
|
|
3853
|
+
bomData.bomJson &&
|
|
3854
|
+
bomData.bomJson.components &&
|
|
3855
|
+
bomData.bomJson.components.length
|
|
3856
|
+
) {
|
|
3791
3857
|
if (DEBUG_MODE) {
|
|
3792
3858
|
console.log(
|
|
3793
3859
|
`Found ${bomData.bomJson.components.length} go packages at ${path}`
|
|
@@ -3795,8 +3861,11 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3795
3861
|
}
|
|
3796
3862
|
components = components.concat(bomData.bomJson.components);
|
|
3797
3863
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3798
|
-
if (
|
|
3799
|
-
|
|
3864
|
+
if (
|
|
3865
|
+
bomData.parentComponent &&
|
|
3866
|
+
Object.keys(bomData.parentComponent).length
|
|
3867
|
+
) {
|
|
3868
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3800
3869
|
}
|
|
3801
3870
|
componentsXmls = componentsXmls.concat(
|
|
3802
3871
|
listComponents(options, {}, bomData.bomJson.components, "golang", "xml")
|
|
@@ -3811,8 +3880,11 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3811
3880
|
}
|
|
3812
3881
|
components = components.concat(bomData.bomJson.components);
|
|
3813
3882
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3814
|
-
if (
|
|
3815
|
-
|
|
3883
|
+
if (
|
|
3884
|
+
bomData.parentComponent &&
|
|
3885
|
+
Object.keys(bomData.parentComponent).length
|
|
3886
|
+
) {
|
|
3887
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3816
3888
|
}
|
|
3817
3889
|
componentsXmls = componentsXmls.concat(
|
|
3818
3890
|
listComponents(options, {}, bomData.bomJson.components, "cargo", "xml")
|
|
@@ -3827,8 +3899,11 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3827
3899
|
}
|
|
3828
3900
|
components = components.concat(bomData.bomJson.components);
|
|
3829
3901
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3830
|
-
if (
|
|
3831
|
-
|
|
3902
|
+
if (
|
|
3903
|
+
bomData.parentComponent &&
|
|
3904
|
+
Object.keys(bomData.parentComponent).length
|
|
3905
|
+
) {
|
|
3906
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3832
3907
|
}
|
|
3833
3908
|
componentsXmls = componentsXmls.concat(
|
|
3834
3909
|
listComponents(
|
|
@@ -3849,8 +3924,11 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3849
3924
|
}
|
|
3850
3925
|
components = components.concat(bomData.bomJson.components);
|
|
3851
3926
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3852
|
-
if (
|
|
3853
|
-
|
|
3927
|
+
if (
|
|
3928
|
+
bomData.parentComponent &&
|
|
3929
|
+
Object.keys(bomData.parentComponent).length
|
|
3930
|
+
) {
|
|
3931
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3854
3932
|
}
|
|
3855
3933
|
componentsXmls = componentsXmls.concat(
|
|
3856
3934
|
listComponents(options, {}, bomData.bomJson.components, "gem", "xml")
|
|
@@ -3865,8 +3943,11 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3865
3943
|
}
|
|
3866
3944
|
components = components.concat(bomData.bomJson.components);
|
|
3867
3945
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3868
|
-
if (
|
|
3869
|
-
|
|
3946
|
+
if (
|
|
3947
|
+
bomData.parentComponent &&
|
|
3948
|
+
Object.keys(bomData.parentComponent).length
|
|
3949
|
+
) {
|
|
3950
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3870
3951
|
}
|
|
3871
3952
|
componentsXmls = componentsXmls.concat(
|
|
3872
3953
|
listComponents(options, {}, bomData.bomJson.components, "nuget", "xml")
|
|
@@ -3881,14 +3962,17 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3881
3962
|
}
|
|
3882
3963
|
components = components.concat(bomData.bomJson.components);
|
|
3883
3964
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3884
|
-
if (
|
|
3885
|
-
|
|
3965
|
+
if (
|
|
3966
|
+
bomData.parentComponent &&
|
|
3967
|
+
Object.keys(bomData.parentComponent).length
|
|
3968
|
+
) {
|
|
3969
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3886
3970
|
}
|
|
3887
3971
|
componentsXmls = componentsXmls.concat(
|
|
3888
3972
|
listComponents(options, {}, bomData.bomJson.components, "pub", "xml")
|
|
3889
3973
|
);
|
|
3890
3974
|
}
|
|
3891
|
-
bomData =
|
|
3975
|
+
bomData = createHaskellBom(path, options);
|
|
3892
3976
|
if (bomData && bomData.bomJson && bomData.bomJson.components) {
|
|
3893
3977
|
if (DEBUG_MODE) {
|
|
3894
3978
|
console.log(
|
|
@@ -3897,8 +3981,11 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3897
3981
|
}
|
|
3898
3982
|
components = components.concat(bomData.bomJson.components);
|
|
3899
3983
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3900
|
-
if (
|
|
3901
|
-
|
|
3984
|
+
if (
|
|
3985
|
+
bomData.parentComponent &&
|
|
3986
|
+
Object.keys(bomData.parentComponent).length
|
|
3987
|
+
) {
|
|
3988
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3902
3989
|
}
|
|
3903
3990
|
componentsXmls = componentsXmls.concat(
|
|
3904
3991
|
listComponents(
|
|
@@ -3910,7 +3997,7 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3910
3997
|
)
|
|
3911
3998
|
);
|
|
3912
3999
|
}
|
|
3913
|
-
bomData =
|
|
4000
|
+
bomData = createElixirBom(path, options);
|
|
3914
4001
|
if (bomData && bomData.bomJson && bomData.bomJson.components) {
|
|
3915
4002
|
if (DEBUG_MODE) {
|
|
3916
4003
|
console.log(
|
|
@@ -3919,14 +4006,17 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3919
4006
|
}
|
|
3920
4007
|
components = components.concat(bomData.bomJson.components);
|
|
3921
4008
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3922
|
-
if (
|
|
3923
|
-
|
|
4009
|
+
if (
|
|
4010
|
+
bomData.parentComponent &&
|
|
4011
|
+
Object.keys(bomData.parentComponent).length
|
|
4012
|
+
) {
|
|
4013
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3924
4014
|
}
|
|
3925
4015
|
componentsXmls = componentsXmls.concat(
|
|
3926
4016
|
listComponents(options, {}, bomData.bomJson.components, "hex", "xml")
|
|
3927
4017
|
);
|
|
3928
4018
|
}
|
|
3929
|
-
bomData =
|
|
4019
|
+
bomData = createCppBom(path, options);
|
|
3930
4020
|
if (bomData && bomData.bomJson && bomData.bomJson.components) {
|
|
3931
4021
|
if (DEBUG_MODE) {
|
|
3932
4022
|
console.log(
|
|
@@ -3935,8 +4025,11 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3935
4025
|
}
|
|
3936
4026
|
components = components.concat(bomData.bomJson.components);
|
|
3937
4027
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3938
|
-
if (
|
|
3939
|
-
|
|
4028
|
+
if (
|
|
4029
|
+
bomData.parentComponent &&
|
|
4030
|
+
Object.keys(bomData.parentComponent).length
|
|
4031
|
+
) {
|
|
4032
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3940
4033
|
}
|
|
3941
4034
|
componentsXmls = componentsXmls.concat(
|
|
3942
4035
|
listComponents(options, {}, bomData.bomJson.components, "conan", "xml")
|
|
@@ -3951,8 +4044,11 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3951
4044
|
}
|
|
3952
4045
|
components = components.concat(bomData.bomJson.components);
|
|
3953
4046
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3954
|
-
if (
|
|
3955
|
-
|
|
4047
|
+
if (
|
|
4048
|
+
bomData.parentComponent &&
|
|
4049
|
+
Object.keys(bomData.parentComponent).length
|
|
4050
|
+
) {
|
|
4051
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3956
4052
|
}
|
|
3957
4053
|
componentsXmls = componentsXmls.concat(
|
|
3958
4054
|
listComponents(
|
|
@@ -3964,7 +4060,7 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3964
4060
|
)
|
|
3965
4061
|
);
|
|
3966
4062
|
}
|
|
3967
|
-
bomData =
|
|
4063
|
+
bomData = createGitHubBom(path, options);
|
|
3968
4064
|
if (bomData && bomData.bomJson && bomData.bomJson.components) {
|
|
3969
4065
|
if (DEBUG_MODE) {
|
|
3970
4066
|
console.log(
|
|
@@ -3973,14 +4069,17 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3973
4069
|
}
|
|
3974
4070
|
components = components.concat(bomData.bomJson.components);
|
|
3975
4071
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3976
|
-
if (
|
|
3977
|
-
|
|
4072
|
+
if (
|
|
4073
|
+
bomData.parentComponent &&
|
|
4074
|
+
Object.keys(bomData.parentComponent).length
|
|
4075
|
+
) {
|
|
4076
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3978
4077
|
}
|
|
3979
4078
|
componentsXmls = componentsXmls.concat(
|
|
3980
4079
|
listComponents(options, {}, bomData.bomJson.components, "github", "xml")
|
|
3981
4080
|
);
|
|
3982
4081
|
}
|
|
3983
|
-
bomData =
|
|
4082
|
+
bomData = createCloudBuildBom(path, options);
|
|
3984
4083
|
if (bomData && bomData.bomJson && bomData.bomJson.components) {
|
|
3985
4084
|
if (DEBUG_MODE) {
|
|
3986
4085
|
console.log(
|
|
@@ -3989,8 +4088,11 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
3989
4088
|
}
|
|
3990
4089
|
components = components.concat(bomData.bomJson.components);
|
|
3991
4090
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
3992
|
-
if (
|
|
3993
|
-
|
|
4091
|
+
if (
|
|
4092
|
+
bomData.parentComponent &&
|
|
4093
|
+
Object.keys(bomData.parentComponent).length
|
|
4094
|
+
) {
|
|
4095
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
3994
4096
|
}
|
|
3995
4097
|
componentsXmls = componentsXmls.concat(
|
|
3996
4098
|
listComponents(
|
|
@@ -4016,8 +4118,11 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
4016
4118
|
}
|
|
4017
4119
|
components = components.concat(bomData.bomJson.components);
|
|
4018
4120
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
4019
|
-
if (
|
|
4020
|
-
|
|
4121
|
+
if (
|
|
4122
|
+
bomData.parentComponent &&
|
|
4123
|
+
Object.keys(bomData.parentComponent).length
|
|
4124
|
+
) {
|
|
4125
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
4021
4126
|
}
|
|
4022
4127
|
componentsXmls = componentsXmls.concat(
|
|
4023
4128
|
listComponents(options, {}, bomData.bomJson.components, "swift", "xml")
|
|
@@ -4034,8 +4139,11 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
4034
4139
|
}
|
|
4035
4140
|
components = components.concat(bomData.bomJson.components);
|
|
4036
4141
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
4037
|
-
if (
|
|
4038
|
-
|
|
4142
|
+
if (
|
|
4143
|
+
bomData.parentComponent &&
|
|
4144
|
+
Object.keys(bomData.parentComponent).length
|
|
4145
|
+
) {
|
|
4146
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
4039
4147
|
}
|
|
4040
4148
|
componentsXmls = componentsXmls.concat(
|
|
4041
4149
|
listComponents(options, {}, bomData.bomJson.components, "maven", "xml")
|
|
@@ -4052,14 +4160,36 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
4052
4160
|
}
|
|
4053
4161
|
components = components.concat(bomData.bomJson.components);
|
|
4054
4162
|
dependencies = dependencies.concat(bomData.bomJson.dependencies);
|
|
4055
|
-
if (
|
|
4056
|
-
|
|
4163
|
+
if (
|
|
4164
|
+
bomData.parentComponent &&
|
|
4165
|
+
Object.keys(bomData.parentComponent).length
|
|
4166
|
+
) {
|
|
4167
|
+
parentSubComponents.push(bomData.parentComponent);
|
|
4057
4168
|
}
|
|
4058
4169
|
componentsXmls = componentsXmls.concat(
|
|
4059
4170
|
listComponents(options, {}, bomData.bomJson.components, "maven", "xml")
|
|
4060
4171
|
);
|
|
4061
4172
|
}
|
|
4062
4173
|
}
|
|
4174
|
+
// Retain the components of parent component
|
|
4175
|
+
if (parentSubComponents.length) {
|
|
4176
|
+
if (!parentComponent || !Object.keys(parentComponent).length) {
|
|
4177
|
+
parentComponent = parentSubComponents[0];
|
|
4178
|
+
}
|
|
4179
|
+
// Our naive approach to appending to sub-components could result in same parent being included as a child
|
|
4180
|
+
// This is filtered out here
|
|
4181
|
+
parentSubComponents = parentSubComponents.filter(
|
|
4182
|
+
(c) => c["bom-ref"] !== parentComponent["bom-ref"]
|
|
4183
|
+
);
|
|
4184
|
+
parentComponent.components = trimComponents(parentSubComponents, "json");
|
|
4185
|
+
if (
|
|
4186
|
+
parentComponent.components.length == 1 &&
|
|
4187
|
+
parentComponent.components[0].name == parentComponent.name
|
|
4188
|
+
) {
|
|
4189
|
+
parentComponent = parentComponent.components[0];
|
|
4190
|
+
delete parentComponent.components;
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4063
4193
|
return dedupeBom(
|
|
4064
4194
|
options,
|
|
4065
4195
|
components,
|
|
@@ -4217,7 +4347,7 @@ export const createXBom = async (path, options) => {
|
|
|
4217
4347
|
(options.multiProject ? "**/" : "") + "cabal.project.freeze"
|
|
4218
4348
|
);
|
|
4219
4349
|
if (hackageFiles.length) {
|
|
4220
|
-
return
|
|
4350
|
+
return createHaskellBom(path, options);
|
|
4221
4351
|
}
|
|
4222
4352
|
|
|
4223
4353
|
// Elixir
|
|
@@ -4226,7 +4356,7 @@ export const createXBom = async (path, options) => {
|
|
|
4226
4356
|
(options.multiProject ? "**/" : "") + "mix.lock"
|
|
4227
4357
|
);
|
|
4228
4358
|
if (mixFiles.length) {
|
|
4229
|
-
return
|
|
4359
|
+
return createElixirBom(path, options);
|
|
4230
4360
|
}
|
|
4231
4361
|
|
|
4232
4362
|
// cpp
|
|
@@ -4239,7 +4369,7 @@ export const createXBom = async (path, options) => {
|
|
|
4239
4369
|
(options.multiProject ? "**/" : "") + "conanfile.txt"
|
|
4240
4370
|
);
|
|
4241
4371
|
if (conanLockFiles.length || conanFiles.length) {
|
|
4242
|
-
return
|
|
4372
|
+
return createCppBom(path, options);
|
|
4243
4373
|
}
|
|
4244
4374
|
|
|
4245
4375
|
// clojure
|
|
@@ -4258,7 +4388,7 @@ export const createXBom = async (path, options) => {
|
|
|
4258
4388
|
// GitHub actions
|
|
4259
4389
|
const ghactionFiles = getAllFiles(path, ".github/workflows/" + "*.yml");
|
|
4260
4390
|
if (ghactionFiles.length) {
|
|
4261
|
-
return
|
|
4391
|
+
return createGitHubBom(path, options);
|
|
4262
4392
|
}
|
|
4263
4393
|
|
|
4264
4394
|
// Jenkins plugins
|
|
@@ -4280,7 +4410,7 @@ export const createXBom = async (path, options) => {
|
|
|
4280
4410
|
(options.multiProject ? "**/" : "") + "values.yaml"
|
|
4281
4411
|
);
|
|
4282
4412
|
if (chartFiles.length || yamlFiles.length) {
|
|
4283
|
-
return
|
|
4413
|
+
return createHelmBom(path, options);
|
|
4284
4414
|
}
|
|
4285
4415
|
|
|
4286
4416
|
// Docker compose, kubernetes and skaffold
|
|
@@ -4306,7 +4436,7 @@ export const createXBom = async (path, options) => {
|
|
|
4306
4436
|
(options.multiProject ? "**/" : "") + "cloudbuild.yaml"
|
|
4307
4437
|
);
|
|
4308
4438
|
if (cbFiles.length) {
|
|
4309
|
-
return
|
|
4439
|
+
return createCloudBuildBom(path, options);
|
|
4310
4440
|
}
|
|
4311
4441
|
|
|
4312
4442
|
// Swift
|
|
@@ -4509,18 +4639,18 @@ export const createBom = async (path, options) => {
|
|
|
4509
4639
|
case "hackage":
|
|
4510
4640
|
case "cabal":
|
|
4511
4641
|
options.multiProject = true;
|
|
4512
|
-
return
|
|
4642
|
+
return createHaskellBom(path, options);
|
|
4513
4643
|
case "elixir":
|
|
4514
4644
|
case "hex":
|
|
4515
4645
|
case "mix":
|
|
4516
4646
|
options.multiProject = true;
|
|
4517
|
-
return
|
|
4647
|
+
return createElixirBom(path, options);
|
|
4518
4648
|
case "c":
|
|
4519
4649
|
case "cpp":
|
|
4520
4650
|
case "c++":
|
|
4521
4651
|
case "conan":
|
|
4522
4652
|
options.multiProject = true;
|
|
4523
|
-
return
|
|
4653
|
+
return createCppBom(path, options);
|
|
4524
4654
|
case "clojure":
|
|
4525
4655
|
case "edn":
|
|
4526
4656
|
case "clj":
|
|
@@ -4530,7 +4660,7 @@ export const createBom = async (path, options) => {
|
|
|
4530
4660
|
case "github":
|
|
4531
4661
|
case "actions":
|
|
4532
4662
|
options.multiProject = true;
|
|
4533
|
-
return
|
|
4663
|
+
return createGitHubBom(path, options);
|
|
4534
4664
|
case "os":
|
|
4535
4665
|
case "osquery":
|
|
4536
4666
|
case "windows":
|
|
@@ -4543,11 +4673,11 @@ export const createBom = async (path, options) => {
|
|
|
4543
4673
|
case "helm":
|
|
4544
4674
|
case "charts":
|
|
4545
4675
|
options.multiProject = true;
|
|
4546
|
-
return
|
|
4676
|
+
return createHelmBom(path, options);
|
|
4547
4677
|
case "helm-index":
|
|
4548
4678
|
case "helm-repo":
|
|
4549
4679
|
options.multiProject = true;
|
|
4550
|
-
return
|
|
4680
|
+
return createHelmBom(
|
|
4551
4681
|
join(homedir(), ".cache", "helm", "repository"),
|
|
4552
4682
|
options
|
|
4553
4683
|
);
|
|
@@ -4565,7 +4695,7 @@ export const createBom = async (path, options) => {
|
|
|
4565
4695
|
return await createContainerSpecLikeBom(path, options);
|
|
4566
4696
|
case "cloudbuild":
|
|
4567
4697
|
options.multiProject = true;
|
|
4568
|
-
return
|
|
4698
|
+
return createCloudBuildBom(path, options);
|
|
4569
4699
|
case "swift":
|
|
4570
4700
|
options.multiProject = true;
|
|
4571
4701
|
return createSwiftBom(path, options);
|
|
@@ -4662,38 +4792,3 @@ export async function submitBom(args, bomContents) {
|
|
|
4662
4792
|
}
|
|
4663
4793
|
}
|
|
4664
4794
|
}
|
|
4665
|
-
|
|
4666
|
-
/**
|
|
4667
|
-
* Validate the generated bom using jsonschema
|
|
4668
|
-
*
|
|
4669
|
-
* @param {object} bomJson content
|
|
4670
|
-
*/
|
|
4671
|
-
export const validateBom = (bomJson) => {
|
|
4672
|
-
if (!bomJson) {
|
|
4673
|
-
return true;
|
|
4674
|
-
}
|
|
4675
|
-
const schema = JSON.parse(
|
|
4676
|
-
readFileSync(join(dirName, "data", "bom-1.5.schema.json"))
|
|
4677
|
-
);
|
|
4678
|
-
const defsSchema = JSON.parse(
|
|
4679
|
-
readFileSync(join(dirName, "data", "jsf-0.82.schema.json"))
|
|
4680
|
-
);
|
|
4681
|
-
const spdxSchema = JSON.parse(
|
|
4682
|
-
readFileSync(join(dirName, "data", "spdx.schema.json"))
|
|
4683
|
-
);
|
|
4684
|
-
const ajv = new Ajv({
|
|
4685
|
-
schemas: [schema, defsSchema, spdxSchema],
|
|
4686
|
-
strict: false,
|
|
4687
|
-
logger: false
|
|
4688
|
-
});
|
|
4689
|
-
addFormats(ajv);
|
|
4690
|
-
const validate = ajv.getSchema(
|
|
4691
|
-
"http://cyclonedx.org/schema/bom-1.5.schema.json"
|
|
4692
|
-
);
|
|
4693
|
-
const isValid = validate(bomJson);
|
|
4694
|
-
if (!isValid) {
|
|
4695
|
-
console.log(validate.errors);
|
|
4696
|
-
return false;
|
|
4697
|
-
}
|
|
4698
|
-
return true;
|
|
4699
|
-
};
|