@cyclonedx/cdxgen 10.4.1 → 10.4.2
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/analyzer.js +9 -10
- package/bin/cdxgen.js +2 -1
- package/bin/repl.js +4 -4
- package/bin/verify.js +3 -4
- package/binary.js +19 -19
- package/cbomutils.js +2 -2
- package/display.js +6 -7
- package/docker.js +56 -63
- package/envcontext.js +6 -7
- package/evinser.js +33 -33
- package/index.js +924 -1011
- package/package.json +4 -4
- package/postgen.js +3 -3
- package/protobom.test.js +1 -1
- package/types/analyzer.d.ts.map +1 -1
- package/types/display.d.ts.map +1 -1
- package/types/docker.d.ts.map +1 -1
- package/types/evinser.d.ts.map +1 -1
- package/types/index.d.ts.map +1 -1
- package/types/utils.d.ts.map +1 -1
- package/types/validator.d.ts.map +1 -1
- package/utils.js +254 -322
- package/utils.test.js +7 -8
- package/validator.js +11 -14
package/index.js
CHANGED
|
@@ -225,7 +225,7 @@ const createDefaultParentComponent = (
|
|
|
225
225
|
const parentComponent = {
|
|
226
226
|
group: options.projectGroup || "",
|
|
227
227
|
name: options.projectName || dirNameStr,
|
|
228
|
-
version:
|
|
228
|
+
version: `${options.projectVersion}` || "latest",
|
|
229
229
|
type: "application",
|
|
230
230
|
};
|
|
231
231
|
const ppurl = new PackageURL(
|
|
@@ -245,11 +245,12 @@ const determineParentComponent = (options) => {
|
|
|
245
245
|
let parentComponent = undefined;
|
|
246
246
|
if (options.parentComponent && Object.keys(options.parentComponent).length) {
|
|
247
247
|
return options.parentComponent;
|
|
248
|
-
}
|
|
248
|
+
}
|
|
249
|
+
if (options.projectName && options.projectVersion) {
|
|
249
250
|
parentComponent = {
|
|
250
251
|
group: options.projectGroup || "",
|
|
251
252
|
name: options.projectName,
|
|
252
|
-
version:
|
|
253
|
+
version: `${options.projectVersion}` || "",
|
|
253
254
|
type: "application",
|
|
254
255
|
};
|
|
255
256
|
const ppurl = new PackageURL(
|
|
@@ -308,9 +309,8 @@ const addToolsSection = (options, context = {}) => {
|
|
|
308
309
|
};
|
|
309
310
|
|
|
310
311
|
const componentToSimpleFullName = (comp) => {
|
|
311
|
-
let fullName =
|
|
312
|
-
|
|
313
|
-
if (comp.version && comp.version.length) {
|
|
312
|
+
let fullName = comp.group?.length ? `${comp.group}/${comp.name}` : comp.name;
|
|
313
|
+
if (comp.version?.length) {
|
|
314
314
|
fullName = `${fullName}@${comp.version}`;
|
|
315
315
|
}
|
|
316
316
|
return fullName;
|
|
@@ -434,13 +434,13 @@ const addFormulationSection = (options) => {
|
|
|
434
434
|
}
|
|
435
435
|
// Collect build environment details
|
|
436
436
|
const infoComponents = collectEnvInfo(options.path);
|
|
437
|
-
if (infoComponents
|
|
437
|
+
if (infoComponents?.length) {
|
|
438
438
|
components = components.concat(infoComponents);
|
|
439
439
|
}
|
|
440
440
|
// Should we include the OS crypto libraries
|
|
441
441
|
if (options.includeCrypto) {
|
|
442
442
|
const cryptoLibs = collectOSCryptoLibs(options);
|
|
443
|
-
if (cryptoLibs
|
|
443
|
+
if (cryptoLibs?.length) {
|
|
444
444
|
components = components.concat(cryptoLibs);
|
|
445
445
|
}
|
|
446
446
|
}
|
|
@@ -510,7 +510,7 @@ function addMetadata(parentComponent = {}, options = {}, context = {}) {
|
|
|
510
510
|
parentComponent["purl"] = encodeForPurl(parentComponent["bom-ref"]);
|
|
511
511
|
}
|
|
512
512
|
}
|
|
513
|
-
if (parentComponent
|
|
513
|
+
if (parentComponent?.components) {
|
|
514
514
|
const parentFullName = componentToSimpleFullName(parentComponent);
|
|
515
515
|
const subComponents = [];
|
|
516
516
|
const addedSubComponents = {};
|
|
@@ -529,7 +529,7 @@ function addMetadata(parentComponent = {}, options = {}, context = {}) {
|
|
|
529
529
|
fullName !== parentFullName &&
|
|
530
530
|
!(
|
|
531
531
|
(comp.name === parentComponent.name ||
|
|
532
|
-
comp.name === parentComponent.name
|
|
532
|
+
comp.name === `${parentComponent.name}:latest`) &&
|
|
533
533
|
comp.version === "latest"
|
|
534
534
|
)
|
|
535
535
|
) {
|
|
@@ -657,7 +657,7 @@ function addMetadata(parentComponent = {}, options = {}, context = {}) {
|
|
|
657
657
|
}
|
|
658
658
|
}
|
|
659
659
|
}
|
|
660
|
-
if (options.allOSComponentTypes
|
|
660
|
+
if (options.allOSComponentTypes?.length) {
|
|
661
661
|
mproperties.push({
|
|
662
662
|
name: "oci:image:componentTypes",
|
|
663
663
|
value: options.allOSComponentTypes.join("\\n"),
|
|
@@ -689,19 +689,19 @@ function addExternalReferences(opkg) {
|
|
|
689
689
|
if (pkg.externalReferences) {
|
|
690
690
|
externalReferences = externalReferences.concat(pkg.externalReferences);
|
|
691
691
|
} else {
|
|
692
|
-
if (pkg.homepage
|
|
692
|
+
if (pkg.homepage?.url) {
|
|
693
693
|
externalReferences.push({
|
|
694
694
|
type: pkg.homepage.url.includes("git") ? "vcs" : "website",
|
|
695
695
|
url: pkg.homepage.url,
|
|
696
696
|
});
|
|
697
697
|
}
|
|
698
|
-
if (pkg.bugs
|
|
698
|
+
if (pkg.bugs?.url) {
|
|
699
699
|
externalReferences.push({
|
|
700
700
|
type: "issue-tracker",
|
|
701
701
|
url: pkg.bugs.url,
|
|
702
702
|
});
|
|
703
703
|
}
|
|
704
|
-
if (pkg.repository
|
|
704
|
+
if (pkg.repository?.url) {
|
|
705
705
|
externalReferences.push({
|
|
706
706
|
type: "vcs",
|
|
707
707
|
url: pkg.repository.url,
|
|
@@ -777,7 +777,7 @@ function addComponent(
|
|
|
777
777
|
encodeForPurl(pkg.subpath),
|
|
778
778
|
);
|
|
779
779
|
// There is no purl for cryptographic-asset
|
|
780
|
-
if (ptype
|
|
780
|
+
if (ptype === "cryptographic-asset") {
|
|
781
781
|
purl = undefined;
|
|
782
782
|
}
|
|
783
783
|
const purlString = purl.toString();
|
|
@@ -787,10 +787,10 @@ function addComponent(
|
|
|
787
787
|
const impPkgs = Object.keys(allImports);
|
|
788
788
|
if (
|
|
789
789
|
impPkgs.includes(name) ||
|
|
790
|
-
impPkgs.includes(group
|
|
791
|
-
impPkgs.includes(
|
|
790
|
+
impPkgs.includes(`${group}/${name}`) ||
|
|
791
|
+
impPkgs.includes(`@${group}/${name}`) ||
|
|
792
792
|
impPkgs.includes(group) ||
|
|
793
|
-
impPkgs.includes(
|
|
793
|
+
impPkgs.includes(`@${group}`)
|
|
794
794
|
) {
|
|
795
795
|
compScope = "required";
|
|
796
796
|
} else if (impPkgs.length) {
|
|
@@ -850,10 +850,10 @@ function addComponent(
|
|
|
850
850
|
component.tags = pkg.tags;
|
|
851
851
|
}
|
|
852
852
|
// Retain any component properties and crypto properties
|
|
853
|
-
if (pkg.properties
|
|
853
|
+
if (pkg.properties?.length) {
|
|
854
854
|
component.properties = pkg.properties;
|
|
855
855
|
}
|
|
856
|
-
if (pkg.cryptoProperties
|
|
856
|
+
if (pkg.cryptoProperties?.length) {
|
|
857
857
|
component.cryptoProperties = pkg.cryptoProperties;
|
|
858
858
|
}
|
|
859
859
|
if (compMap[component.purl]) return; //remove cycles
|
|
@@ -904,7 +904,7 @@ function determinePackageType(pkg) {
|
|
|
904
904
|
for (const cf of frameworksList.all) {
|
|
905
905
|
if (
|
|
906
906
|
pkg.purl.startsWith(cf) ||
|
|
907
|
-
|
|
907
|
+
purl.namespace?.includes(cf) ||
|
|
908
908
|
purl.name.toLowerCase().includes(cf)
|
|
909
909
|
) {
|
|
910
910
|
return "framework";
|
|
@@ -919,10 +919,7 @@ function determinePackageType(pkg) {
|
|
|
919
919
|
}
|
|
920
920
|
}
|
|
921
921
|
if (Object.prototype.hasOwnProperty.call(pkg, "description")) {
|
|
922
|
-
if (
|
|
923
|
-
pkg.description &&
|
|
924
|
-
pkg.description.toLowerCase().includes("framework")
|
|
925
|
-
) {
|
|
922
|
+
if (pkg.description?.toLowerCase().includes("framework")) {
|
|
926
923
|
return "framework";
|
|
927
924
|
}
|
|
928
925
|
}
|
|
@@ -1011,9 +1008,9 @@ const buildBomNSData = (options, pkgInfo, ptype, context) => {
|
|
|
1011
1008
|
dependencies: undefined,
|
|
1012
1009
|
parentComponent: undefined,
|
|
1013
1010
|
};
|
|
1014
|
-
const serialNum =
|
|
1011
|
+
const serialNum = `urn:uuid:${uuidv4()}`;
|
|
1015
1012
|
let allImports = {};
|
|
1016
|
-
if (context
|
|
1013
|
+
if (context?.allImports) {
|
|
1017
1014
|
allImports = context.allImports;
|
|
1018
1015
|
}
|
|
1019
1016
|
const nsMapping = context.nsMapping || {};
|
|
@@ -1026,7 +1023,7 @@ const buildBomNSData = (options, pkgInfo, ptype, context) => {
|
|
|
1026
1023
|
// CycloneDX 1.5 Json Template
|
|
1027
1024
|
const jsonTpl = {
|
|
1028
1025
|
bomFormat: "CycloneDX",
|
|
1029
|
-
specVersion:
|
|
1026
|
+
specVersion: `${options.specVersion || "1.5"}`,
|
|
1030
1027
|
serialNumber: serialNum,
|
|
1031
1028
|
version: 1,
|
|
1032
1029
|
metadata: metadata,
|
|
@@ -1082,14 +1079,14 @@ export async function createJarBom(path, options) {
|
|
|
1082
1079
|
} else {
|
|
1083
1080
|
jarFiles = getAllFiles(
|
|
1084
1081
|
path,
|
|
1085
|
-
|
|
1082
|
+
`${options.multiProject ? "**/" : ""}*.[jw]ar`,
|
|
1086
1083
|
options,
|
|
1087
1084
|
);
|
|
1088
1085
|
}
|
|
1089
1086
|
// Jenkins plugins
|
|
1090
1087
|
const hpiFiles = getAllFiles(
|
|
1091
1088
|
path,
|
|
1092
|
-
|
|
1089
|
+
`${options.multiProject ? "**/" : ""}*.hpi`,
|
|
1093
1090
|
options,
|
|
1094
1091
|
);
|
|
1095
1092
|
if (hpiFiles.length) {
|
|
@@ -1101,7 +1098,7 @@ export async function createJarBom(path, options) {
|
|
|
1101
1098
|
console.log(`Parsing ${jar}`);
|
|
1102
1099
|
}
|
|
1103
1100
|
const dlist = await extractJarArchive(jar, tempDir);
|
|
1104
|
-
if (dlist
|
|
1101
|
+
if (dlist?.length) {
|
|
1105
1102
|
pkgList = pkgList.concat(dlist);
|
|
1106
1103
|
}
|
|
1107
1104
|
if (pkgList.length) {
|
|
@@ -1109,7 +1106,7 @@ export async function createJarBom(path, options) {
|
|
|
1109
1106
|
}
|
|
1110
1107
|
}
|
|
1111
1108
|
// Clean up
|
|
1112
|
-
if (tempDir
|
|
1109
|
+
if (tempDir?.startsWith(tmpdir()) && rmSync) {
|
|
1113
1110
|
rmSync(tempDir, { recursive: true, force: true });
|
|
1114
1111
|
}
|
|
1115
1112
|
pkgList = pkgList.concat(convertJarNSToPackages(nsMapping));
|
|
@@ -1182,7 +1179,7 @@ export async function createJavaBom(path, options) {
|
|
|
1182
1179
|
pkgList = await getMvnMetadata(pkgList);
|
|
1183
1180
|
}
|
|
1184
1181
|
// Clean up
|
|
1185
|
-
if (tempDir
|
|
1182
|
+
if (tempDir?.startsWith(tmpdir()) && rmSync) {
|
|
1186
1183
|
console.log(`Cleaning up ${tempDir}`);
|
|
1187
1184
|
rmSync(tempDir, { recursive: true, force: true });
|
|
1188
1185
|
}
|
|
@@ -1196,740 +1193,737 @@ export async function createJavaBom(path, options) {
|
|
|
1196
1193
|
dependencies,
|
|
1197
1194
|
parentComponent,
|
|
1198
1195
|
});
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1196
|
+
}
|
|
1197
|
+
// maven - pom.xml
|
|
1198
|
+
const pomFiles = getAllFiles(
|
|
1199
|
+
path,
|
|
1200
|
+
`${options.multiProject ? "**/" : ""}pom.xml`,
|
|
1201
|
+
options,
|
|
1202
|
+
);
|
|
1203
|
+
let bomJsonFiles = [];
|
|
1204
|
+
if (
|
|
1205
|
+
pomFiles?.length &&
|
|
1206
|
+
!["scala", "sbt", "gradle"].includes(options.projectType)
|
|
1207
|
+
) {
|
|
1208
|
+
const cdxMavenPlugin =
|
|
1209
|
+
process.env.CDX_MAVEN_PLUGIN ||
|
|
1210
|
+
"org.cyclonedx:cyclonedx-maven-plugin:2.8.0";
|
|
1211
|
+
const cdxMavenGoal = process.env.CDX_MAVEN_GOAL || "makeAggregateBom";
|
|
1212
|
+
let mvnArgs = [`${cdxMavenPlugin}:${cdxMavenGoal}`, "-DoutputName=bom"];
|
|
1213
|
+
if (includeMavenTestScope) {
|
|
1214
|
+
mvnArgs.push("-DincludeTestScope=true");
|
|
1215
|
+
}
|
|
1216
|
+
// By using quiet mode we can reduce the maxBuffer used and avoid crashes
|
|
1217
|
+
if (!DEBUG_MODE) {
|
|
1218
|
+
mvnArgs.push("-q");
|
|
1219
|
+
}
|
|
1220
|
+
// Support for passing additional settings and profile to maven
|
|
1221
|
+
if (process.env.MVN_ARGS) {
|
|
1222
|
+
const addArgs = process.env.MVN_ARGS.split(" ");
|
|
1223
|
+
mvnArgs = mvnArgs.concat(addArgs);
|
|
1224
|
+
}
|
|
1225
|
+
// specVersion 1.4 doesn't support externalReferences.type=disribution-intake
|
|
1226
|
+
// so we need to run the plugin with the correct version
|
|
1227
|
+
if (options.specVersion === 1.4) {
|
|
1228
|
+
mvnArgs = mvnArgs.concat("-DschemaVersion=1.4");
|
|
1229
|
+
}
|
|
1230
|
+
for (const f of pomFiles) {
|
|
1231
|
+
const basePath = dirname(f);
|
|
1232
|
+
const settingsXml = join(basePath, "settings.xml");
|
|
1233
|
+
if (existsSync(settingsXml)) {
|
|
1234
|
+
console.log(
|
|
1235
|
+
`maven settings.xml found in ${basePath}. Please set the MVN_ARGS environment variable based on the full mvn build command used for this project.\nExample: MVN_ARGS='--settings ${settingsXml}'`,
|
|
1236
|
+
);
|
|
1237
|
+
}
|
|
1238
|
+
const mavenCmd = getMavenCommand(basePath, path);
|
|
1239
|
+
// Should we attempt to resolve class names
|
|
1240
|
+
if (options.resolveClass || options.deep) {
|
|
1241
|
+
const tmpjarNSMapping = await collectMvnDependencies(
|
|
1242
|
+
mavenCmd,
|
|
1243
|
+
basePath,
|
|
1244
|
+
true,
|
|
1245
|
+
false,
|
|
1246
|
+
);
|
|
1247
|
+
if (tmpjarNSMapping && Object.keys(tmpjarNSMapping).length) {
|
|
1248
|
+
jarNSMapping = { ...jarNSMapping, ...tmpjarNSMapping };
|
|
1241
1249
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1250
|
+
}
|
|
1251
|
+
console.log(`Executing '${mavenCmd} ${mvnArgs.join(" ")}' in`, basePath);
|
|
1252
|
+
let result = spawnSync(mavenCmd, mvnArgs, {
|
|
1253
|
+
cwd: basePath,
|
|
1254
|
+
shell: true,
|
|
1255
|
+
encoding: "utf-8",
|
|
1256
|
+
timeout: TIMEOUT_MS,
|
|
1257
|
+
maxBuffer: MAX_BUFFER,
|
|
1258
|
+
});
|
|
1259
|
+
// Check if the cyclonedx plugin created the required bom.json file
|
|
1260
|
+
// Sometimes the plugin fails silently for complex maven projects
|
|
1261
|
+
bomJsonFiles = getAllFiles(path, "**/target/*.json", options);
|
|
1262
|
+
// Check if the bom json files got created in a directory other than target
|
|
1263
|
+
if (!bomJsonFiles.length) {
|
|
1264
|
+
bomJsonFiles = getAllFiles(path, "**/bom*.json", options);
|
|
1265
|
+
}
|
|
1266
|
+
const bomGenerated = bomJsonFiles.length;
|
|
1267
|
+
if (!bomGenerated || result.status !== 0 || result.error) {
|
|
1268
|
+
const tempDir = mkdtempSync(join(tmpdir(), "cdxmvn-"));
|
|
1269
|
+
const tempMvnTree = join(tempDir, "mvn-tree.txt");
|
|
1270
|
+
let mvnTreeArgs = ["dependency:tree", `-DoutputFile=${tempMvnTree}`];
|
|
1271
|
+
if (process.env.MVN_ARGS) {
|
|
1272
|
+
const addArgs = process.env.MVN_ARGS.split(" ");
|
|
1273
|
+
mvnTreeArgs = mvnTreeArgs.concat(addArgs);
|
|
1254
1274
|
}
|
|
1255
1275
|
console.log(
|
|
1256
|
-
`
|
|
1257
|
-
basePath,
|
|
1276
|
+
`Fallback to executing ${mavenCmd} ${mvnTreeArgs.join(" ")}`,
|
|
1258
1277
|
);
|
|
1259
|
-
|
|
1278
|
+
result = spawnSync(mavenCmd, mvnTreeArgs, {
|
|
1260
1279
|
cwd: basePath,
|
|
1261
1280
|
shell: true,
|
|
1262
1281
|
encoding: "utf-8",
|
|
1263
1282
|
timeout: TIMEOUT_MS,
|
|
1264
1283
|
maxBuffer: MAX_BUFFER,
|
|
1265
1284
|
});
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
const addArgs = process.env.MVN_ARGS.split(" ");
|
|
1280
|
-
mvnTreeArgs = mvnTreeArgs.concat(addArgs);
|
|
1281
|
-
}
|
|
1282
|
-
console.log(
|
|
1283
|
-
`Fallback to executing ${mavenCmd} ${mvnTreeArgs.join(" ")}`,
|
|
1284
|
-
);
|
|
1285
|
-
result = spawnSync(mavenCmd, mvnTreeArgs, {
|
|
1286
|
-
cwd: basePath,
|
|
1287
|
-
shell: true,
|
|
1288
|
-
encoding: "utf-8",
|
|
1289
|
-
timeout: TIMEOUT_MS,
|
|
1290
|
-
maxBuffer: MAX_BUFFER,
|
|
1291
|
-
});
|
|
1292
|
-
if (result.status !== 0 || result.error) {
|
|
1293
|
-
// Our approach to recursively invoking the maven plugin for each sub-module is bound to result in failures
|
|
1294
|
-
// These could be due to a range of reasons that are covered below.
|
|
1295
|
-
if (pomFiles.length === 1 || DEBUG_MODE) {
|
|
1296
|
-
console.error(result.stdout, result.stderr);
|
|
1285
|
+
if (result.status !== 0 || result.error) {
|
|
1286
|
+
// Our approach to recursively invoking the maven plugin for each sub-module is bound to result in failures
|
|
1287
|
+
// These could be due to a range of reasons that are covered below.
|
|
1288
|
+
if (pomFiles.length === 1 || DEBUG_MODE) {
|
|
1289
|
+
console.error(result.stdout, result.stderr);
|
|
1290
|
+
console.log(
|
|
1291
|
+
"Resolve the above maven error. This could be due to the following:\n",
|
|
1292
|
+
);
|
|
1293
|
+
if (
|
|
1294
|
+
result.stdout &&
|
|
1295
|
+
(result.stdout.includes("Non-resolvable parent POM") ||
|
|
1296
|
+
result.stdout.includes("points at wrong local POM"))
|
|
1297
|
+
) {
|
|
1297
1298
|
console.log(
|
|
1298
|
-
"
|
|
1299
|
+
"1. Check if the pom.xml contains valid settings for parent and modules. Some projects can be built only from a specific directory.",
|
|
1299
1300
|
);
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
console.log(
|
|
1306
|
-
"1. Check if the pom.xml contains valid settings such `parent.relativePath` to make mvn command work from within the sub-directory.",
|
|
1307
|
-
);
|
|
1308
|
-
} else if (
|
|
1309
|
-
result.stdout &&
|
|
1310
|
-
(result.stdout.includes("Could not resolve dependencies") ||
|
|
1311
|
-
result.stdout.includes("no dependency information available"))
|
|
1312
|
-
) {
|
|
1313
|
-
console.log(
|
|
1314
|
-
"1. Try building the project with 'mvn package -Dmaven.test.skip=true' using the correct version of Java and maven before invoking cdxgen.",
|
|
1315
|
-
);
|
|
1316
|
-
} else if (
|
|
1317
|
-
result.stdout &&
|
|
1318
|
-
result.stdout.includes(
|
|
1319
|
-
"Could not resolve target platform specification",
|
|
1320
|
-
)
|
|
1321
|
-
) {
|
|
1322
|
-
console.log(
|
|
1323
|
-
"1. Some projects can be built only from the root directory. Invoke cdxgen with --no-recurse option",
|
|
1324
|
-
);
|
|
1325
|
-
} else {
|
|
1326
|
-
console.log(
|
|
1327
|
-
"1. Java version requirement: cdxgen container image bundles Java 21 with maven 3.9 which might be incompatible.",
|
|
1328
|
-
);
|
|
1329
|
-
}
|
|
1301
|
+
} else if (
|
|
1302
|
+
result.stdout &&
|
|
1303
|
+
(result.stdout.includes("Could not resolve dependencies") ||
|
|
1304
|
+
result.stdout.includes("no dependency information available"))
|
|
1305
|
+
) {
|
|
1330
1306
|
console.log(
|
|
1331
|
-
"
|
|
1307
|
+
"1. Try building the project with 'mvn package -Dmaven.test.skip=true' using the correct version of Java and maven before invoking cdxgen.",
|
|
1332
1308
|
);
|
|
1309
|
+
} else if (
|
|
1310
|
+
result.stdout?.includes(
|
|
1311
|
+
"Could not resolve target platform specification",
|
|
1312
|
+
)
|
|
1313
|
+
) {
|
|
1333
1314
|
console.log(
|
|
1334
|
-
"
|
|
1315
|
+
"1. Some projects can be built only from the root directory. Invoke cdxgen with --no-recurse option",
|
|
1316
|
+
);
|
|
1317
|
+
} else {
|
|
1318
|
+
console.log(
|
|
1319
|
+
"1. Java version requirement: cdxgen container image bundles Java 21 with maven 3.9 which might be incompatible. Try running cdxgen with the unofficial JDK11-based image `ghcr.io/appthreat/cdxgen-java:v10`.",
|
|
1335
1320
|
);
|
|
1336
1321
|
}
|
|
1337
|
-
// Do not fall back to methods that can produce incomplete results when failOnError is set
|
|
1338
|
-
options.failOnError && process.exit(1);
|
|
1339
1322
|
console.log(
|
|
1340
|
-
"
|
|
1323
|
+
"2. Private dependencies cannot be downloaded: Check if any additional arguments must be passed to maven and set them via MVN_ARGS environment variable.",
|
|
1324
|
+
);
|
|
1325
|
+
console.log(
|
|
1326
|
+
"3. Check if all required environment variables including any maven profile arguments are passed correctly to this tool.",
|
|
1341
1327
|
);
|
|
1342
|
-
const dlist = parsePom(f);
|
|
1343
|
-
if (dlist && dlist.length) {
|
|
1344
|
-
pkgList = pkgList.concat(dlist);
|
|
1345
|
-
}
|
|
1346
|
-
} else {
|
|
1347
|
-
if (existsSync(tempMvnTree)) {
|
|
1348
|
-
const mvnTreeString = readFileSync(tempMvnTree, {
|
|
1349
|
-
encoding: "utf-8",
|
|
1350
|
-
});
|
|
1351
|
-
const parsedList = parseMavenTree(mvnTreeString);
|
|
1352
|
-
const dlist = parsedList.pkgList;
|
|
1353
|
-
parentComponent = dlist.splice(0, 1)[0];
|
|
1354
|
-
parentComponent.type = "application";
|
|
1355
|
-
if (dlist && dlist.length) {
|
|
1356
|
-
pkgList = pkgList.concat(dlist);
|
|
1357
|
-
}
|
|
1358
|
-
if (parsedList.dependenciesList && parsedList.dependenciesList) {
|
|
1359
|
-
dependencies = dependencies.concat(parsedList.dependenciesList);
|
|
1360
|
-
}
|
|
1361
|
-
unlinkSync(tempMvnTree);
|
|
1362
|
-
}
|
|
1363
1328
|
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1329
|
+
// Do not fall back to methods that can produce incomplete results when failOnError is set
|
|
1330
|
+
options.failOnError && process.exit(1);
|
|
1331
|
+
console.log(
|
|
1332
|
+
"\nFalling back to parsing pom.xml files. Only direct dependencies would get included!",
|
|
1333
|
+
);
|
|
1334
|
+
const dlist = parsePom(f);
|
|
1335
|
+
if (dlist?.length) {
|
|
1336
|
+
pkgList = pkgList.concat(dlist);
|
|
1371
1337
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1338
|
+
} else {
|
|
1339
|
+
if (existsSync(tempMvnTree)) {
|
|
1340
|
+
const mvnTreeString = readFileSync(tempMvnTree, {
|
|
1374
1341
|
encoding: "utf-8",
|
|
1375
|
-
})
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
Array.isArray(bomJsonObj.metadata.tools)
|
|
1383
|
-
) {
|
|
1384
|
-
tools = bomJsonObj.metadata.tools;
|
|
1385
|
-
}
|
|
1386
|
-
if (
|
|
1387
|
-
bomJsonObj.metadata &&
|
|
1388
|
-
bomJsonObj.metadata.component &&
|
|
1389
|
-
!Object.keys(parentComponent).length
|
|
1390
|
-
) {
|
|
1391
|
-
parentComponent = bomJsonObj.metadata.component;
|
|
1392
|
-
options.parentComponent = parentComponent;
|
|
1393
|
-
pkgList = [];
|
|
1394
|
-
}
|
|
1395
|
-
if (bomJsonObj.components) {
|
|
1396
|
-
pkgList = pkgList.concat(bomJsonObj.components);
|
|
1397
|
-
}
|
|
1398
|
-
if (bomJsonObj.dependencies) {
|
|
1399
|
-
dependencies = mergeDependencies(
|
|
1400
|
-
dependencies,
|
|
1401
|
-
bomJsonObj.dependencies,
|
|
1402
|
-
parentComponent,
|
|
1403
|
-
);
|
|
1342
|
+
});
|
|
1343
|
+
const parsedList = parseMavenTree(mvnTreeString);
|
|
1344
|
+
const dlist = parsedList.pkgList;
|
|
1345
|
+
parentComponent = dlist.splice(0, 1)[0];
|
|
1346
|
+
parentComponent.type = "application";
|
|
1347
|
+
if (dlist?.length) {
|
|
1348
|
+
pkgList = pkgList.concat(dlist);
|
|
1404
1349
|
}
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
if (options.failOnError || DEBUG_MODE) {
|
|
1408
|
-
console.log(err);
|
|
1409
|
-
options.failOnError && process.exit(1);
|
|
1410
|
-
}
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
if (pkgList) {
|
|
1414
|
-
pkgList = trimComponents(pkgList);
|
|
1415
|
-
pkgList = await getMvnMetadata(pkgList, jarNSMapping);
|
|
1416
|
-
return buildBomNSData(options, pkgList, "maven", {
|
|
1417
|
-
src: path,
|
|
1418
|
-
filename: pomFiles.join(", "),
|
|
1419
|
-
nsMapping: jarNSMapping,
|
|
1420
|
-
dependencies,
|
|
1421
|
-
parentComponent,
|
|
1422
|
-
tools,
|
|
1423
|
-
});
|
|
1424
|
-
} else if (bomJsonFiles.length) {
|
|
1425
|
-
const bomNSData = {};
|
|
1426
|
-
bomNSData.bomJsonFiles = bomJsonFiles;
|
|
1427
|
-
bomNSData.nsMapping = jarNSMapping;
|
|
1428
|
-
bomNSData.dependencies = dependencies;
|
|
1429
|
-
bomNSData.parentComponent = parentComponent;
|
|
1430
|
-
return bomNSData;
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1433
|
-
// gradle
|
|
1434
|
-
const gradleFiles = getAllFiles(
|
|
1435
|
-
path,
|
|
1436
|
-
(options.multiProject ? "**/" : "") + "build.gradle*",
|
|
1437
|
-
options,
|
|
1438
|
-
);
|
|
1439
|
-
const allProjects = [];
|
|
1440
|
-
const allProjectsAddedPurls = [];
|
|
1441
|
-
const rootDependsOn = [];
|
|
1442
|
-
// Execute gradle properties
|
|
1443
|
-
if (
|
|
1444
|
-
gradleFiles &&
|
|
1445
|
-
gradleFiles.length &&
|
|
1446
|
-
!["scala", "sbt"].includes(options.projectType)
|
|
1447
|
-
) {
|
|
1448
|
-
let retMap = executeGradleProperties(path, null, null);
|
|
1449
|
-
const allProjectsStr = retMap.projects || [];
|
|
1450
|
-
const rootProject = retMap.rootProject;
|
|
1451
|
-
if (rootProject) {
|
|
1452
|
-
parentComponent = {
|
|
1453
|
-
name: rootProject,
|
|
1454
|
-
type: "application",
|
|
1455
|
-
...retMap.metadata,
|
|
1456
|
-
};
|
|
1457
|
-
const parentPurl = new PackageURL(
|
|
1458
|
-
"maven",
|
|
1459
|
-
parentComponent.group || "",
|
|
1460
|
-
parentComponent.name,
|
|
1461
|
-
parentComponent.version,
|
|
1462
|
-
{ type: "jar" },
|
|
1463
|
-
null,
|
|
1464
|
-
).toString();
|
|
1465
|
-
parentComponent["purl"] = parentPurl;
|
|
1466
|
-
parentComponent["bom-ref"] = decodeURIComponent(parentPurl);
|
|
1467
|
-
}
|
|
1468
|
-
// Get the sub-project properties and set the root dependencies
|
|
1469
|
-
if (allProjectsStr && allProjectsStr.length) {
|
|
1470
|
-
for (const spstr of allProjectsStr) {
|
|
1471
|
-
retMap = executeGradleProperties(path, null, spstr);
|
|
1472
|
-
const rootSubProject = retMap.rootProject;
|
|
1473
|
-
if (rootSubProject) {
|
|
1474
|
-
const rspName = rootSubProject.replace(/^:/, "");
|
|
1475
|
-
const rootSubProjectObj = {
|
|
1476
|
-
name: rspName,
|
|
1477
|
-
type: "application",
|
|
1478
|
-
qualifiers: { type: "jar" },
|
|
1479
|
-
...retMap.metadata,
|
|
1480
|
-
};
|
|
1481
|
-
const rootSubProjectPurl = new PackageURL(
|
|
1482
|
-
"maven",
|
|
1483
|
-
rootSubProjectObj.group && rootSubProjectObj.group.length
|
|
1484
|
-
? rootSubProjectObj.group
|
|
1485
|
-
: parentComponent.group,
|
|
1486
|
-
rootSubProjectObj.name,
|
|
1487
|
-
retMap.metadata.version && retMap.metadata.version !== "latest"
|
|
1488
|
-
? retMap.metadata.version
|
|
1489
|
-
: parentComponent.version,
|
|
1490
|
-
rootSubProjectObj.qualifiers,
|
|
1491
|
-
null,
|
|
1492
|
-
).toString();
|
|
1493
|
-
rootSubProjectObj["purl"] = rootSubProjectPurl;
|
|
1494
|
-
rootSubProjectObj["bom-ref"] =
|
|
1495
|
-
decodeURIComponent(rootSubProjectPurl);
|
|
1496
|
-
if (!allProjectsAddedPurls.includes(rootSubProjectPurl)) {
|
|
1497
|
-
allProjects.push(rootSubProjectObj);
|
|
1498
|
-
rootDependsOn.push(rootSubProjectPurl);
|
|
1499
|
-
allProjectsAddedPurls.push(rootSubProjectPurl);
|
|
1350
|
+
if (parsedList.dependenciesList && parsedList.dependenciesList) {
|
|
1351
|
+
dependencies = dependencies.concat(parsedList.dependenciesList);
|
|
1500
1352
|
}
|
|
1353
|
+
unlinkSync(tempMvnTree);
|
|
1501
1354
|
}
|
|
1502
1355
|
}
|
|
1503
|
-
// Bug #317 fix
|
|
1504
|
-
parentComponent.components = allProjects.flatMap((s) => {
|
|
1505
|
-
delete s.qualifiers;
|
|
1506
|
-
delete s.evidence;
|
|
1507
|
-
return s;
|
|
1508
|
-
});
|
|
1509
|
-
dependencies.push({
|
|
1510
|
-
ref: parentComponent["bom-ref"],
|
|
1511
|
-
dependsOn: rootDependsOn,
|
|
1512
|
-
});
|
|
1513
1356
|
}
|
|
1514
|
-
}
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
) {
|
|
1521
|
-
const gradleCmd = getGradleCommand(path, null);
|
|
1522
|
-
const defaultDepTaskArgs = ["-q", "--console", "plain", "--build-cache"];
|
|
1523
|
-
allProjects.push(parentComponent);
|
|
1524
|
-
let depTaskWithArgs = ["dependencies"];
|
|
1525
|
-
if (process.env.GRADLE_DEPENDENCY_TASK) {
|
|
1526
|
-
depTaskWithArgs = process.env.GRADLE_DEPENDENCY_TASK.split(" ");
|
|
1527
|
-
}
|
|
1528
|
-
for (const sp of allProjects) {
|
|
1529
|
-
let gradleDepArgs = [
|
|
1530
|
-
sp.purl === parentComponent.purl
|
|
1531
|
-
? depTaskWithArgs[0]
|
|
1532
|
-
: `:${sp.name}:${depTaskWithArgs[0]}`,
|
|
1533
|
-
];
|
|
1534
|
-
gradleDepArgs = gradleDepArgs
|
|
1535
|
-
.concat(depTaskWithArgs.slice(1))
|
|
1536
|
-
.concat(defaultDepTaskArgs);
|
|
1537
|
-
// Support custom GRADLE_ARGS such as --configuration runtimeClassPath (used for all tasks)
|
|
1538
|
-
if (process.env.GRADLE_ARGS) {
|
|
1539
|
-
const addArgs = process.env.GRADLE_ARGS.split(" ");
|
|
1540
|
-
gradleDepArgs = gradleDepArgs.concat(addArgs);
|
|
1541
|
-
}
|
|
1542
|
-
// gradle args only for the dependencies task
|
|
1543
|
-
if (process.env.GRADLE_ARGS_DEPENDENCIES) {
|
|
1544
|
-
const addArgs = process.env.GRADLE_ARGS_DEPENDENCIES.split(" ");
|
|
1545
|
-
gradleDepArgs = gradleDepArgs.concat(addArgs);
|
|
1357
|
+
} // for
|
|
1358
|
+
for (const abjson of bomJsonFiles) {
|
|
1359
|
+
let bomJsonObj = undefined;
|
|
1360
|
+
try {
|
|
1361
|
+
if (DEBUG_MODE) {
|
|
1362
|
+
console.log(`Extracting data from generated bom file ${abjson}`);
|
|
1546
1363
|
}
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
"in",
|
|
1552
|
-
path,
|
|
1364
|
+
bomJsonObj = JSON.parse(
|
|
1365
|
+
readFileSync(abjson, {
|
|
1366
|
+
encoding: "utf-8",
|
|
1367
|
+
}),
|
|
1553
1368
|
);
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
console.error(sresult.stdout, sresult.stderr);
|
|
1369
|
+
if (bomJsonObj) {
|
|
1370
|
+
if (
|
|
1371
|
+
!tools &&
|
|
1372
|
+
bomJsonObj.metadata &&
|
|
1373
|
+
bomJsonObj.metadata.tools &&
|
|
1374
|
+
Array.isArray(bomJsonObj.metadata.tools)
|
|
1375
|
+
) {
|
|
1376
|
+
tools = bomJsonObj.metadata.tools;
|
|
1563
1377
|
}
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
sp.group || parentComponent.group,
|
|
1572
|
-
sp.name,
|
|
1573
|
-
sp.version && sp.version.length && sp.version !== "latest"
|
|
1574
|
-
? sp.version
|
|
1575
|
-
: parentComponent.version,
|
|
1576
|
-
);
|
|
1577
|
-
const dlist = parsedList.pkgList;
|
|
1578
|
-
if (parsedList.dependenciesList && parsedList.dependenciesList) {
|
|
1579
|
-
dependencies = mergeDependencies(
|
|
1580
|
-
dependencies,
|
|
1581
|
-
parsedList.dependenciesList,
|
|
1582
|
-
parentComponent,
|
|
1583
|
-
);
|
|
1378
|
+
if (
|
|
1379
|
+
bomJsonObj.metadata?.component &&
|
|
1380
|
+
!Object.keys(parentComponent).length
|
|
1381
|
+
) {
|
|
1382
|
+
parentComponent = bomJsonObj.metadata.component;
|
|
1383
|
+
options.parentComponent = parentComponent;
|
|
1384
|
+
pkgList = [];
|
|
1584
1385
|
}
|
|
1585
|
-
if (
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1386
|
+
if (bomJsonObj.components) {
|
|
1387
|
+
// Inject evidence into the components. #994
|
|
1388
|
+
if (options.specVersion >= 1.5) {
|
|
1389
|
+
// maven would usually generate a target directory closest to the pom.xml
|
|
1390
|
+
// I am sure there would be cases where this assumption is not true :)
|
|
1391
|
+
const srcPomFile = join(dirname(abjson), "..", "pom.xml");
|
|
1392
|
+
for (const acomp of bomJsonObj.components) {
|
|
1393
|
+
if (!acomp.evidence) {
|
|
1394
|
+
acomp.evidence = {
|
|
1395
|
+
identity: {
|
|
1396
|
+
field: "purl",
|
|
1397
|
+
confidence: 0.8,
|
|
1398
|
+
methods: [
|
|
1399
|
+
{
|
|
1400
|
+
technique: "manifest-analysis",
|
|
1401
|
+
confidence: 0.8,
|
|
1402
|
+
value: srcPomFile,
|
|
1403
|
+
},
|
|
1404
|
+
],
|
|
1405
|
+
},
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1408
|
+
if (!acomp.properties) {
|
|
1409
|
+
acomp.properties = [];
|
|
1410
|
+
}
|
|
1411
|
+
acomp.properties.push({
|
|
1412
|
+
name: "SrcFile",
|
|
1413
|
+
value: srcPomFile,
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1593
1416
|
}
|
|
1594
|
-
pkgList = pkgList.concat(
|
|
1417
|
+
pkgList = pkgList.concat(bomJsonObj.components);
|
|
1595
1418
|
}
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
pkgList = pkgList.filter(
|
|
1602
|
-
(pkg) => pkg["bom-ref"] !== subProj["bom-ref"],
|
|
1419
|
+
if (bomJsonObj.dependencies) {
|
|
1420
|
+
dependencies = mergeDependencies(
|
|
1421
|
+
dependencies,
|
|
1422
|
+
bomJsonObj.dependencies,
|
|
1423
|
+
parentComponent,
|
|
1603
1424
|
);
|
|
1604
1425
|
}
|
|
1605
1426
|
}
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
);
|
|
1611
|
-
} else {
|
|
1612
|
-
console.log(
|
|
1613
|
-
"No packages found. Set the environment variable 'CDXGEN_DEBUG_MODE=debug' to troubleshoot any gradle related errors.",
|
|
1614
|
-
);
|
|
1615
|
-
options.failOnError && process.exit(1);
|
|
1616
|
-
}
|
|
1617
|
-
// Should we attempt to resolve class names
|
|
1618
|
-
if (options.resolveClass || options.deep) {
|
|
1619
|
-
const tmpjarNSMapping = await collectJarNS(GRADLE_CACHE_DIR);
|
|
1620
|
-
if (tmpjarNSMapping && Object.keys(tmpjarNSMapping).length) {
|
|
1621
|
-
jarNSMapping = { ...jarNSMapping, ...tmpjarNSMapping };
|
|
1427
|
+
} catch (err) {
|
|
1428
|
+
if (options.failOnError || DEBUG_MODE) {
|
|
1429
|
+
console.log(err);
|
|
1430
|
+
options.failOnError && process.exit(1);
|
|
1622
1431
|
}
|
|
1623
1432
|
}
|
|
1433
|
+
}
|
|
1434
|
+
if (pkgList) {
|
|
1435
|
+
pkgList = trimComponents(pkgList);
|
|
1624
1436
|
pkgList = await getMvnMetadata(pkgList, jarNSMapping);
|
|
1625
1437
|
return buildBomNSData(options, pkgList, "maven", {
|
|
1626
1438
|
src: path,
|
|
1627
|
-
filename:
|
|
1439
|
+
filename: pomFiles.join(", "),
|
|
1628
1440
|
nsMapping: jarNSMapping,
|
|
1629
1441
|
dependencies,
|
|
1630
1442
|
parentComponent,
|
|
1443
|
+
tools,
|
|
1631
1444
|
});
|
|
1632
1445
|
}
|
|
1446
|
+
if (bomJsonFiles.length) {
|
|
1447
|
+
const bomNSData = {};
|
|
1448
|
+
bomNSData.bomJsonFiles = bomJsonFiles;
|
|
1449
|
+
bomNSData.nsMapping = jarNSMapping;
|
|
1450
|
+
bomNSData.dependencies = dependencies;
|
|
1451
|
+
bomNSData.parentComponent = parentComponent;
|
|
1452
|
+
return bomNSData;
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
// gradle
|
|
1456
|
+
const gradleFiles = getAllFiles(
|
|
1457
|
+
path,
|
|
1458
|
+
`${options.multiProject ? "**/" : ""}build.gradle*`,
|
|
1459
|
+
options,
|
|
1460
|
+
);
|
|
1461
|
+
const allProjects = [];
|
|
1462
|
+
const allProjectsAddedPurls = [];
|
|
1463
|
+
const rootDependsOn = [];
|
|
1464
|
+
// Execute gradle properties
|
|
1465
|
+
if (gradleFiles?.length && !["scala", "sbt"].includes(options.projectType)) {
|
|
1466
|
+
let retMap = executeGradleProperties(path, null, null);
|
|
1467
|
+
const allProjectsStr = retMap.projects || [];
|
|
1468
|
+
const rootProject = retMap.rootProject;
|
|
1469
|
+
if (rootProject) {
|
|
1470
|
+
parentComponent = {
|
|
1471
|
+
name: rootProject,
|
|
1472
|
+
type: "application",
|
|
1473
|
+
...retMap.metadata,
|
|
1474
|
+
};
|
|
1475
|
+
const parentPurl = new PackageURL(
|
|
1476
|
+
"maven",
|
|
1477
|
+
parentComponent.group || "",
|
|
1478
|
+
parentComponent.name,
|
|
1479
|
+
parentComponent.version,
|
|
1480
|
+
{ type: "jar" },
|
|
1481
|
+
null,
|
|
1482
|
+
).toString();
|
|
1483
|
+
parentComponent["purl"] = parentPurl;
|
|
1484
|
+
parentComponent["bom-ref"] = decodeURIComponent(parentPurl);
|
|
1485
|
+
}
|
|
1486
|
+
// Get the sub-project properties and set the root dependencies
|
|
1487
|
+
if (allProjectsStr?.length) {
|
|
1488
|
+
for (const spstr of allProjectsStr) {
|
|
1489
|
+
retMap = executeGradleProperties(path, null, spstr);
|
|
1490
|
+
const rootSubProject = retMap.rootProject;
|
|
1491
|
+
if (rootSubProject) {
|
|
1492
|
+
const rspName = rootSubProject.replace(/^:/, "");
|
|
1493
|
+
const rootSubProjectObj = {
|
|
1494
|
+
name: rspName,
|
|
1495
|
+
type: "application",
|
|
1496
|
+
qualifiers: { type: "jar" },
|
|
1497
|
+
...retMap.metadata,
|
|
1498
|
+
};
|
|
1499
|
+
const rootSubProjectPurl = new PackageURL(
|
|
1500
|
+
"maven",
|
|
1501
|
+
rootSubProjectObj.group?.length
|
|
1502
|
+
? rootSubProjectObj.group
|
|
1503
|
+
: parentComponent.group,
|
|
1504
|
+
rootSubProjectObj.name,
|
|
1505
|
+
retMap.metadata.version && retMap.metadata.version !== "latest"
|
|
1506
|
+
? retMap.metadata.version
|
|
1507
|
+
: parentComponent.version,
|
|
1508
|
+
rootSubProjectObj.qualifiers,
|
|
1509
|
+
null,
|
|
1510
|
+
).toString();
|
|
1511
|
+
rootSubProjectObj["purl"] = rootSubProjectPurl;
|
|
1512
|
+
rootSubProjectObj["bom-ref"] = decodeURIComponent(rootSubProjectPurl);
|
|
1513
|
+
if (!allProjectsAddedPurls.includes(rootSubProjectPurl)) {
|
|
1514
|
+
allProjects.push(rootSubProjectObj);
|
|
1515
|
+
rootDependsOn.push(rootSubProjectPurl);
|
|
1516
|
+
allProjectsAddedPurls.push(rootSubProjectPurl);
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
// Bug #317 fix
|
|
1521
|
+
parentComponent.components = allProjects.flatMap((s) => {
|
|
1522
|
+
delete s.qualifiers;
|
|
1523
|
+
delete s.evidence;
|
|
1524
|
+
return s;
|
|
1525
|
+
});
|
|
1526
|
+
dependencies.push({
|
|
1527
|
+
ref: parentComponent["bom-ref"],
|
|
1528
|
+
dependsOn: rootDependsOn,
|
|
1529
|
+
});
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
if (
|
|
1533
|
+
gradleFiles?.length &&
|
|
1534
|
+
options.installDeps &&
|
|
1535
|
+
!["scala", "sbt"].includes(options.projectType)
|
|
1536
|
+
) {
|
|
1537
|
+
const gradleCmd = getGradleCommand(path, null);
|
|
1538
|
+
const defaultDepTaskArgs = ["-q", "--console", "plain", "--build-cache"];
|
|
1539
|
+
allProjects.push(parentComponent);
|
|
1540
|
+
let depTaskWithArgs = ["dependencies"];
|
|
1541
|
+
if (process.env.GRADLE_DEPENDENCY_TASK) {
|
|
1542
|
+
depTaskWithArgs = process.env.GRADLE_DEPENDENCY_TASK.split(" ");
|
|
1543
|
+
}
|
|
1544
|
+
for (const sp of allProjects) {
|
|
1545
|
+
let gradleDepArgs = [
|
|
1546
|
+
sp.purl === parentComponent.purl
|
|
1547
|
+
? depTaskWithArgs[0]
|
|
1548
|
+
: `:${sp.name}:${depTaskWithArgs[0]}`,
|
|
1549
|
+
];
|
|
1550
|
+
gradleDepArgs = gradleDepArgs
|
|
1551
|
+
.concat(depTaskWithArgs.slice(1))
|
|
1552
|
+
.concat(defaultDepTaskArgs);
|
|
1553
|
+
// Support custom GRADLE_ARGS such as --configuration runtimeClassPath (used for all tasks)
|
|
1554
|
+
if (process.env.GRADLE_ARGS) {
|
|
1555
|
+
const addArgs = process.env.GRADLE_ARGS.split(" ");
|
|
1556
|
+
gradleDepArgs = gradleDepArgs.concat(addArgs);
|
|
1557
|
+
}
|
|
1558
|
+
// gradle args only for the dependencies task
|
|
1559
|
+
if (process.env.GRADLE_ARGS_DEPENDENCIES) {
|
|
1560
|
+
const addArgs = process.env.GRADLE_ARGS_DEPENDENCIES.split(" ");
|
|
1561
|
+
gradleDepArgs = gradleDepArgs.concat(addArgs);
|
|
1562
|
+
}
|
|
1563
|
+
console.log("Executing", gradleCmd, gradleDepArgs.join(" "), "in", path);
|
|
1564
|
+
const sresult = spawnSync(gradleCmd, gradleDepArgs, {
|
|
1565
|
+
cwd: path,
|
|
1566
|
+
encoding: "utf-8",
|
|
1567
|
+
timeout: TIMEOUT_MS,
|
|
1568
|
+
maxBuffer: MAX_BUFFER,
|
|
1569
|
+
});
|
|
1570
|
+
if (sresult.status !== 0 || sresult.error) {
|
|
1571
|
+
if (options.failOnError || DEBUG_MODE) {
|
|
1572
|
+
console.error(sresult.stdout, sresult.stderr);
|
|
1573
|
+
}
|
|
1574
|
+
options.failOnError && process.exit(1);
|
|
1575
|
+
}
|
|
1576
|
+
const sstdout = sresult.stdout;
|
|
1577
|
+
if (sstdout) {
|
|
1578
|
+
const cmdOutput = Buffer.from(sstdout).toString();
|
|
1579
|
+
const parsedList = parseGradleDep(
|
|
1580
|
+
cmdOutput,
|
|
1581
|
+
sp.group || parentComponent.group,
|
|
1582
|
+
sp.name,
|
|
1583
|
+
sp.version?.length && sp.version !== "latest"
|
|
1584
|
+
? sp.version
|
|
1585
|
+
: parentComponent.version,
|
|
1586
|
+
);
|
|
1587
|
+
const dlist = parsedList.pkgList;
|
|
1588
|
+
if (parsedList.dependenciesList && parsedList.dependenciesList) {
|
|
1589
|
+
dependencies = mergeDependencies(
|
|
1590
|
+
dependencies,
|
|
1591
|
+
parsedList.dependenciesList,
|
|
1592
|
+
parentComponent,
|
|
1593
|
+
);
|
|
1594
|
+
}
|
|
1595
|
+
if (dlist?.length) {
|
|
1596
|
+
if (DEBUG_MODE) {
|
|
1597
|
+
console.log(
|
|
1598
|
+
"Found",
|
|
1599
|
+
dlist.length,
|
|
1600
|
+
"packages in gradle project",
|
|
1601
|
+
sp.name,
|
|
1602
|
+
);
|
|
1603
|
+
}
|
|
1604
|
+
pkgList = pkgList.concat(dlist);
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
} // for
|
|
1608
|
+
if (pkgList.length) {
|
|
1609
|
+
if (parentComponent.components?.length) {
|
|
1610
|
+
for (const subProj of parentComponent.components) {
|
|
1611
|
+
pkgList = pkgList.filter(
|
|
1612
|
+
(pkg) => pkg["bom-ref"] !== subProj["bom-ref"],
|
|
1613
|
+
);
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
console.log(
|
|
1617
|
+
"Obtained",
|
|
1618
|
+
pkgList.length,
|
|
1619
|
+
"from this gradle project. De-duping this list ...",
|
|
1620
|
+
);
|
|
1621
|
+
} else {
|
|
1622
|
+
console.log(
|
|
1623
|
+
"No packages found. Set the environment variable 'CDXGEN_DEBUG_MODE=debug' to troubleshoot any gradle related errors.",
|
|
1624
|
+
);
|
|
1625
|
+
options.failOnError && process.exit(1);
|
|
1626
|
+
}
|
|
1627
|
+
// Should we attempt to resolve class names
|
|
1628
|
+
if (options.resolveClass || options.deep) {
|
|
1629
|
+
const tmpjarNSMapping = await collectJarNS(GRADLE_CACHE_DIR);
|
|
1630
|
+
if (tmpjarNSMapping && Object.keys(tmpjarNSMapping).length) {
|
|
1631
|
+
jarNSMapping = { ...jarNSMapping, ...tmpjarNSMapping };
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
pkgList = await getMvnMetadata(pkgList, jarNSMapping);
|
|
1635
|
+
return buildBomNSData(options, pkgList, "maven", {
|
|
1636
|
+
src: path,
|
|
1637
|
+
filename: gradleFiles.join(", "),
|
|
1638
|
+
nsMapping: jarNSMapping,
|
|
1639
|
+
dependencies,
|
|
1640
|
+
parentComponent,
|
|
1641
|
+
});
|
|
1642
|
+
}
|
|
1633
1643
|
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1644
|
+
// Bazel
|
|
1645
|
+
// Look for the BUILD file only in the root directory
|
|
1646
|
+
const bazelFiles = getAllFiles(path, "BUILD", options);
|
|
1647
|
+
if (bazelFiles?.length && !["scala", "sbt"].includes(options.projectType)) {
|
|
1648
|
+
let BAZEL_CMD = "bazel";
|
|
1649
|
+
if (process.env.BAZEL_HOME) {
|
|
1650
|
+
BAZEL_CMD = join(process.env.BAZEL_HOME, "bin", "bazel");
|
|
1651
|
+
}
|
|
1652
|
+
for (const f of bazelFiles) {
|
|
1653
|
+
const basePath = dirname(f);
|
|
1654
|
+
// Invoke bazel build first
|
|
1655
|
+
const bazelTarget = process.env.BAZEL_TARGET || ":all";
|
|
1656
|
+
console.log("Executing", BAZEL_CMD, "build", bazelTarget, "in", basePath);
|
|
1657
|
+
let result = spawnSync(BAZEL_CMD, ["build", bazelTarget], {
|
|
1658
|
+
cwd: basePath,
|
|
1659
|
+
shell: true,
|
|
1660
|
+
encoding: "utf-8",
|
|
1661
|
+
timeout: TIMEOUT_MS,
|
|
1662
|
+
maxBuffer: MAX_BUFFER,
|
|
1663
|
+
});
|
|
1664
|
+
if (result.status !== 0 || result.error) {
|
|
1665
|
+
if (result.stderr) {
|
|
1666
|
+
console.error(result.stdout, result.stderr);
|
|
1667
|
+
}
|
|
1650
1668
|
console.log(
|
|
1651
|
-
"
|
|
1652
|
-
BAZEL_CMD,
|
|
1653
|
-
"build",
|
|
1654
|
-
bazelTarget,
|
|
1655
|
-
"in",
|
|
1656
|
-
basePath,
|
|
1669
|
+
"1. Check if bazel is installed and available in PATH.\n2. Try building your app with bazel prior to invoking cdxgen",
|
|
1657
1670
|
);
|
|
1658
|
-
|
|
1671
|
+
options.failOnError && process.exit(1);
|
|
1672
|
+
} else {
|
|
1673
|
+
const target = process.env.BAZEL_TARGET || "//...";
|
|
1674
|
+
let query;
|
|
1675
|
+
let bazelParser;
|
|
1676
|
+
if (["true", "1"].includes(process.env.BAZEL_USE_ACTION_GRAPH)) {
|
|
1677
|
+
query = ["aquery", `outputs('.*.jar',deps(${target}))`];
|
|
1678
|
+
bazelParser = parseBazelActionGraph;
|
|
1679
|
+
} else {
|
|
1680
|
+
query = ["aquery", "--output=textproto", "--skyframe_state"];
|
|
1681
|
+
bazelParser = parseBazelSkyframe;
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
console.log("Executing", BAZEL_CMD, `${query.join(" ")} in`, basePath);
|
|
1685
|
+
result = spawnSync(BAZEL_CMD, query, {
|
|
1659
1686
|
cwd: basePath,
|
|
1660
|
-
shell: true,
|
|
1661
1687
|
encoding: "utf-8",
|
|
1662
1688
|
timeout: TIMEOUT_MS,
|
|
1663
1689
|
maxBuffer: MAX_BUFFER,
|
|
1664
1690
|
});
|
|
1665
1691
|
if (result.status !== 0 || result.error) {
|
|
1666
|
-
|
|
1667
|
-
console.error(result.stdout, result.stderr);
|
|
1668
|
-
}
|
|
1669
|
-
console.log(
|
|
1670
|
-
"1. Check if bazel is installed and available in PATH.\n2. Try building your app with bazel prior to invoking cdxgen",
|
|
1671
|
-
);
|
|
1692
|
+
console.error(result.stdout, result.stderr);
|
|
1672
1693
|
options.failOnError && process.exit(1);
|
|
1673
|
-
}
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
} else {
|
|
1681
|
-
query = ["aquery", "--output=textproto", "--skyframe_state"];
|
|
1682
|
-
bazelParser = parseBazelSkyframe;
|
|
1683
|
-
}
|
|
1684
|
-
|
|
1685
|
-
console.log(
|
|
1686
|
-
"Executing",
|
|
1687
|
-
BAZEL_CMD,
|
|
1688
|
-
`${query.join(" ")} in`,
|
|
1689
|
-
basePath,
|
|
1690
|
-
);
|
|
1691
|
-
result = spawnSync(BAZEL_CMD, query, {
|
|
1692
|
-
cwd: basePath,
|
|
1693
|
-
encoding: "utf-8",
|
|
1694
|
-
timeout: TIMEOUT_MS,
|
|
1695
|
-
maxBuffer: MAX_BUFFER,
|
|
1696
|
-
});
|
|
1697
|
-
if (result.status !== 0 || result.error) {
|
|
1698
|
-
console.error(result.stdout, result.stderr);
|
|
1699
|
-
options.failOnError && process.exit(1);
|
|
1700
|
-
}
|
|
1701
|
-
const stdout = result.stdout;
|
|
1702
|
-
if (stdout) {
|
|
1703
|
-
const cmdOutput = Buffer.from(stdout).toString();
|
|
1704
|
-
const dlist = bazelParser(cmdOutput);
|
|
1705
|
-
if (dlist && dlist.length) {
|
|
1706
|
-
pkgList = pkgList.concat(dlist);
|
|
1707
|
-
} else {
|
|
1708
|
-
console.log(
|
|
1709
|
-
"No packages were detected.\n1. Build your project using bazel build command before running cdxgen\n2. Try running the bazel aquery command manually to see if skyframe state can be retrieved.",
|
|
1710
|
-
);
|
|
1711
|
-
console.log(
|
|
1712
|
-
"If your project requires a different query, please file a bug at cyclonedx/cdxgen repo!",
|
|
1713
|
-
);
|
|
1714
|
-
options.failOnError && process.exit(1);
|
|
1715
|
-
}
|
|
1694
|
+
}
|
|
1695
|
+
const stdout = result.stdout;
|
|
1696
|
+
if (stdout) {
|
|
1697
|
+
const cmdOutput = Buffer.from(stdout).toString();
|
|
1698
|
+
const dlist = bazelParser(cmdOutput);
|
|
1699
|
+
if (dlist?.length) {
|
|
1700
|
+
pkgList = pkgList.concat(dlist);
|
|
1716
1701
|
} else {
|
|
1717
|
-
console.log(
|
|
1702
|
+
console.log(
|
|
1703
|
+
"No packages were detected.\n1. Build your project using bazel build command before running cdxgen\n2. Try running the bazel aquery command manually to see if skyframe state can be retrieved.",
|
|
1704
|
+
);
|
|
1705
|
+
console.log(
|
|
1706
|
+
"If your project requires a different query, please file a bug at cyclonedx/cdxgen repo!",
|
|
1707
|
+
);
|
|
1718
1708
|
options.failOnError && process.exit(1);
|
|
1719
1709
|
}
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
src: path,
|
|
1724
|
-
filename: "BUILD",
|
|
1725
|
-
nsMapping: {},
|
|
1726
|
-
dependencies,
|
|
1727
|
-
parentComponent,
|
|
1728
|
-
});
|
|
1710
|
+
} else {
|
|
1711
|
+
console.log("Bazel unexpectedly didn't produce any output");
|
|
1712
|
+
options.failOnError && process.exit(1);
|
|
1729
1713
|
}
|
|
1714
|
+
// FIXME: How do we retrieve jarNSMapping for bazel projects?
|
|
1715
|
+
pkgList = await getMvnMetadata(pkgList, jarNSMapping);
|
|
1716
|
+
return buildBomNSData(options, pkgList, "maven", {
|
|
1717
|
+
src: path,
|
|
1718
|
+
filename: "BUILD",
|
|
1719
|
+
nsMapping: {},
|
|
1720
|
+
dependencies,
|
|
1721
|
+
parentComponent,
|
|
1722
|
+
});
|
|
1730
1723
|
}
|
|
1731
1724
|
}
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
// scala sbt
|
|
1728
|
+
// Identify sbt projects via its `project` directory:
|
|
1729
|
+
// - all SBT project _should_ define build.properties file with sbt version info
|
|
1730
|
+
// - SBT projects _typically_ have some configs/plugins defined in .sbt files
|
|
1731
|
+
// - SBT projects that are still on 0.13.x, can still use the old approach,
|
|
1732
|
+
// where configs are defined via Scala files
|
|
1733
|
+
// Detecting one of those should be enough to determine an SBT project.
|
|
1734
|
+
let sbtProjectFiles = getAllFiles(
|
|
1735
|
+
path,
|
|
1736
|
+
`${
|
|
1737
|
+
options.multiProject ? "**/" : ""
|
|
1738
|
+
}project/{build.properties,*.sbt,*.scala}`,
|
|
1739
|
+
options,
|
|
1740
|
+
);
|
|
1732
1741
|
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
//
|
|
1736
|
-
//
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1742
|
+
let sbtProjects = [];
|
|
1743
|
+
for (const i in sbtProjectFiles) {
|
|
1744
|
+
// parent dir of sbtProjectFile is the `project` directory
|
|
1745
|
+
// parent dir of `project` is the sbt root project directory
|
|
1746
|
+
const baseDir = dirname(dirname(sbtProjectFiles[i]));
|
|
1747
|
+
sbtProjects = sbtProjects.concat(baseDir);
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
// Fallback in case sbt's project directory is non-existent
|
|
1751
|
+
if (!sbtProjects.length) {
|
|
1752
|
+
sbtProjectFiles = getAllFiles(
|
|
1741
1753
|
path,
|
|
1742
|
-
|
|
1743
|
-
"project/{build.properties,*.sbt,*.scala}",
|
|
1754
|
+
`${options.multiProject ? "**/" : ""}*.sbt`,
|
|
1744
1755
|
options,
|
|
1745
1756
|
);
|
|
1746
|
-
|
|
1747
|
-
let sbtProjects = [];
|
|
1748
1757
|
for (const i in sbtProjectFiles) {
|
|
1749
|
-
|
|
1750
|
-
// parent dir of `project` is the sbt root project directory
|
|
1751
|
-
const baseDir = dirname(dirname(sbtProjectFiles[i]));
|
|
1758
|
+
const baseDir = dirname(sbtProjectFiles[i]);
|
|
1752
1759
|
sbtProjects = sbtProjects.concat(baseDir);
|
|
1753
1760
|
}
|
|
1761
|
+
}
|
|
1762
|
+
// eliminate duplicates and ignore project directories
|
|
1763
|
+
sbtProjects = [...new Set(sbtProjects)].filter(
|
|
1764
|
+
(p) => !p.endsWith(`${sep}project`) && !p.includes(`target${sep}`),
|
|
1765
|
+
);
|
|
1766
|
+
const sbtLockFiles = getAllFiles(
|
|
1767
|
+
path,
|
|
1768
|
+
`${options.multiProject ? "**/" : ""}build.sbt.lock`,
|
|
1769
|
+
options,
|
|
1770
|
+
);
|
|
1754
1771
|
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
const baseDir = dirname(sbtProjectFiles[i]);
|
|
1764
|
-
sbtProjects = sbtProjects.concat(baseDir);
|
|
1765
|
-
}
|
|
1766
|
-
}
|
|
1767
|
-
// eliminate duplicates and ignore project directories
|
|
1768
|
-
sbtProjects = [...new Set(sbtProjects)].filter(
|
|
1769
|
-
(p) => !p.endsWith(sep + "project") && !p.includes("target" + sep),
|
|
1770
|
-
);
|
|
1771
|
-
const sbtLockFiles = getAllFiles(
|
|
1772
|
-
path,
|
|
1773
|
-
(options.multiProject ? "**/" : "") + "build.sbt.lock",
|
|
1774
|
-
options,
|
|
1775
|
-
);
|
|
1776
|
-
|
|
1777
|
-
if (sbtProjects && sbtProjects.length) {
|
|
1778
|
-
let pkgList = [];
|
|
1779
|
-
// If the project use sbt lock files
|
|
1780
|
-
if (sbtLockFiles && sbtLockFiles.length) {
|
|
1781
|
-
for (const f of sbtLockFiles) {
|
|
1782
|
-
const dlist = parseSbtLock(f);
|
|
1783
|
-
if (dlist && dlist.length) {
|
|
1784
|
-
pkgList = pkgList.concat(dlist);
|
|
1785
|
-
}
|
|
1772
|
+
if (sbtProjects?.length) {
|
|
1773
|
+
let pkgList = [];
|
|
1774
|
+
// If the project use sbt lock files
|
|
1775
|
+
if (sbtLockFiles?.length) {
|
|
1776
|
+
for (const f of sbtLockFiles) {
|
|
1777
|
+
const dlist = parseSbtLock(f);
|
|
1778
|
+
if (dlist?.length) {
|
|
1779
|
+
pkgList = pkgList.concat(dlist);
|
|
1786
1780
|
}
|
|
1787
|
-
}
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1781
|
+
}
|
|
1782
|
+
} else {
|
|
1783
|
+
const SBT_CMD = process.env.SBT_CMD || "sbt";
|
|
1784
|
+
let sbtVersion = determineSbtVersion(path);
|
|
1785
|
+
// If can't find sbt version at the root of repository then search in
|
|
1786
|
+
// sbt project array too because sometimes the project folder isn't at
|
|
1787
|
+
// root of repository
|
|
1788
|
+
if (sbtVersion == null) {
|
|
1789
|
+
for (const i in sbtProjects) {
|
|
1790
|
+
sbtVersion = determineSbtVersion(sbtProjects[i]);
|
|
1791
|
+
if (sbtVersion != null) {
|
|
1792
|
+
break;
|
|
1799
1793
|
}
|
|
1800
1794
|
}
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
}
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1795
|
+
}
|
|
1796
|
+
if (DEBUG_MODE) {
|
|
1797
|
+
console.log(`Detected sbt version: ${sbtVersion}`);
|
|
1798
|
+
}
|
|
1799
|
+
// Introduced in 1.2.0 https://www.scala-sbt.org/1.x/docs/sbt-1.2-Release-Notes.html#addPluginSbtFile+command,
|
|
1800
|
+
// however working properly for real only since 1.3.4: https://github.com/sbt/sbt/releases/tag/v1.3.4
|
|
1801
|
+
const standalonePluginFile =
|
|
1802
|
+
sbtVersion != null &&
|
|
1803
|
+
gte(sbtVersion, "1.3.4") &&
|
|
1804
|
+
lte(sbtVersion, "1.4.0");
|
|
1805
|
+
const useSlashSyntax = gte(sbtVersion, "1.5.0");
|
|
1806
|
+
const isDependencyTreeBuiltIn =
|
|
1807
|
+
sbtVersion != null && gte(sbtVersion, "1.4.0");
|
|
1808
|
+
const tempDir = mkdtempSync(join(tmpdir(), "cdxsbt-"));
|
|
1809
|
+
const tempSbtgDir = mkdtempSync(join(tmpdir(), "cdxsbtg-"));
|
|
1810
|
+
mkdirSync(tempSbtgDir, { recursive: true });
|
|
1811
|
+
// Create temporary plugins file
|
|
1812
|
+
const tempSbtPlugins = join(tempSbtgDir, "dep-plugins.sbt");
|
|
1818
1813
|
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
}
|
|
1814
|
+
// Requires a custom version of `sbt-dependency-graph` that
|
|
1815
|
+
// supports `--append` for `toFile` subtask.
|
|
1816
|
+
let sbtPluginDefinition = `\naddSbtPlugin("io.shiftleft" % "sbt-dependency-graph" % "0.10.0-append-to-file3")\n`;
|
|
1817
|
+
if (isDependencyTreeBuiltIn) {
|
|
1818
|
+
sbtPluginDefinition = "\naddDependencyTreePlugin\n";
|
|
1819
|
+
if (DEBUG_MODE) {
|
|
1820
|
+
console.log("Using addDependencyTreePlugin as the custom plugin");
|
|
1827
1821
|
}
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1822
|
+
}
|
|
1823
|
+
writeFileSync(tempSbtPlugins, sbtPluginDefinition);
|
|
1824
|
+
for (const i in sbtProjects) {
|
|
1825
|
+
const basePath = sbtProjects[i];
|
|
1826
|
+
const dlFile = join(tempDir, `dl-${i}.tmp`);
|
|
1827
|
+
let sbtArgs = [];
|
|
1828
|
+
let pluginFile = null;
|
|
1829
|
+
if (standalonePluginFile) {
|
|
1830
|
+
sbtArgs = [
|
|
1831
|
+
`-addPluginSbtFile=${tempSbtPlugins}`,
|
|
1832
|
+
`"dependencyList::toFile ${dlFile} --force"`,
|
|
1833
|
+
];
|
|
1834
|
+
} else {
|
|
1835
|
+
// write to the existing plugins file
|
|
1836
|
+
if (useSlashSyntax) {
|
|
1835
1837
|
sbtArgs = [
|
|
1836
|
-
|
|
1837
|
-
`"dependencyList::toFile ${dlFile} --force"`,
|
|
1838
|
+
`'set ThisBuild / asciiGraphWidth := 400' "dependencyTree / toFile ${dlFile} --force"`,
|
|
1838
1839
|
];
|
|
1839
1840
|
} else {
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
`'set ThisBuild / asciiGraphWidth := 400' "dependencyTree / toFile ${dlFile} --force"`,
|
|
1844
|
-
];
|
|
1845
|
-
} else {
|
|
1846
|
-
sbtArgs = [
|
|
1847
|
-
`'set asciiGraphWidth in ThisBuild := 400' "dependencyTree::toFile ${dlFile} --force"`,
|
|
1848
|
-
];
|
|
1849
|
-
}
|
|
1850
|
-
pluginFile = addPlugin(basePath, sbtPluginDefinition);
|
|
1841
|
+
sbtArgs = [
|
|
1842
|
+
`'set asciiGraphWidth in ThisBuild := 400' "dependencyTree::toFile ${dlFile} --force"`,
|
|
1843
|
+
];
|
|
1851
1844
|
}
|
|
1845
|
+
pluginFile = addPlugin(basePath, sbtPluginDefinition);
|
|
1846
|
+
}
|
|
1847
|
+
console.log(
|
|
1848
|
+
"Executing",
|
|
1849
|
+
SBT_CMD,
|
|
1850
|
+
sbtArgs.join(" "),
|
|
1851
|
+
"in",
|
|
1852
|
+
basePath,
|
|
1853
|
+
"using plugins",
|
|
1854
|
+
tempSbtgDir,
|
|
1855
|
+
);
|
|
1856
|
+
// Note that the command has to be invoked with `shell: true` to properly execut sbt
|
|
1857
|
+
const result = spawnSync(SBT_CMD, sbtArgs, {
|
|
1858
|
+
cwd: basePath,
|
|
1859
|
+
shell: true,
|
|
1860
|
+
encoding: "utf-8",
|
|
1861
|
+
timeout: TIMEOUT_MS,
|
|
1862
|
+
maxBuffer: MAX_BUFFER,
|
|
1863
|
+
});
|
|
1864
|
+
if (result.status !== 0 || result.error) {
|
|
1865
|
+
console.error(result.stdout, result.stderr);
|
|
1852
1866
|
console.log(
|
|
1853
|
-
"
|
|
1854
|
-
SBT_CMD,
|
|
1855
|
-
sbtArgs.join(" "),
|
|
1856
|
-
"in",
|
|
1857
|
-
basePath,
|
|
1858
|
-
"using plugins",
|
|
1859
|
-
tempSbtgDir,
|
|
1867
|
+
"1. Check if scala and sbt is installed and available in PATH. Only scala 2.10 + sbt 0.13.6+ and 2.12 + sbt 1.0+ is supported for now.",
|
|
1860
1868
|
);
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1869
|
+
console.log(
|
|
1870
|
+
"2. Check if the plugin net.virtual-void:sbt-dependency-graph 0.10.0-RC1 can be used in the environment",
|
|
1871
|
+
);
|
|
1872
|
+
console.log(
|
|
1873
|
+
"3. Consider creating a lockfile using sbt-dependency-lock plugin. See https://github.com/stringbean/sbt-dependency-lock",
|
|
1874
|
+
);
|
|
1875
|
+
options.failOnError && process.exit(1);
|
|
1876
|
+
}
|
|
1877
|
+
if (!standalonePluginFile) {
|
|
1878
|
+
cleanupPlugin(basePath, pluginFile);
|
|
1879
|
+
}
|
|
1880
|
+
if (existsSync(dlFile)) {
|
|
1881
|
+
const retMap = parseSbtTree(dlFile);
|
|
1882
|
+
if (retMap.pkgList?.length) {
|
|
1883
|
+
const tmpParentComponent = retMap.pkgList.splice(0, 1)[0];
|
|
1884
|
+
tmpParentComponent.type = "application";
|
|
1885
|
+
pkgList = pkgList.concat(retMap.pkgList);
|
|
1886
|
+
if (!parentComponent || !Object.keys(parentComponent).length) {
|
|
1887
|
+
parentComponent = tmpParentComponent;
|
|
1888
|
+
}
|
|
1881
1889
|
}
|
|
1882
|
-
if (
|
|
1883
|
-
|
|
1890
|
+
if (retMap.dependenciesList) {
|
|
1891
|
+
dependencies = mergeDependencies(
|
|
1892
|
+
dependencies,
|
|
1893
|
+
retMap.dependenciesList,
|
|
1894
|
+
parentComponent,
|
|
1895
|
+
);
|
|
1884
1896
|
}
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
const tmpParentComponent = retMap.pkgList.splice(0, 1)[0];
|
|
1889
|
-
tmpParentComponent.type = "application";
|
|
1890
|
-
pkgList = pkgList.concat(retMap.pkgList);
|
|
1891
|
-
if (!parentComponent || !Object.keys(parentComponent).length) {
|
|
1892
|
-
parentComponent = tmpParentComponent;
|
|
1893
|
-
}
|
|
1894
|
-
}
|
|
1895
|
-
if (retMap.dependenciesList) {
|
|
1896
|
-
dependencies = mergeDependencies(
|
|
1897
|
-
dependencies,
|
|
1898
|
-
retMap.dependenciesList,
|
|
1899
|
-
parentComponent,
|
|
1900
|
-
);
|
|
1901
|
-
}
|
|
1902
|
-
} else {
|
|
1903
|
-
if (options.failOnError || DEBUG_MODE) {
|
|
1904
|
-
console.log(`sbt dependencyList did not yield ${dlFile}`);
|
|
1905
|
-
}
|
|
1906
|
-
options.failOnError && process.exit(1);
|
|
1897
|
+
} else {
|
|
1898
|
+
if (options.failOnError || DEBUG_MODE) {
|
|
1899
|
+
console.log(`sbt dependencyList did not yield ${dlFile}`);
|
|
1907
1900
|
}
|
|
1901
|
+
options.failOnError && process.exit(1);
|
|
1908
1902
|
}
|
|
1903
|
+
}
|
|
1909
1904
|
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1905
|
+
// Cleanup
|
|
1906
|
+
unlinkSync(tempSbtPlugins);
|
|
1907
|
+
} // else
|
|
1913
1908
|
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
}
|
|
1909
|
+
if (DEBUG_MODE) {
|
|
1910
|
+
console.log(`Found ${pkgList.length} packages`);
|
|
1911
|
+
}
|
|
1912
|
+
// Should we attempt to resolve class names
|
|
1913
|
+
if (options.resolveClass || options.deep) {
|
|
1914
|
+
const tmpjarNSMapping = await collectJarNS(SBT_CACHE_DIR);
|
|
1915
|
+
if (tmpjarNSMapping && Object.keys(tmpjarNSMapping).length) {
|
|
1916
|
+
jarNSMapping = { ...jarNSMapping, ...tmpjarNSMapping };
|
|
1923
1917
|
}
|
|
1924
|
-
pkgList = await getMvnMetadata(pkgList, jarNSMapping);
|
|
1925
|
-
return buildBomNSData(options, pkgList, "maven", {
|
|
1926
|
-
src: path,
|
|
1927
|
-
filename: sbtProjects.join(", "),
|
|
1928
|
-
nsMapping: jarNSMapping,
|
|
1929
|
-
dependencies,
|
|
1930
|
-
parentComponent,
|
|
1931
|
-
});
|
|
1932
1918
|
}
|
|
1919
|
+
pkgList = await getMvnMetadata(pkgList, jarNSMapping);
|
|
1920
|
+
return buildBomNSData(options, pkgList, "maven", {
|
|
1921
|
+
src: path,
|
|
1922
|
+
filename: sbtProjects.join(", "),
|
|
1923
|
+
nsMapping: jarNSMapping,
|
|
1924
|
+
dependencies,
|
|
1925
|
+
parentComponent,
|
|
1926
|
+
});
|
|
1933
1927
|
}
|
|
1934
1928
|
}
|
|
1935
1929
|
|
|
@@ -1953,7 +1947,7 @@ export async function createNodejsBom(path, options) {
|
|
|
1953
1947
|
if (pkgJsonFiles.length) {
|
|
1954
1948
|
for (const pj of pkgJsonFiles) {
|
|
1955
1949
|
const dlist = await parsePkgJson(pj);
|
|
1956
|
-
if (dlist
|
|
1950
|
+
if (dlist?.length) {
|
|
1957
1951
|
pkgList = pkgList.concat(dlist);
|
|
1958
1952
|
}
|
|
1959
1953
|
}
|
|
@@ -1982,17 +1976,17 @@ export async function createNodejsBom(path, options) {
|
|
|
1982
1976
|
}
|
|
1983
1977
|
const yarnLockFiles = getAllFiles(
|
|
1984
1978
|
path,
|
|
1985
|
-
|
|
1979
|
+
`${options.multiProject ? "**/" : ""}yarn.lock`,
|
|
1986
1980
|
options,
|
|
1987
1981
|
);
|
|
1988
1982
|
const shrinkwrapFiles = getAllFiles(
|
|
1989
1983
|
path,
|
|
1990
|
-
|
|
1984
|
+
`${options.multiProject ? "**/" : ""}npm-shrinkwrap.json`,
|
|
1991
1985
|
options,
|
|
1992
1986
|
);
|
|
1993
1987
|
let pkgLockFiles = getAllFiles(
|
|
1994
1988
|
path,
|
|
1995
|
-
|
|
1989
|
+
`${options.multiProject ? "**/" : ""}package-lock.json`,
|
|
1996
1990
|
options,
|
|
1997
1991
|
);
|
|
1998
1992
|
if (shrinkwrapFiles.length) {
|
|
@@ -2000,40 +1994,40 @@ export async function createNodejsBom(path, options) {
|
|
|
2000
1994
|
}
|
|
2001
1995
|
const pnpmLockFiles = getAllFiles(
|
|
2002
1996
|
path,
|
|
2003
|
-
|
|
1997
|
+
`${options.multiProject ? "**/" : ""}pnpm-lock.yaml`,
|
|
2004
1998
|
options,
|
|
2005
1999
|
);
|
|
2006
2000
|
const minJsFiles = getAllFiles(
|
|
2007
2001
|
path,
|
|
2008
|
-
|
|
2002
|
+
`${options.multiProject ? "**/" : ""}*min.js`,
|
|
2009
2003
|
options,
|
|
2010
2004
|
);
|
|
2011
2005
|
const bowerFiles = getAllFiles(
|
|
2012
2006
|
path,
|
|
2013
|
-
|
|
2007
|
+
`${options.multiProject ? "**/" : ""}bower.json`,
|
|
2014
2008
|
options,
|
|
2015
2009
|
);
|
|
2016
2010
|
// Parse min js files
|
|
2017
|
-
if (minJsFiles
|
|
2011
|
+
if (minJsFiles?.length) {
|
|
2018
2012
|
manifestFiles = manifestFiles.concat(minJsFiles);
|
|
2019
2013
|
for (const f of minJsFiles) {
|
|
2020
2014
|
const dlist = await parseMinJs(f);
|
|
2021
|
-
if (dlist
|
|
2015
|
+
if (dlist?.length) {
|
|
2022
2016
|
pkgList = pkgList.concat(dlist);
|
|
2023
2017
|
}
|
|
2024
2018
|
}
|
|
2025
2019
|
}
|
|
2026
2020
|
// Parse bower json files
|
|
2027
|
-
if (bowerFiles
|
|
2021
|
+
if (bowerFiles?.length) {
|
|
2028
2022
|
manifestFiles = manifestFiles.concat(bowerFiles);
|
|
2029
2023
|
for (const f of bowerFiles) {
|
|
2030
2024
|
const dlist = await parseBowerJson(f);
|
|
2031
|
-
if (dlist
|
|
2025
|
+
if (dlist?.length) {
|
|
2032
2026
|
pkgList = pkgList.concat(dlist);
|
|
2033
2027
|
}
|
|
2034
2028
|
}
|
|
2035
2029
|
}
|
|
2036
|
-
if (pnpmLockFiles
|
|
2030
|
+
if (pnpmLockFiles?.length) {
|
|
2037
2031
|
manifestFiles = manifestFiles.concat(pnpmLockFiles);
|
|
2038
2032
|
for (const f of pnpmLockFiles) {
|
|
2039
2033
|
const basePath = dirname(f);
|
|
@@ -2078,7 +2072,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2078
2072
|
// Parse the pnpm file
|
|
2079
2073
|
const parsedList = await parsePnpmLock(f, parentComponent);
|
|
2080
2074
|
const dlist = parsedList.pkgList;
|
|
2081
|
-
if (dlist
|
|
2075
|
+
if (dlist?.length) {
|
|
2082
2076
|
pkgList = pkgList.concat(dlist);
|
|
2083
2077
|
}
|
|
2084
2078
|
if (parsedList.dependenciesList && parsedList.dependenciesList) {
|
|
@@ -2090,7 +2084,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2090
2084
|
}
|
|
2091
2085
|
}
|
|
2092
2086
|
}
|
|
2093
|
-
if (pkgLockFiles
|
|
2087
|
+
if (pkgLockFiles?.length) {
|
|
2094
2088
|
manifestFiles = manifestFiles.concat(pkgLockFiles);
|
|
2095
2089
|
for (const f of pkgLockFiles) {
|
|
2096
2090
|
if (DEBUG_MODE) {
|
|
@@ -2106,7 +2100,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2106
2100
|
} else {
|
|
2107
2101
|
parentSubComponents.push(tmpParentComponent);
|
|
2108
2102
|
}
|
|
2109
|
-
if (dlist
|
|
2103
|
+
if (dlist?.length) {
|
|
2110
2104
|
pkgList = pkgList.concat(dlist);
|
|
2111
2105
|
}
|
|
2112
2106
|
if (parsedList.dependenciesList && parsedList.dependenciesList) {
|
|
@@ -2132,7 +2126,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2132
2126
|
encoding: "utf-8",
|
|
2133
2127
|
},
|
|
2134
2128
|
);
|
|
2135
|
-
if (result.status
|
|
2129
|
+
if (result.status === 1 || result.error) {
|
|
2136
2130
|
console.error(result.stdout, result.stderr);
|
|
2137
2131
|
options.failOnError && process.exit(1);
|
|
2138
2132
|
}
|
|
@@ -2162,7 +2156,8 @@ export async function createNodejsBom(path, options) {
|
|
|
2162
2156
|
src: path,
|
|
2163
2157
|
filename: "shrinkwrap-deps.json",
|
|
2164
2158
|
});
|
|
2165
|
-
}
|
|
2159
|
+
}
|
|
2160
|
+
if (existsSync(pnpmLock)) {
|
|
2166
2161
|
let pkgList = await parsePnpmLock(pnpmLock);
|
|
2167
2162
|
if (allImports && Object.keys(allImports).length) {
|
|
2168
2163
|
pkgList = await addEvidenceForImports(
|
|
@@ -2178,18 +2173,17 @@ export async function createNodejsBom(path, options) {
|
|
|
2178
2173
|
src: path,
|
|
2179
2174
|
filename: "pnpm-lock.yaml",
|
|
2180
2175
|
});
|
|
2181
|
-
} else {
|
|
2182
|
-
console.log(
|
|
2183
|
-
"Neither shrinkwrap file: ",
|
|
2184
|
-
swFile,
|
|
2185
|
-
" nor pnpm lockfile",
|
|
2186
|
-
pnpmLock,
|
|
2187
|
-
"was found!",
|
|
2188
|
-
);
|
|
2189
|
-
options.failOnError && process.exit(1);
|
|
2190
2176
|
}
|
|
2177
|
+
console.log(
|
|
2178
|
+
"Neither shrinkwrap file: ",
|
|
2179
|
+
swFile,
|
|
2180
|
+
" nor pnpm lockfile",
|
|
2181
|
+
pnpmLock,
|
|
2182
|
+
"was found!",
|
|
2183
|
+
);
|
|
2184
|
+
options.failOnError && process.exit(1);
|
|
2191
2185
|
}
|
|
2192
|
-
if (yarnLockFiles
|
|
2186
|
+
if (yarnLockFiles?.length) {
|
|
2193
2187
|
manifestFiles = manifestFiles.concat(yarnLockFiles);
|
|
2194
2188
|
for (const f of yarnLockFiles) {
|
|
2195
2189
|
if (DEBUG_MODE) {
|
|
@@ -2248,7 +2242,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2248
2242
|
// rush.js could include yarn.lock :(
|
|
2249
2243
|
const parsedList = await parseYarnLock(f);
|
|
2250
2244
|
const dlist = parsedList.pkgList;
|
|
2251
|
-
if (dlist
|
|
2245
|
+
if (dlist?.length) {
|
|
2252
2246
|
pkgList = pkgList.concat(dlist);
|
|
2253
2247
|
}
|
|
2254
2248
|
const rdeplist = [];
|
|
@@ -2294,7 +2288,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2294
2288
|
manifestFiles = manifestFiles.concat(pkgJsonFiles);
|
|
2295
2289
|
for (const pkgjf of pkgJsonFiles) {
|
|
2296
2290
|
const dlist = await parsePkgJson(pkgjf);
|
|
2297
|
-
if (dlist
|
|
2291
|
+
if (dlist?.length) {
|
|
2298
2292
|
pkgList = pkgList.concat(dlist);
|
|
2299
2293
|
}
|
|
2300
2294
|
}
|
|
@@ -2356,20 +2350,20 @@ export async function createPythonBom(path, options) {
|
|
|
2356
2350
|
const pipenvMode = existsSync(join(path, "Pipfile"));
|
|
2357
2351
|
let poetryFiles = getAllFiles(
|
|
2358
2352
|
path,
|
|
2359
|
-
|
|
2353
|
+
`${options.multiProject ? "**/" : ""}poetry.lock`,
|
|
2360
2354
|
options,
|
|
2361
2355
|
);
|
|
2362
2356
|
const pdmLockFiles = getAllFiles(
|
|
2363
2357
|
path,
|
|
2364
|
-
|
|
2358
|
+
`${options.multiProject ? "**/" : ""}pdm.lock`,
|
|
2365
2359
|
options,
|
|
2366
2360
|
);
|
|
2367
|
-
if (pdmLockFiles
|
|
2361
|
+
if (pdmLockFiles?.length) {
|
|
2368
2362
|
poetryFiles = poetryFiles.concat(pdmLockFiles);
|
|
2369
2363
|
}
|
|
2370
2364
|
let reqFiles = getAllFiles(
|
|
2371
2365
|
path,
|
|
2372
|
-
|
|
2366
|
+
`${options.multiProject ? "**/" : ""}*requirements*.txt`,
|
|
2373
2367
|
options,
|
|
2374
2368
|
);
|
|
2375
2369
|
reqFiles = reqFiles.filter(
|
|
@@ -2377,22 +2371,22 @@ export async function createPythonBom(path, options) {
|
|
|
2377
2371
|
);
|
|
2378
2372
|
const reqDirFiles = getAllFiles(
|
|
2379
2373
|
path,
|
|
2380
|
-
|
|
2374
|
+
`${options.multiProject ? "**/" : ""}requirements/*.txt`,
|
|
2381
2375
|
options,
|
|
2382
2376
|
);
|
|
2383
2377
|
const metadataFiles = getAllFiles(
|
|
2384
2378
|
path,
|
|
2385
|
-
|
|
2379
|
+
`${options.multiProject ? "**/site-packages/**/" : ""}METADATA`,
|
|
2386
2380
|
options,
|
|
2387
2381
|
);
|
|
2388
2382
|
const whlFiles = getAllFiles(
|
|
2389
2383
|
path,
|
|
2390
|
-
|
|
2384
|
+
`${options.multiProject ? "**/" : ""}*.whl`,
|
|
2391
2385
|
options,
|
|
2392
2386
|
);
|
|
2393
2387
|
const eggInfoFiles = getAllFiles(
|
|
2394
2388
|
path,
|
|
2395
|
-
|
|
2389
|
+
`${options.multiProject ? "**/" : ""}*.egg-info`,
|
|
2396
2390
|
options,
|
|
2397
2391
|
);
|
|
2398
2392
|
const setupPy = join(path, "setup.py");
|
|
@@ -2400,7 +2394,7 @@ export async function createPythonBom(path, options) {
|
|
|
2400
2394
|
const pyProjectMode = existsSync(pyProjectFile);
|
|
2401
2395
|
if (pyProjectMode) {
|
|
2402
2396
|
const tmpParentComponent = parsePyProjectToml(pyProjectFile);
|
|
2403
|
-
if (tmpParentComponent
|
|
2397
|
+
if (tmpParentComponent?.name) {
|
|
2404
2398
|
parentComponent = tmpParentComponent;
|
|
2405
2399
|
delete parentComponent.homepage;
|
|
2406
2400
|
delete parentComponent.repository;
|
|
@@ -2417,9 +2411,8 @@ export async function createPythonBom(path, options) {
|
|
|
2417
2411
|
parentComponent["purl"] = ppurl;
|
|
2418
2412
|
}
|
|
2419
2413
|
}
|
|
2420
|
-
const requirementsMode =
|
|
2421
|
-
|
|
2422
|
-
const poetryMode = poetryFiles && poetryFiles.length;
|
|
2414
|
+
const requirementsMode = reqFiles?.length || reqDirFiles?.length;
|
|
2415
|
+
const poetryMode = poetryFiles?.length;
|
|
2423
2416
|
const setupPyMode = existsSync(setupPy);
|
|
2424
2417
|
// Poetry sets up its own virtual env containing site-packages so
|
|
2425
2418
|
// we give preference to poetry lock file. Issue# 129
|
|
@@ -2428,11 +2421,11 @@ export async function createPythonBom(path, options) {
|
|
|
2428
2421
|
const basePath = dirname(f);
|
|
2429
2422
|
const lockData = readFileSync(f, { encoding: "utf-8" });
|
|
2430
2423
|
let retMap = await parsePoetrylockData(lockData, f);
|
|
2431
|
-
if (retMap.pkgList
|
|
2424
|
+
if (retMap.pkgList?.length) {
|
|
2432
2425
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
2433
2426
|
pkgList = trimComponents(pkgList);
|
|
2434
2427
|
}
|
|
2435
|
-
if (retMap.dependenciesList
|
|
2428
|
+
if (retMap.dependenciesList?.length) {
|
|
2436
2429
|
dependencies = mergeDependencies(
|
|
2437
2430
|
dependencies,
|
|
2438
2431
|
retMap.dependenciesList,
|
|
@@ -2443,7 +2436,7 @@ export async function createPythonBom(path, options) {
|
|
|
2443
2436
|
// This is a slow operation
|
|
2444
2437
|
if (options.deep || !dependencies.length) {
|
|
2445
2438
|
retMap = getPipFrozenTree(basePath, f, tempDir);
|
|
2446
|
-
if (retMap.pkgList
|
|
2439
|
+
if (retMap.pkgList?.length) {
|
|
2447
2440
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
2448
2441
|
}
|
|
2449
2442
|
if (retMap.dependenciesList) {
|
|
@@ -2471,35 +2464,36 @@ export async function createPythonBom(path, options) {
|
|
|
2471
2464
|
dependencies,
|
|
2472
2465
|
parentComponent,
|
|
2473
2466
|
});
|
|
2474
|
-
}
|
|
2467
|
+
}
|
|
2468
|
+
if (metadataFiles?.length) {
|
|
2475
2469
|
// dist-info directories
|
|
2476
2470
|
for (const mf of metadataFiles) {
|
|
2477
2471
|
const mData = readFileSync(mf, {
|
|
2478
2472
|
encoding: "utf-8",
|
|
2479
2473
|
});
|
|
2480
2474
|
const dlist = parseBdistMetadata(mData);
|
|
2481
|
-
if (dlist
|
|
2475
|
+
if (dlist?.length) {
|
|
2482
2476
|
pkgList = pkgList.concat(dlist);
|
|
2483
2477
|
}
|
|
2484
2478
|
}
|
|
2485
2479
|
}
|
|
2486
2480
|
// .whl files. Zip file containing dist-info directory
|
|
2487
|
-
if (whlFiles
|
|
2481
|
+
if (whlFiles?.length) {
|
|
2488
2482
|
for (const wf of whlFiles) {
|
|
2489
2483
|
const mData = await readZipEntry(wf, "METADATA");
|
|
2490
2484
|
if (mData) {
|
|
2491
2485
|
const dlist = parseBdistMetadata(mData);
|
|
2492
|
-
if (dlist
|
|
2486
|
+
if (dlist?.length) {
|
|
2493
2487
|
pkgList = pkgList.concat(dlist);
|
|
2494
2488
|
}
|
|
2495
2489
|
}
|
|
2496
2490
|
}
|
|
2497
2491
|
}
|
|
2498
2492
|
// .egg-info files
|
|
2499
|
-
if (eggInfoFiles
|
|
2493
|
+
if (eggInfoFiles?.length) {
|
|
2500
2494
|
for (const ef of eggInfoFiles) {
|
|
2501
2495
|
const dlist = parseBdistMetadata(readFileSync(ef, { encoding: "utf-8" }));
|
|
2502
|
-
if (dlist
|
|
2496
|
+
if (dlist?.length) {
|
|
2503
2497
|
pkgList = pkgList.concat(dlist);
|
|
2504
2498
|
}
|
|
2505
2499
|
}
|
|
@@ -2511,7 +2505,7 @@ export async function createPythonBom(path, options) {
|
|
|
2511
2505
|
if (existsSync(piplockFile)) {
|
|
2512
2506
|
const lockData = JSON.parse(readFileSync(piplockFile));
|
|
2513
2507
|
const dlist = await parsePiplockData(lockData);
|
|
2514
|
-
if (dlist
|
|
2508
|
+
if (dlist?.length) {
|
|
2515
2509
|
pkgList = pkgList.concat(dlist);
|
|
2516
2510
|
}
|
|
2517
2511
|
} else {
|
|
@@ -2520,7 +2514,7 @@ export async function createPythonBom(path, options) {
|
|
|
2520
2514
|
}
|
|
2521
2515
|
} else if (requirementsMode) {
|
|
2522
2516
|
metadataFilename = "requirements.txt";
|
|
2523
|
-
if (reqFiles
|
|
2517
|
+
if (reqFiles?.length) {
|
|
2524
2518
|
if (options.installDeps && DEBUG_MODE) {
|
|
2525
2519
|
console.log(
|
|
2526
2520
|
"cdxgen will now attempt to generate an SBOM for 'build' lifecycle phase for Python. This would take some time ...\nTo speed up this step, invoke cdxgen from within a virtual environment with all the dependencies installed.\nAlternatively, pass the argument '--lifecycle pre-build' to generate a faster but less precise SBOM without installing the dependencies in case of any build issues.",
|
|
@@ -2535,7 +2529,7 @@ export async function createPythonBom(path, options) {
|
|
|
2535
2529
|
// If there are multiple requirements files then the tree is getting constructed for each one
|
|
2536
2530
|
// adding to the delay.
|
|
2537
2531
|
const pkgMap = getPipFrozenTree(basePath, f, tempDir);
|
|
2538
|
-
if (pkgMap.pkgList
|
|
2532
|
+
if (pkgMap.pkgList?.length) {
|
|
2539
2533
|
pkgList = pkgList.concat(pkgMap.pkgList);
|
|
2540
2534
|
frozen = pkgMap.frozen;
|
|
2541
2535
|
}
|
|
@@ -2556,18 +2550,18 @@ export async function createPythonBom(path, options) {
|
|
|
2556
2550
|
}
|
|
2557
2551
|
reqData = readFileSync(f, { encoding: "utf-8" });
|
|
2558
2552
|
const dlist = await parseReqFile(reqData, true);
|
|
2559
|
-
if (dlist
|
|
2553
|
+
if (dlist?.length) {
|
|
2560
2554
|
pkgList = pkgList.concat(dlist);
|
|
2561
2555
|
}
|
|
2562
2556
|
}
|
|
2563
2557
|
} // for
|
|
2564
2558
|
metadataFilename = reqFiles.join(", ");
|
|
2565
|
-
} else if (reqDirFiles
|
|
2559
|
+
} else if (reqDirFiles?.length) {
|
|
2566
2560
|
for (const j in reqDirFiles) {
|
|
2567
2561
|
const f = reqDirFiles[j];
|
|
2568
2562
|
const reqData = readFileSync(f, { encoding: "utf-8" });
|
|
2569
2563
|
const dlist = await parseReqFile(reqData, false);
|
|
2570
|
-
if (dlist
|
|
2564
|
+
if (dlist?.length) {
|
|
2571
2565
|
pkgList = pkgList.concat(dlist);
|
|
2572
2566
|
}
|
|
2573
2567
|
}
|
|
@@ -2593,7 +2587,7 @@ export async function createPythonBom(path, options) {
|
|
|
2593
2587
|
const parentDependsOn = new Set();
|
|
2594
2588
|
const retMap = await getPyModules(path, pkgList, options);
|
|
2595
2589
|
// We need to patch the existing package list to add ImportedModules for evinse to work
|
|
2596
|
-
if (retMap.modList
|
|
2590
|
+
if (retMap.modList?.length) {
|
|
2597
2591
|
const iSymbolsMap = {};
|
|
2598
2592
|
retMap.modList.forEach((v) => {
|
|
2599
2593
|
iSymbolsMap[v.name] = v.importedSymbols;
|
|
@@ -2609,7 +2603,7 @@ export async function createPythonBom(path, options) {
|
|
|
2609
2603
|
}
|
|
2610
2604
|
}
|
|
2611
2605
|
}
|
|
2612
|
-
if (retMap.pkgList
|
|
2606
|
+
if (retMap.pkgList?.length) {
|
|
2613
2607
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
2614
2608
|
for (const p of retMap.pkgList) {
|
|
2615
2609
|
if (
|
|
@@ -2644,7 +2638,7 @@ export async function createPythonBom(path, options) {
|
|
|
2644
2638
|
}
|
|
2645
2639
|
parentDependsOn.add(`pkg:pypi/${p.name}@${p.version}`);
|
|
2646
2640
|
}
|
|
2647
|
-
if (pkgMap.pkgList
|
|
2641
|
+
if (pkgMap.pkgList?.length) {
|
|
2648
2642
|
pkgList = pkgList.concat(pkgMap.pkgList);
|
|
2649
2643
|
}
|
|
2650
2644
|
if (pkgMap.dependenciesList) {
|
|
@@ -2677,12 +2671,12 @@ export async function createPythonBom(path, options) {
|
|
|
2677
2671
|
if (!pkgList.length && setupPyMode) {
|
|
2678
2672
|
const setupPyData = readFileSync(setupPy, { encoding: "utf-8" });
|
|
2679
2673
|
const dlist = await parseSetupPyFile(setupPyData);
|
|
2680
|
-
if (dlist
|
|
2674
|
+
if (dlist?.length) {
|
|
2681
2675
|
pkgList = pkgList.concat(dlist);
|
|
2682
2676
|
}
|
|
2683
2677
|
}
|
|
2684
2678
|
// Clean up
|
|
2685
|
-
if (tempDir
|
|
2679
|
+
if (tempDir?.startsWith(tmpdir()) && rmSync) {
|
|
2686
2680
|
rmSync(tempDir, { recursive: true, force: true });
|
|
2687
2681
|
}
|
|
2688
2682
|
if (FETCH_LICENSE) {
|
|
@@ -2722,7 +2716,7 @@ export async function createGoBom(path, options) {
|
|
|
2722
2716
|
// Read in go.sum and merge all go.sum files.
|
|
2723
2717
|
const gosumFiles = getAllFiles(
|
|
2724
2718
|
path,
|
|
2725
|
-
|
|
2719
|
+
`${options.multiProject ? "**/" : ""}go.sum`,
|
|
2726
2720
|
options,
|
|
2727
2721
|
);
|
|
2728
2722
|
|
|
@@ -2740,7 +2734,7 @@ export async function createGoBom(path, options) {
|
|
|
2740
2734
|
}
|
|
2741
2735
|
const gosumData = readFileSync(f, { encoding: "utf-8" });
|
|
2742
2736
|
const dlist = await parseGosumData(gosumData);
|
|
2743
|
-
if (dlist
|
|
2737
|
+
if (dlist?.length) {
|
|
2744
2738
|
pkgList = pkgList.concat(dlist);
|
|
2745
2739
|
}
|
|
2746
2740
|
}
|
|
@@ -2799,7 +2793,7 @@ export async function createGoBom(path, options) {
|
|
|
2799
2793
|
// whyPkg would include this package string
|
|
2800
2794
|
// github.com/golang/protobuf/proto github.com/golang/protobuf
|
|
2801
2795
|
// golang.org/x/tools/cmd/goimports golang.org/x/tools
|
|
2802
|
-
if (whyPkg
|
|
2796
|
+
if (whyPkg?.includes(pkgFullName)) {
|
|
2803
2797
|
allImports[pkgFullName] = true;
|
|
2804
2798
|
}
|
|
2805
2799
|
doneList[pkgFullName] = true;
|
|
@@ -2826,7 +2820,7 @@ export async function createGoBom(path, options) {
|
|
|
2826
2820
|
}
|
|
2827
2821
|
const gosumData = readFileSync(f, { encoding: "utf-8" });
|
|
2828
2822
|
const dlist = await parseGosumData(gosumData);
|
|
2829
|
-
if (dlist
|
|
2823
|
+
if (dlist?.length) {
|
|
2830
2824
|
dlist.forEach((pkg) => {
|
|
2831
2825
|
gosumMap[`${pkg.name}@${pkg.version}`] = pkg._integrity;
|
|
2832
2826
|
});
|
|
@@ -2837,14 +2831,14 @@ export async function createGoBom(path, options) {
|
|
|
2837
2831
|
// Read in data from Gopkg.lock files if they exist
|
|
2838
2832
|
const gopkgLockFiles = getAllFiles(
|
|
2839
2833
|
path,
|
|
2840
|
-
|
|
2834
|
+
`${options.multiProject ? "**/" : ""}Gopkg.lock`,
|
|
2841
2835
|
options,
|
|
2842
2836
|
);
|
|
2843
2837
|
|
|
2844
2838
|
// Read in go.mod files and parse BOM components with checksums from gosumData
|
|
2845
2839
|
const gomodFiles = getAllFiles(
|
|
2846
2840
|
path,
|
|
2847
|
-
|
|
2841
|
+
`${options.multiProject ? "**/" : ""}go.mod`,
|
|
2848
2842
|
options,
|
|
2849
2843
|
);
|
|
2850
2844
|
if (gomodFiles.length) {
|
|
@@ -2894,7 +2888,7 @@ export async function createGoBom(path, options) {
|
|
|
2894
2888
|
if (stdout) {
|
|
2895
2889
|
let cmdOutput = Buffer.from(stdout).toString();
|
|
2896
2890
|
const retMap = await parseGoListDep(cmdOutput, gosumMap);
|
|
2897
|
-
if (retMap.pkgList
|
|
2891
|
+
if (retMap.pkgList?.length) {
|
|
2898
2892
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
2899
2893
|
}
|
|
2900
2894
|
// We treat the main module as our parent
|
|
@@ -2931,11 +2925,11 @@ export async function createGoBom(path, options) {
|
|
|
2931
2925
|
pkgList,
|
|
2932
2926
|
parentComponent,
|
|
2933
2927
|
);
|
|
2934
|
-
if (retMap.pkgList
|
|
2928
|
+
if (retMap.pkgList?.length) {
|
|
2935
2929
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
2936
2930
|
pkgList = trimComponents(pkgList);
|
|
2937
2931
|
}
|
|
2938
|
-
if (retMap.dependenciesList
|
|
2932
|
+
if (retMap.dependenciesList?.length) {
|
|
2939
2933
|
dependencies = mergeDependencies(
|
|
2940
2934
|
dependencies,
|
|
2941
2935
|
retMap.dependenciesList,
|
|
@@ -2973,7 +2967,7 @@ export async function createGoBom(path, options) {
|
|
|
2973
2967
|
}
|
|
2974
2968
|
const gomodData = readFileSync(f, { encoding: "utf-8" });
|
|
2975
2969
|
const dlist = await parseGoModData(gomodData, gosumMap);
|
|
2976
|
-
if (dlist
|
|
2970
|
+
if (dlist?.length) {
|
|
2977
2971
|
pkgList = pkgList.concat(dlist);
|
|
2978
2972
|
}
|
|
2979
2973
|
}
|
|
@@ -2983,7 +2977,8 @@ export async function createGoBom(path, options) {
|
|
|
2983
2977
|
parentComponent,
|
|
2984
2978
|
filename: gomodFiles.join(", "),
|
|
2985
2979
|
});
|
|
2986
|
-
}
|
|
2980
|
+
}
|
|
2981
|
+
if (gopkgLockFiles.length) {
|
|
2987
2982
|
for (const f of gopkgLockFiles) {
|
|
2988
2983
|
if (DEBUG_MODE) {
|
|
2989
2984
|
console.log(`Parsing ${f}`);
|
|
@@ -2992,7 +2987,7 @@ export async function createGoBom(path, options) {
|
|
|
2992
2987
|
encoding: "utf-8",
|
|
2993
2988
|
});
|
|
2994
2989
|
const dlist = await parseGopkgData(gopkgData);
|
|
2995
|
-
if (dlist
|
|
2990
|
+
if (dlist?.length) {
|
|
2996
2991
|
pkgList = pkgList.concat(dlist);
|
|
2997
2992
|
}
|
|
2998
2993
|
}
|
|
@@ -3025,7 +3020,7 @@ export async function createRustBom(path, options) {
|
|
|
3025
3020
|
if (maybeBinary) {
|
|
3026
3021
|
const cargoData = getCargoAuditableInfo(path);
|
|
3027
3022
|
const dlist = await parseCargoAuditableData(cargoData);
|
|
3028
|
-
if (dlist
|
|
3023
|
+
if (dlist?.length) {
|
|
3029
3024
|
pkgList = pkgList.concat(dlist);
|
|
3030
3025
|
}
|
|
3031
3026
|
// Since this pkg list is derived from the binary mark them as used.
|
|
@@ -3042,12 +3037,12 @@ export async function createRustBom(path, options) {
|
|
|
3042
3037
|
}
|
|
3043
3038
|
let cargoLockFiles = getAllFiles(
|
|
3044
3039
|
path,
|
|
3045
|
-
|
|
3040
|
+
`${options.multiProject ? "**/" : ""}Cargo.lock`,
|
|
3046
3041
|
options,
|
|
3047
3042
|
);
|
|
3048
3043
|
const cargoFiles = getAllFiles(
|
|
3049
3044
|
path,
|
|
3050
|
-
|
|
3045
|
+
`${options.multiProject ? "**/" : ""}Cargo.toml`,
|
|
3051
3046
|
options,
|
|
3052
3047
|
);
|
|
3053
3048
|
// This function assumes that the given path is prioritized, i.e that the
|
|
@@ -3064,7 +3059,7 @@ export async function createRustBom(path, options) {
|
|
|
3064
3059
|
console.log(`Parsing ${f}`);
|
|
3065
3060
|
}
|
|
3066
3061
|
const dlist = await parseCargoTomlData(f, cargoLockMode);
|
|
3067
|
-
if (dlist
|
|
3062
|
+
if (dlist?.length) {
|
|
3068
3063
|
if (!cargoLockMode) {
|
|
3069
3064
|
pkgList = pkgList.concat(dlist);
|
|
3070
3065
|
} else {
|
|
@@ -3087,7 +3082,7 @@ export async function createRustBom(path, options) {
|
|
|
3087
3082
|
// Get the new lock files
|
|
3088
3083
|
cargoLockFiles = getAllFiles(
|
|
3089
3084
|
path,
|
|
3090
|
-
|
|
3085
|
+
`${options.multiProject ? "**/" : ""}Cargo.lock`,
|
|
3091
3086
|
options,
|
|
3092
3087
|
);
|
|
3093
3088
|
let dependencyTree = [];
|
|
@@ -3097,7 +3092,7 @@ export async function createRustBom(path, options) {
|
|
|
3097
3092
|
console.log(`Parsing ${f}`);
|
|
3098
3093
|
}
|
|
3099
3094
|
const dlist = await parseCargoData(f);
|
|
3100
|
-
if (dlist
|
|
3095
|
+
if (dlist?.length) {
|
|
3101
3096
|
pkgList = pkgList.concat(dlist);
|
|
3102
3097
|
}
|
|
3103
3098
|
|
|
@@ -3106,7 +3101,7 @@ export async function createRustBom(path, options) {
|
|
|
3106
3101
|
}
|
|
3107
3102
|
const cargoLockData = readFileSync(f, { encoding: "utf-8" });
|
|
3108
3103
|
const fileDependencylist = parseCargoDependencyData(cargoLockData);
|
|
3109
|
-
if (fileDependencylist
|
|
3104
|
+
if (fileDependencylist?.length) {
|
|
3110
3105
|
dependencyTree = mergeDependencies(
|
|
3111
3106
|
dependencyTree,
|
|
3112
3107
|
fileDependencylist,
|
|
@@ -3133,12 +3128,12 @@ export async function createRustBom(path, options) {
|
|
|
3133
3128
|
export async function createDartBom(path, options) {
|
|
3134
3129
|
const pubFiles = getAllFiles(
|
|
3135
3130
|
path,
|
|
3136
|
-
|
|
3131
|
+
`${options.multiProject ? "**/" : ""}pubspec.lock`,
|
|
3137
3132
|
options,
|
|
3138
3133
|
);
|
|
3139
3134
|
const pubSpecYamlFiles = getAllFiles(
|
|
3140
3135
|
path,
|
|
3141
|
-
|
|
3136
|
+
`${options.multiProject ? "**/" : ""}pubspec.yaml`,
|
|
3142
3137
|
options,
|
|
3143
3138
|
);
|
|
3144
3139
|
let pkgList = [];
|
|
@@ -3149,7 +3144,7 @@ export async function createDartBom(path, options) {
|
|
|
3149
3144
|
}
|
|
3150
3145
|
const pubLockData = readFileSync(f, { encoding: "utf-8" });
|
|
3151
3146
|
const dlist = await parsePubLockData(pubLockData);
|
|
3152
|
-
if (dlist
|
|
3147
|
+
if (dlist?.length) {
|
|
3153
3148
|
pkgList = pkgList.concat(dlist);
|
|
3154
3149
|
}
|
|
3155
3150
|
}
|
|
@@ -3157,14 +3152,15 @@ export async function createDartBom(path, options) {
|
|
|
3157
3152
|
src: path,
|
|
3158
3153
|
filename: pubFiles.join(", "),
|
|
3159
3154
|
});
|
|
3160
|
-
}
|
|
3155
|
+
}
|
|
3156
|
+
if (pubSpecYamlFiles.length) {
|
|
3161
3157
|
for (const f of pubSpecYamlFiles) {
|
|
3162
3158
|
if (DEBUG_MODE) {
|
|
3163
3159
|
console.log(`Parsing ${f}`);
|
|
3164
3160
|
}
|
|
3165
3161
|
const pubYamlData = readFileSync(f, { encoding: "utf-8" });
|
|
3166
3162
|
const dlist = parsePubYamlData(pubYamlData);
|
|
3167
|
-
if (dlist
|
|
3163
|
+
if (dlist?.length) {
|
|
3168
3164
|
pkgList = pkgList.concat(dlist);
|
|
3169
3165
|
}
|
|
3170
3166
|
}
|
|
@@ -3189,36 +3185,36 @@ export function createCppBom(path, options) {
|
|
|
3189
3185
|
const addedParentComponentsMap = {};
|
|
3190
3186
|
const conanLockFiles = getAllFiles(
|
|
3191
3187
|
path,
|
|
3192
|
-
|
|
3188
|
+
`${options.multiProject ? "**/" : ""}conan.lock`,
|
|
3193
3189
|
options,
|
|
3194
3190
|
);
|
|
3195
3191
|
const conanFiles = getAllFiles(
|
|
3196
3192
|
path,
|
|
3197
|
-
|
|
3193
|
+
`${options.multiProject ? "**/" : ""}conanfile.txt`,
|
|
3198
3194
|
options,
|
|
3199
3195
|
);
|
|
3200
3196
|
let cmakeLikeFiles = [];
|
|
3201
3197
|
const mesonBuildFiles = getAllFiles(
|
|
3202
3198
|
path,
|
|
3203
|
-
|
|
3199
|
+
`${options.multiProject ? "**/" : ""}meson.build`,
|
|
3204
3200
|
options,
|
|
3205
3201
|
);
|
|
3206
|
-
if (mesonBuildFiles
|
|
3202
|
+
if (mesonBuildFiles?.length) {
|
|
3207
3203
|
cmakeLikeFiles = cmakeLikeFiles.concat(mesonBuildFiles);
|
|
3208
3204
|
}
|
|
3209
3205
|
cmakeLikeFiles = cmakeLikeFiles.concat(
|
|
3210
3206
|
getAllFiles(
|
|
3211
3207
|
path,
|
|
3212
|
-
|
|
3208
|
+
`${options.multiProject ? "**/" : ""}CMakeLists.txt`,
|
|
3213
3209
|
options,
|
|
3214
3210
|
),
|
|
3215
3211
|
);
|
|
3216
3212
|
const cmakeFiles = getAllFiles(
|
|
3217
3213
|
path,
|
|
3218
|
-
|
|
3214
|
+
`${options.multiProject ? "**/" : ""}*.cmake`,
|
|
3219
3215
|
options,
|
|
3220
3216
|
);
|
|
3221
|
-
if (cmakeFiles
|
|
3217
|
+
if (cmakeFiles?.length) {
|
|
3222
3218
|
cmakeLikeFiles = cmakeLikeFiles.concat(cmakeFiles);
|
|
3223
3219
|
}
|
|
3224
3220
|
let pkgList = [];
|
|
@@ -3229,7 +3225,7 @@ export function createCppBom(path, options) {
|
|
|
3229
3225
|
}
|
|
3230
3226
|
const conanLockData = readFileSync(f, { encoding: "utf-8" });
|
|
3231
3227
|
const dlist = parseConanLockData(conanLockData);
|
|
3232
|
-
if (dlist
|
|
3228
|
+
if (dlist?.length) {
|
|
3233
3229
|
pkgList = pkgList.concat(dlist);
|
|
3234
3230
|
}
|
|
3235
3231
|
}
|
|
@@ -3240,7 +3236,7 @@ export function createCppBom(path, options) {
|
|
|
3240
3236
|
}
|
|
3241
3237
|
const conanData = readFileSync(f, { encoding: "utf-8" });
|
|
3242
3238
|
const dlist = parseConanData(conanData);
|
|
3243
|
-
if (dlist
|
|
3239
|
+
if (dlist?.length) {
|
|
3244
3240
|
pkgList = pkgList.concat(dlist);
|
|
3245
3241
|
}
|
|
3246
3242
|
}
|
|
@@ -3252,7 +3248,7 @@ export function createCppBom(path, options) {
|
|
|
3252
3248
|
}
|
|
3253
3249
|
const basePath = dirname(f);
|
|
3254
3250
|
const retMap = parseCmakeLikeFile(f, "generic");
|
|
3255
|
-
if (retMap.pkgList
|
|
3251
|
+
if (retMap.pkgList?.length) {
|
|
3256
3252
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
3257
3253
|
}
|
|
3258
3254
|
if (
|
|
@@ -3312,7 +3308,7 @@ export function createCppBom(path, options) {
|
|
|
3312
3308
|
results,
|
|
3313
3309
|
true,
|
|
3314
3310
|
);
|
|
3315
|
-
if (dlist
|
|
3311
|
+
if (dlist?.length) {
|
|
3316
3312
|
osPkgsList = osPkgsList.concat(dlist);
|
|
3317
3313
|
}
|
|
3318
3314
|
}
|
|
@@ -3320,7 +3316,7 @@ export function createCppBom(path, options) {
|
|
|
3320
3316
|
// We pass the current list of packages so that we enhance the current list and replace
|
|
3321
3317
|
// components inadvertently. For example, we might resolved a name, version and url information already via cmake
|
|
3322
3318
|
const retMap = getCppModules(path, options, osPkgsList, pkgList);
|
|
3323
|
-
if (retMap.pkgList
|
|
3319
|
+
if (retMap.pkgList?.length) {
|
|
3324
3320
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
3325
3321
|
}
|
|
3326
3322
|
if (retMap.dependenciesList) {
|
|
@@ -3366,12 +3362,12 @@ export function createCppBom(path, options) {
|
|
|
3366
3362
|
export function createClojureBom(path, options) {
|
|
3367
3363
|
const ednFiles = getAllFiles(
|
|
3368
3364
|
path,
|
|
3369
|
-
|
|
3365
|
+
`${options.multiProject ? "**/" : ""}deps.edn`,
|
|
3370
3366
|
options,
|
|
3371
3367
|
);
|
|
3372
3368
|
const leinFiles = getAllFiles(
|
|
3373
3369
|
path,
|
|
3374
|
-
|
|
3370
|
+
`${options.multiProject ? "**/" : ""}project.clj`,
|
|
3375
3371
|
options,
|
|
3376
3372
|
);
|
|
3377
3373
|
let pkgList = [];
|
|
@@ -3405,7 +3401,7 @@ export function createClojureBom(path, options) {
|
|
|
3405
3401
|
}
|
|
3406
3402
|
const leinData = readFileSync(f, { encoding: "utf-8" });
|
|
3407
3403
|
const dlist = parseLeiningenData(leinData);
|
|
3408
|
-
if (dlist
|
|
3404
|
+
if (dlist?.length) {
|
|
3409
3405
|
pkgList = pkgList.concat(dlist);
|
|
3410
3406
|
}
|
|
3411
3407
|
} else {
|
|
@@ -3413,7 +3409,7 @@ export function createClojureBom(path, options) {
|
|
|
3413
3409
|
if (stdout) {
|
|
3414
3410
|
const cmdOutput = Buffer.from(stdout).toString();
|
|
3415
3411
|
const dlist = parseLeinDep(cmdOutput);
|
|
3416
|
-
if (dlist
|
|
3412
|
+
if (dlist?.length) {
|
|
3417
3413
|
pkgList = pkgList.concat(dlist);
|
|
3418
3414
|
}
|
|
3419
3415
|
} else {
|
|
@@ -3426,7 +3422,8 @@ export function createClojureBom(path, options) {
|
|
|
3426
3422
|
src: path,
|
|
3427
3423
|
filename: leinFiles.join(", "),
|
|
3428
3424
|
});
|
|
3429
|
-
}
|
|
3425
|
+
}
|
|
3426
|
+
if (ednFiles.length) {
|
|
3430
3427
|
let CLJ_ARGS = ["-Stree"];
|
|
3431
3428
|
if (process.env.CLJ_ARGS) {
|
|
3432
3429
|
CLJ_ARGS = process.env.CLJ_ARGS.split(" ");
|
|
@@ -3453,7 +3450,7 @@ export function createClojureBom(path, options) {
|
|
|
3453
3450
|
}
|
|
3454
3451
|
const ednData = readFileSync(f, { encoding: "utf-8" });
|
|
3455
3452
|
const dlist = parseEdnData(ednData);
|
|
3456
|
-
if (dlist
|
|
3453
|
+
if (dlist?.length) {
|
|
3457
3454
|
pkgList = pkgList.concat(dlist);
|
|
3458
3455
|
}
|
|
3459
3456
|
} else {
|
|
@@ -3461,7 +3458,7 @@ export function createClojureBom(path, options) {
|
|
|
3461
3458
|
if (stdout) {
|
|
3462
3459
|
const cmdOutput = Buffer.from(stdout).toString();
|
|
3463
3460
|
const dlist = parseCljDep(cmdOutput);
|
|
3464
|
-
if (dlist
|
|
3461
|
+
if (dlist?.length) {
|
|
3465
3462
|
pkgList = pkgList.concat(dlist);
|
|
3466
3463
|
}
|
|
3467
3464
|
} else {
|
|
@@ -3488,7 +3485,7 @@ export function createClojureBom(path, options) {
|
|
|
3488
3485
|
export function createHaskellBom(path, options) {
|
|
3489
3486
|
const cabalFiles = getAllFiles(
|
|
3490
3487
|
path,
|
|
3491
|
-
|
|
3488
|
+
`${options.multiProject ? "**/" : ""}cabal.project.freeze`,
|
|
3492
3489
|
options,
|
|
3493
3490
|
);
|
|
3494
3491
|
let pkgList = [];
|
|
@@ -3499,7 +3496,7 @@ export function createHaskellBom(path, options) {
|
|
|
3499
3496
|
}
|
|
3500
3497
|
const cabalData = readFileSync(f, { encoding: "utf-8" });
|
|
3501
3498
|
const dlist = parseCabalData(cabalData);
|
|
3502
|
-
if (dlist
|
|
3499
|
+
if (dlist?.length) {
|
|
3503
3500
|
pkgList = pkgList.concat(dlist);
|
|
3504
3501
|
}
|
|
3505
3502
|
}
|
|
@@ -3520,7 +3517,7 @@ export function createHaskellBom(path, options) {
|
|
|
3520
3517
|
export function createElixirBom(path, options) {
|
|
3521
3518
|
const mixFiles = getAllFiles(
|
|
3522
3519
|
path,
|
|
3523
|
-
|
|
3520
|
+
`${options.multiProject ? "**/" : ""}mix.lock`,
|
|
3524
3521
|
options,
|
|
3525
3522
|
);
|
|
3526
3523
|
let pkgList = [];
|
|
@@ -3531,7 +3528,7 @@ export function createElixirBom(path, options) {
|
|
|
3531
3528
|
}
|
|
3532
3529
|
const mixData = readFileSync(f, { encoding: "utf-8" });
|
|
3533
3530
|
const dlist = parseMixLockData(mixData);
|
|
3534
|
-
if (dlist
|
|
3531
|
+
if (dlist?.length) {
|
|
3535
3532
|
pkgList = pkgList.concat(dlist);
|
|
3536
3533
|
}
|
|
3537
3534
|
}
|
|
@@ -3563,7 +3560,7 @@ export function createGitHubBom(path, options) {
|
|
|
3563
3560
|
}
|
|
3564
3561
|
const ghwData = readFileSync(f, { encoding: "utf-8" });
|
|
3565
3562
|
const dlist = parseGitHubWorkflowData(ghwData);
|
|
3566
|
-
if (dlist
|
|
3563
|
+
if (dlist?.length) {
|
|
3567
3564
|
pkgList = pkgList.concat(dlist);
|
|
3568
3565
|
}
|
|
3569
3566
|
}
|
|
@@ -3591,7 +3588,7 @@ export function createCloudBuildBom(path, options) {
|
|
|
3591
3588
|
}
|
|
3592
3589
|
const cbwData = readFileSync(f, { encoding: "utf-8" });
|
|
3593
3590
|
const dlist = parseCloudBuildData(cbwData);
|
|
3594
|
-
if (dlist
|
|
3591
|
+
if (dlist?.length) {
|
|
3595
3592
|
pkgList = pkgList.concat(dlist);
|
|
3596
3593
|
}
|
|
3597
3594
|
}
|
|
@@ -3625,7 +3622,7 @@ export function createOSBom(path, options) {
|
|
|
3625
3622
|
results,
|
|
3626
3623
|
false,
|
|
3627
3624
|
);
|
|
3628
|
-
if (dlist
|
|
3625
|
+
if (dlist?.length) {
|
|
3629
3626
|
if (!Object.keys(parentComponent).length) {
|
|
3630
3627
|
parentComponent = dlist.splice(0, 1)[0];
|
|
3631
3628
|
}
|
|
@@ -3671,7 +3668,7 @@ export async function createJenkinsBom(path, options) {
|
|
|
3671
3668
|
let pkgList = [];
|
|
3672
3669
|
const hpiFiles = getAllFiles(
|
|
3673
3670
|
path,
|
|
3674
|
-
|
|
3671
|
+
`${options.multiProject ? "**/" : ""}*.hpi`,
|
|
3675
3672
|
options,
|
|
3676
3673
|
);
|
|
3677
3674
|
const tempDir = mkdtempSync(join(tmpdir(), "hpi-deps-"));
|
|
@@ -3681,7 +3678,7 @@ export async function createJenkinsBom(path, options) {
|
|
|
3681
3678
|
console.log(`Parsing ${f}`);
|
|
3682
3679
|
}
|
|
3683
3680
|
const dlist = await extractJarArchive(f, tempDir);
|
|
3684
|
-
if (dlist
|
|
3681
|
+
if (dlist?.length) {
|
|
3685
3682
|
pkgList = pkgList.concat(dlist);
|
|
3686
3683
|
}
|
|
3687
3684
|
}
|
|
@@ -3693,13 +3690,13 @@ export async function createJenkinsBom(path, options) {
|
|
|
3693
3690
|
console.log(`Parsing ${f}`);
|
|
3694
3691
|
}
|
|
3695
3692
|
const dlist = await parseMinJs(f);
|
|
3696
|
-
if (dlist
|
|
3693
|
+
if (dlist?.length) {
|
|
3697
3694
|
pkgList = pkgList.concat(dlist);
|
|
3698
3695
|
}
|
|
3699
3696
|
}
|
|
3700
3697
|
}
|
|
3701
3698
|
// Clean up
|
|
3702
|
-
if (tempDir
|
|
3699
|
+
if (tempDir?.startsWith(tmpdir()) && rmSync) {
|
|
3703
3700
|
console.log(`Cleaning up ${tempDir}`);
|
|
3704
3701
|
rmSync(tempDir, { recursive: true, force: true });
|
|
3705
3702
|
}
|
|
@@ -3720,7 +3717,7 @@ export function createHelmBom(path, options) {
|
|
|
3720
3717
|
let pkgList = [];
|
|
3721
3718
|
const yamlFiles = getAllFiles(
|
|
3722
3719
|
path,
|
|
3723
|
-
|
|
3720
|
+
`${options.multiProject ? "**/" : ""}*.yaml`,
|
|
3724
3721
|
options,
|
|
3725
3722
|
);
|
|
3726
3723
|
if (yamlFiles.length) {
|
|
@@ -3730,7 +3727,7 @@ export function createHelmBom(path, options) {
|
|
|
3730
3727
|
}
|
|
3731
3728
|
const helmData = readFileSync(f, { encoding: "utf-8" });
|
|
3732
3729
|
const dlist = parseHelmYamlData(helmData);
|
|
3733
|
-
if (dlist
|
|
3730
|
+
if (dlist?.length) {
|
|
3734
3731
|
pkgList = pkgList.concat(dlist);
|
|
3735
3732
|
}
|
|
3736
3733
|
}
|
|
@@ -3751,12 +3748,12 @@ export function createHelmBom(path, options) {
|
|
|
3751
3748
|
export async function createSwiftBom(path, options) {
|
|
3752
3749
|
const swiftFiles = getAllFiles(
|
|
3753
3750
|
path,
|
|
3754
|
-
|
|
3751
|
+
`${options.multiProject ? "**/" : ""}Package*.swift`,
|
|
3755
3752
|
options,
|
|
3756
3753
|
);
|
|
3757
3754
|
const pkgResolvedFiles = getAllFiles(
|
|
3758
3755
|
path,
|
|
3759
|
-
|
|
3756
|
+
`${options.multiProject ? "**/" : ""}Package.resolved`,
|
|
3760
3757
|
options,
|
|
3761
3758
|
);
|
|
3762
3759
|
let pkgList = [];
|
|
@@ -3772,7 +3769,7 @@ export async function createSwiftBom(path, options) {
|
|
|
3772
3769
|
console.log("Parsing", f);
|
|
3773
3770
|
}
|
|
3774
3771
|
const dlist = parseSwiftResolved(f);
|
|
3775
|
-
if (dlist
|
|
3772
|
+
if (dlist?.length) {
|
|
3776
3773
|
pkgList = pkgList.concat(dlist);
|
|
3777
3774
|
}
|
|
3778
3775
|
}
|
|
@@ -3801,7 +3798,7 @@ export async function createSwiftBom(path, options) {
|
|
|
3801
3798
|
completedPath.push(basePath);
|
|
3802
3799
|
treeData = Buffer.from(result.stdout).toString();
|
|
3803
3800
|
const retData = parseSwiftJsonTree(treeData, f);
|
|
3804
|
-
if (retData.pkgList
|
|
3801
|
+
if (retData.pkgList?.length) {
|
|
3805
3802
|
parentComponent = retData.pkgList.splice(0, 1)[0];
|
|
3806
3803
|
parentComponent.type = "application";
|
|
3807
3804
|
pkgList = pkgList.concat(retData.pkgList);
|
|
@@ -3853,40 +3850,40 @@ export async function createContainerSpecLikeBom(path, options) {
|
|
|
3853
3850
|
const origProjectType = options.projectType;
|
|
3854
3851
|
let dcFiles = getAllFiles(
|
|
3855
3852
|
path,
|
|
3856
|
-
|
|
3853
|
+
`${options.multiProject ? "**/" : ""}*.yml`,
|
|
3857
3854
|
options,
|
|
3858
3855
|
);
|
|
3859
3856
|
const dfFiles = getAllFiles(
|
|
3860
3857
|
path,
|
|
3861
|
-
|
|
3858
|
+
`${options.multiProject ? "**/" : ""}*Dockerfile*`,
|
|
3862
3859
|
options,
|
|
3863
3860
|
);
|
|
3864
3861
|
const bbPipelineFiles = getAllFiles(
|
|
3865
3862
|
path,
|
|
3866
|
-
|
|
3863
|
+
`${options.multiProject ? "**/" : ""}bitbucket-pipelines.yml`,
|
|
3867
3864
|
options,
|
|
3868
3865
|
);
|
|
3869
3866
|
const cfFiles = getAllFiles(
|
|
3870
3867
|
path,
|
|
3871
|
-
|
|
3868
|
+
`${options.multiProject ? "**/" : ""}*Containerfile*`,
|
|
3872
3869
|
options,
|
|
3873
3870
|
);
|
|
3874
3871
|
const yamlFiles = getAllFiles(
|
|
3875
3872
|
path,
|
|
3876
|
-
|
|
3873
|
+
`${options.multiProject ? "**/" : ""}*.yaml`,
|
|
3877
3874
|
options,
|
|
3878
3875
|
);
|
|
3879
3876
|
let oapiFiles = getAllFiles(
|
|
3880
3877
|
path,
|
|
3881
|
-
|
|
3878
|
+
`${options.multiProject ? "**/" : ""}open*.json`,
|
|
3882
3879
|
options,
|
|
3883
3880
|
);
|
|
3884
3881
|
const oapiYamlFiles = getAllFiles(
|
|
3885
3882
|
path,
|
|
3886
|
-
|
|
3883
|
+
`${options.multiProject ? "**/" : ""}open*.yaml`,
|
|
3887
3884
|
options,
|
|
3888
3885
|
);
|
|
3889
|
-
if (oapiYamlFiles
|
|
3886
|
+
if (oapiYamlFiles?.length) {
|
|
3890
3887
|
oapiFiles = oapiFiles.concat(oapiYamlFiles);
|
|
3891
3888
|
}
|
|
3892
3889
|
if (yamlFiles.length) {
|
|
@@ -3918,7 +3915,7 @@ export async function createContainerSpecLikeBom(path, options) {
|
|
|
3918
3915
|
imgList = parseContainerFile(dData);
|
|
3919
3916
|
}
|
|
3920
3917
|
|
|
3921
|
-
if (imgList
|
|
3918
|
+
if (imgList?.length) {
|
|
3922
3919
|
if (DEBUG_MODE) {
|
|
3923
3920
|
console.log("Images identified in", f, "are", imgList);
|
|
3924
3921
|
}
|
|
@@ -3999,7 +3996,7 @@ export async function createContainerSpecLikeBom(path, options) {
|
|
|
3999
3996
|
group: imageObj.group,
|
|
4000
3997
|
version:
|
|
4001
3998
|
imageObj.tag ||
|
|
4002
|
-
(imageObj.digest ?
|
|
3999
|
+
(imageObj.digest ? `sha256:${imageObj.digest}` : "latest"),
|
|
4003
4000
|
qualifiers: {},
|
|
4004
4001
|
properties: commonProperties,
|
|
4005
4002
|
type: "container",
|
|
@@ -4033,17 +4030,13 @@ export async function createContainerSpecLikeBom(path, options) {
|
|
|
4033
4030
|
filename: f,
|
|
4034
4031
|
nsMapping: {},
|
|
4035
4032
|
});
|
|
4036
|
-
if (
|
|
4037
|
-
imageBomData &&
|
|
4038
|
-
imageBomData.bomJson &&
|
|
4039
|
-
imageBomData.bomJson.components
|
|
4040
|
-
) {
|
|
4033
|
+
if (imageBomData?.bomJson?.components) {
|
|
4041
4034
|
components = components.concat(imageBomData.bomJson.components);
|
|
4042
4035
|
}
|
|
4043
4036
|
const bomData = await createBom(img.image, { projectType: "oci" });
|
|
4044
4037
|
doneimages.push(img.image);
|
|
4045
4038
|
if (bomData) {
|
|
4046
|
-
if (bomData.components
|
|
4039
|
+
if (bomData.components?.length) {
|
|
4047
4040
|
// Inject properties
|
|
4048
4041
|
for (const co of bomData.components) {
|
|
4049
4042
|
co.properties = commonProperties;
|
|
@@ -4067,7 +4060,7 @@ export async function createContainerSpecLikeBom(path, options) {
|
|
|
4067
4060
|
}
|
|
4068
4061
|
const oaData = readFileSync(af, { encoding: "utf-8" });
|
|
4069
4062
|
const servlist = parseOpenapiSpecData(oaData);
|
|
4070
|
-
if (servlist
|
|
4063
|
+
if (servlist?.length) {
|
|
4071
4064
|
// Inject SrcFile property
|
|
4072
4065
|
for (const se of servlist) {
|
|
4073
4066
|
se.properties = [
|
|
@@ -4131,7 +4124,7 @@ export async function createContainerSpecLikeBom(path, options) {
|
|
|
4131
4124
|
multiProject: true,
|
|
4132
4125
|
});
|
|
4133
4126
|
if (mbomData) {
|
|
4134
|
-
if (mbomData.components
|
|
4127
|
+
if (mbomData.components?.length) {
|
|
4135
4128
|
components = components.concat(mbomData.components);
|
|
4136
4129
|
}
|
|
4137
4130
|
// We need to retain the parentComponent. See #527
|
|
@@ -4173,7 +4166,7 @@ export function createPHPBom(path, options) {
|
|
|
4173
4166
|
let parentComponent = {};
|
|
4174
4167
|
const composerJsonFiles = getAllFiles(
|
|
4175
4168
|
path,
|
|
4176
|
-
|
|
4169
|
+
`${options.multiProject ? "**/" : ""}composer.json`,
|
|
4177
4170
|
options,
|
|
4178
4171
|
);
|
|
4179
4172
|
if (!options.exclude) {
|
|
@@ -4183,7 +4176,7 @@ export function createPHPBom(path, options) {
|
|
|
4183
4176
|
options.exclude.push("**/vendor/**");
|
|
4184
4177
|
let composerLockFiles = getAllFiles(
|
|
4185
4178
|
path,
|
|
4186
|
-
|
|
4179
|
+
`${options.multiProject ? "**/" : ""}composer.lock`,
|
|
4187
4180
|
options,
|
|
4188
4181
|
);
|
|
4189
4182
|
let pkgList = [];
|
|
@@ -4211,7 +4204,7 @@ export function createPHPBom(path, options) {
|
|
|
4211
4204
|
console.log("Parsing version", versionResult.stdout);
|
|
4212
4205
|
}
|
|
4213
4206
|
const tmpV = undefined;
|
|
4214
|
-
if (versionResult
|
|
4207
|
+
if (versionResult?.stdout) {
|
|
4215
4208
|
versionResult.stdout.split(" ");
|
|
4216
4209
|
}
|
|
4217
4210
|
if (tmpV && tmpV.length > 1) {
|
|
@@ -4240,7 +4233,7 @@ export function createPHPBom(path, options) {
|
|
|
4240
4233
|
}
|
|
4241
4234
|
composerLockFiles = getAllFiles(
|
|
4242
4235
|
path,
|
|
4243
|
-
|
|
4236
|
+
`${options.multiProject ? "**/" : ""}composer.lock`,
|
|
4244
4237
|
options,
|
|
4245
4238
|
);
|
|
4246
4239
|
if (composerLockFiles.length) {
|
|
@@ -4281,7 +4274,7 @@ export function createPHPBom(path, options) {
|
|
|
4281
4274
|
}
|
|
4282
4275
|
}
|
|
4283
4276
|
const retMap = parseComposerLock(f, rootRequires);
|
|
4284
|
-
if (retMap.pkgList
|
|
4277
|
+
if (retMap.pkgList?.length) {
|
|
4285
4278
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
4286
4279
|
}
|
|
4287
4280
|
if (retMap.dependenciesList) {
|
|
@@ -4328,12 +4321,12 @@ export function createPHPBom(path, options) {
|
|
|
4328
4321
|
export async function createRubyBom(path, options) {
|
|
4329
4322
|
const gemFiles = getAllFiles(
|
|
4330
4323
|
path,
|
|
4331
|
-
|
|
4324
|
+
`${options.multiProject ? "**/" : ""}Gemfile`,
|
|
4332
4325
|
options,
|
|
4333
4326
|
);
|
|
4334
4327
|
let gemLockFiles = getAllFiles(
|
|
4335
4328
|
path,
|
|
4336
|
-
|
|
4329
|
+
`${options.multiProject ? "**/" : ""}Gemfile*.lock`,
|
|
4337
4330
|
options,
|
|
4338
4331
|
);
|
|
4339
4332
|
let pkgList = [];
|
|
@@ -4361,7 +4354,7 @@ export async function createRubyBom(path, options) {
|
|
|
4361
4354
|
}
|
|
4362
4355
|
gemLockFiles = getAllFiles(
|
|
4363
4356
|
path,
|
|
4364
|
-
|
|
4357
|
+
`${options.multiProject ? "**/" : ""}Gemfile*.lock`,
|
|
4365
4358
|
options,
|
|
4366
4359
|
);
|
|
4367
4360
|
if (gemLockFiles.length) {
|
|
@@ -4371,18 +4364,18 @@ export async function createRubyBom(path, options) {
|
|
|
4371
4364
|
}
|
|
4372
4365
|
const gemLockData = readFileSync(f, { encoding: "utf-8" });
|
|
4373
4366
|
const retMap = await parseGemfileLockData(gemLockData, f);
|
|
4374
|
-
if (retMap.pkgList
|
|
4367
|
+
if (retMap.pkgList?.length) {
|
|
4375
4368
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
4376
4369
|
pkgList = trimComponents(pkgList);
|
|
4377
4370
|
}
|
|
4378
|
-
if (retMap.dependenciesList
|
|
4371
|
+
if (retMap.dependenciesList?.length) {
|
|
4379
4372
|
dependencies = mergeDependencies(
|
|
4380
4373
|
dependencies,
|
|
4381
4374
|
retMap.dependenciesList,
|
|
4382
4375
|
parentComponent,
|
|
4383
4376
|
);
|
|
4384
4377
|
}
|
|
4385
|
-
if (retMap.rootList
|
|
4378
|
+
if (retMap.rootList?.length) {
|
|
4386
4379
|
rootList = rootList.concat(retMap.rootList);
|
|
4387
4380
|
}
|
|
4388
4381
|
}
|
|
@@ -4423,58 +4416,46 @@ export async function createCsharpBom(path, options) {
|
|
|
4423
4416
|
const parentComponent = createDefaultParentComponent(path, "nuget", options);
|
|
4424
4417
|
const slnFiles = getAllFiles(
|
|
4425
4418
|
path,
|
|
4426
|
-
|
|
4419
|
+
`${options.multiProject ? "**/" : ""}*.sln`,
|
|
4427
4420
|
options,
|
|
4428
4421
|
);
|
|
4429
4422
|
let csProjFiles = getAllFiles(
|
|
4430
4423
|
path,
|
|
4431
|
-
|
|
4424
|
+
`${options.multiProject ? "**/" : ""}*.csproj`,
|
|
4432
4425
|
options,
|
|
4433
4426
|
);
|
|
4434
4427
|
csProjFiles = csProjFiles.concat(
|
|
4435
|
-
getAllFiles(
|
|
4436
|
-
path,
|
|
4437
|
-
(options.multiProject ? "**/" : "") + "*.vbproj",
|
|
4438
|
-
options,
|
|
4439
|
-
),
|
|
4428
|
+
getAllFiles(path, `${options.multiProject ? "**/" : ""}*.vbproj`, options),
|
|
4440
4429
|
);
|
|
4441
4430
|
csProjFiles = csProjFiles.concat(
|
|
4442
|
-
getAllFiles(
|
|
4443
|
-
path,
|
|
4444
|
-
(options.multiProject ? "**/" : "") + "*.vcxproj",
|
|
4445
|
-
options,
|
|
4446
|
-
),
|
|
4431
|
+
getAllFiles(path, `${options.multiProject ? "**/" : ""}*.vcxproj`, options),
|
|
4447
4432
|
);
|
|
4448
4433
|
csProjFiles = csProjFiles.concat(
|
|
4449
|
-
getAllFiles(
|
|
4450
|
-
path,
|
|
4451
|
-
(options.multiProject ? "**/" : "") + "*.fsproj",
|
|
4452
|
-
options,
|
|
4453
|
-
),
|
|
4434
|
+
getAllFiles(path, `${options.multiProject ? "**/" : ""}*.fsproj`, options),
|
|
4454
4435
|
);
|
|
4455
4436
|
const pkgConfigFiles = getAllFiles(
|
|
4456
4437
|
path,
|
|
4457
|
-
|
|
4438
|
+
`${options.multiProject ? "**/" : ""}packages.config`,
|
|
4458
4439
|
options,
|
|
4459
4440
|
);
|
|
4460
4441
|
let projAssetsFiles = getAllFiles(
|
|
4461
4442
|
path,
|
|
4462
|
-
|
|
4443
|
+
`${options.multiProject ? "**/" : ""}project.assets.json`,
|
|
4463
4444
|
options,
|
|
4464
4445
|
);
|
|
4465
4446
|
const pkgLockFiles = getAllFiles(
|
|
4466
4447
|
path,
|
|
4467
|
-
|
|
4448
|
+
`${options.multiProject ? "**/" : ""}packages.lock.json`,
|
|
4468
4449
|
options,
|
|
4469
4450
|
);
|
|
4470
4451
|
const paketLockFiles = getAllFiles(
|
|
4471
4452
|
path,
|
|
4472
|
-
|
|
4453
|
+
`${options.multiProject ? "**/" : ""}paket.lock`,
|
|
4473
4454
|
options,
|
|
4474
4455
|
);
|
|
4475
4456
|
const nupkgFiles = getAllFiles(
|
|
4476
4457
|
path,
|
|
4477
|
-
|
|
4458
|
+
`${options.multiProject ? "**/" : ""}*.nupkg`,
|
|
4478
4459
|
options,
|
|
4479
4460
|
);
|
|
4480
4461
|
// Support for automatic restore
|
|
@@ -4512,7 +4493,7 @@ export async function createCsharpBom(path, options) {
|
|
|
4512
4493
|
// Collect the assets file generated from restore
|
|
4513
4494
|
projAssetsFiles = getAllFiles(
|
|
4514
4495
|
path,
|
|
4515
|
-
|
|
4496
|
+
`${options.multiProject ? "**/" : ""}project.assets.json`,
|
|
4516
4497
|
options,
|
|
4517
4498
|
);
|
|
4518
4499
|
}
|
|
@@ -4524,7 +4505,7 @@ export async function createCsharpBom(path, options) {
|
|
|
4524
4505
|
console.log(`Parsing ${nf}`);
|
|
4525
4506
|
}
|
|
4526
4507
|
const dlist = await parseNupkg(nf);
|
|
4527
|
-
if (dlist
|
|
4508
|
+
if (dlist?.length) {
|
|
4528
4509
|
pkgList = pkgList.concat(dlist);
|
|
4529
4510
|
}
|
|
4530
4511
|
}
|
|
@@ -4540,10 +4521,10 @@ export async function createCsharpBom(path, options) {
|
|
|
4540
4521
|
const results = parseCsProjAssetsData(pkgData, af);
|
|
4541
4522
|
const deps = results["dependenciesList"];
|
|
4542
4523
|
const dlist = results["pkgList"];
|
|
4543
|
-
if (dlist
|
|
4524
|
+
if (dlist?.length) {
|
|
4544
4525
|
pkgList = pkgList.concat(dlist);
|
|
4545
4526
|
}
|
|
4546
|
-
if (deps
|
|
4527
|
+
if (deps?.length) {
|
|
4547
4528
|
dependencies = mergeDependencies(dependencies, deps, parentComponent);
|
|
4548
4529
|
}
|
|
4549
4530
|
}
|
|
@@ -4580,15 +4561,15 @@ export async function createCsharpBom(path, options) {
|
|
|
4580
4561
|
const deps = results["dependenciesList"];
|
|
4581
4562
|
const dlist = results["pkgList"];
|
|
4582
4563
|
const rootList = results["rootList"];
|
|
4583
|
-
if (dlist
|
|
4564
|
+
if (dlist?.length) {
|
|
4584
4565
|
pkgList = pkgList.concat(dlist);
|
|
4585
4566
|
}
|
|
4586
|
-
if (deps
|
|
4567
|
+
if (deps?.length) {
|
|
4587
4568
|
dependencies = mergeDependencies(dependencies, deps, parentComponent);
|
|
4588
4569
|
}
|
|
4589
4570
|
// Keep track of the direct dependencies so that we can construct one complete
|
|
4590
4571
|
// list after processing all lock files
|
|
4591
|
-
if (rootList
|
|
4572
|
+
if (rootList?.length) {
|
|
4592
4573
|
for (const p of rootList) {
|
|
4593
4574
|
parentDependsOn.add(p["bom-ref"]);
|
|
4594
4575
|
}
|
|
@@ -4613,7 +4594,7 @@ export async function createCsharpBom(path, options) {
|
|
|
4613
4594
|
pkgData = pkgData.slice(1);
|
|
4614
4595
|
}
|
|
4615
4596
|
const dlist = parseCsPkgData(pkgData);
|
|
4616
|
-
if (dlist
|
|
4597
|
+
if (dlist?.length) {
|
|
4617
4598
|
pkgList = pkgList.concat(dlist);
|
|
4618
4599
|
}
|
|
4619
4600
|
}
|
|
@@ -4629,10 +4610,10 @@ export async function createCsharpBom(path, options) {
|
|
|
4629
4610
|
const results = parsePaketLockData(pkgData, f);
|
|
4630
4611
|
const dlist = results.pkgList;
|
|
4631
4612
|
const deps = results.dependenciesList;
|
|
4632
|
-
if (dlist
|
|
4613
|
+
if (dlist?.length) {
|
|
4633
4614
|
pkgList = pkgList.concat(dlist);
|
|
4634
4615
|
}
|
|
4635
|
-
if (deps
|
|
4616
|
+
if (deps?.length) {
|
|
4636
4617
|
dependencies = mergeDependencies(dependencies, deps, parentComponent);
|
|
4637
4618
|
}
|
|
4638
4619
|
}
|
|
@@ -4650,7 +4631,7 @@ export async function createCsharpBom(path, options) {
|
|
|
4650
4631
|
csProjData = csProjData.slice(1);
|
|
4651
4632
|
}
|
|
4652
4633
|
const dlist = parseCsProjData(csProjData, f);
|
|
4653
|
-
if (dlist
|
|
4634
|
+
if (dlist?.length) {
|
|
4654
4635
|
pkgList = pkgList.concat(dlist);
|
|
4655
4636
|
}
|
|
4656
4637
|
}
|
|
@@ -4682,7 +4663,7 @@ export async function createCsharpBom(path, options) {
|
|
|
4682
4663
|
}
|
|
4683
4664
|
if (FETCH_LICENSE) {
|
|
4684
4665
|
const retMap = await getNugetMetadata(pkgList, dependencies);
|
|
4685
|
-
if (retMap.dependencies
|
|
4666
|
+
if (retMap.dependencies?.length) {
|
|
4686
4667
|
dependencies = mergeDependencies(
|
|
4687
4668
|
dependencies,
|
|
4688
4669
|
retMap.dependencies,
|
|
@@ -4709,8 +4690,9 @@ export async function createCryptoCertsBom(path, options) {
|
|
|
4709
4690
|
const pkgList = [];
|
|
4710
4691
|
const certFiles = getAllFiles(
|
|
4711
4692
|
path,
|
|
4712
|
-
|
|
4713
|
-
"
|
|
4693
|
+
`${
|
|
4694
|
+
options.multiProject ? "**/" : ""
|
|
4695
|
+
}*.{p12,jks,jceks,bks,keystore,key,pem,cer,gpg,pub}`,
|
|
4714
4696
|
options,
|
|
4715
4697
|
);
|
|
4716
4698
|
for (const f of certFiles) {
|
|
@@ -4752,10 +4734,9 @@ export function mergeDependencies(
|
|
|
4752
4734
|
let providesFound = false;
|
|
4753
4735
|
const deps_map = {};
|
|
4754
4736
|
const provides_map = {};
|
|
4755
|
-
const parentRef =
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
: undefined;
|
|
4737
|
+
const parentRef = parentComponent?.["bom-ref"]
|
|
4738
|
+
? parentComponent["bom-ref"]
|
|
4739
|
+
: undefined;
|
|
4759
4740
|
const combinedDeps = dependencies.concat(newDependencies || []);
|
|
4760
4741
|
for (const adep of combinedDeps) {
|
|
4761
4742
|
if (!deps_map[adep.ref]) {
|
|
@@ -4840,14 +4821,14 @@ export function dedupeBom(options, components, parentComponent, dependencies) {
|
|
|
4840
4821
|
`BOM includes ${components.length} components and ${dependencies.length} dependencies after dedupe`,
|
|
4841
4822
|
);
|
|
4842
4823
|
}
|
|
4843
|
-
const serialNum =
|
|
4824
|
+
const serialNum = `urn:uuid:${uuidv4()}`;
|
|
4844
4825
|
return {
|
|
4845
4826
|
options,
|
|
4846
4827
|
parentComponent,
|
|
4847
4828
|
components,
|
|
4848
4829
|
bomJson: {
|
|
4849
4830
|
bomFormat: "CycloneDX",
|
|
4850
|
-
specVersion:
|
|
4831
|
+
specVersion: `${options.specVersion || 1.5}`,
|
|
4851
4832
|
serialNumber: serialNum,
|
|
4852
4833
|
version: 1,
|
|
4853
4834
|
metadata: addMetadata(parentComponent, options, {}),
|
|
@@ -4883,11 +4864,11 @@ export async function createMultiXBom(pathList, options) {
|
|
|
4883
4864
|
`Found ${osPackages.length} OS packages at ${options.allLayersExplodedDir}`,
|
|
4884
4865
|
);
|
|
4885
4866
|
}
|
|
4886
|
-
if (allTypes
|
|
4867
|
+
if (allTypes?.length) {
|
|
4887
4868
|
options.allOSComponentTypes = allTypes;
|
|
4888
4869
|
}
|
|
4889
4870
|
components = components.concat(osPackages);
|
|
4890
|
-
if (dependenciesList
|
|
4871
|
+
if (dependenciesList?.length) {
|
|
4891
4872
|
dependencies = dependencies.concat(dependenciesList);
|
|
4892
4873
|
}
|
|
4893
4874
|
if (parentComponent && Object.keys(parentComponent).length) {
|
|
@@ -4901,7 +4882,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
4901
4882
|
}
|
|
4902
4883
|
if (options.projectType === "os" && options.bomData) {
|
|
4903
4884
|
bomData = options.bomData;
|
|
4904
|
-
if (bomData
|
|
4885
|
+
if (bomData?.bomJson?.components) {
|
|
4905
4886
|
if (DEBUG_MODE) {
|
|
4906
4887
|
console.log(`Found ${bomData.bomJson.components.length} OS components`);
|
|
4907
4888
|
}
|
|
@@ -4913,12 +4894,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
4913
4894
|
console.log("Scanning", path);
|
|
4914
4895
|
}
|
|
4915
4896
|
bomData = await createNodejsBom(path, options);
|
|
4916
|
-
if (
|
|
4917
|
-
bomData &&
|
|
4918
|
-
bomData.bomJson &&
|
|
4919
|
-
bomData.bomJson.components &&
|
|
4920
|
-
bomData.bomJson.components.length
|
|
4921
|
-
) {
|
|
4897
|
+
if (bomData?.bomJson?.components?.length) {
|
|
4922
4898
|
if (DEBUG_MODE) {
|
|
4923
4899
|
console.log(
|
|
4924
4900
|
`Found ${bomData.bomJson.components.length} npm packages at ${path}`,
|
|
@@ -4933,22 +4909,14 @@ export async function createMultiXBom(pathList, options) {
|
|
|
4933
4909
|
parentSubComponents.push(bomData.parentComponent);
|
|
4934
4910
|
}
|
|
4935
4911
|
// Retain metadata.component.components
|
|
4936
|
-
if (
|
|
4937
|
-
bomData.parentComponent.components &&
|
|
4938
|
-
bomData.parentComponent.components.length
|
|
4939
|
-
) {
|
|
4912
|
+
if (bomData.parentComponent.components?.length) {
|
|
4940
4913
|
parentSubComponents = parentSubComponents.concat(
|
|
4941
4914
|
bomData.parentComponent.components,
|
|
4942
4915
|
);
|
|
4943
4916
|
}
|
|
4944
4917
|
}
|
|
4945
4918
|
bomData = await createJavaBom(path, options);
|
|
4946
|
-
if (
|
|
4947
|
-
bomData &&
|
|
4948
|
-
bomData.bomJson &&
|
|
4949
|
-
bomData.bomJson.components &&
|
|
4950
|
-
bomData.bomJson.components.length
|
|
4951
|
-
) {
|
|
4919
|
+
if (bomData?.bomJson?.components?.length) {
|
|
4952
4920
|
if (DEBUG_MODE) {
|
|
4953
4921
|
console.log(
|
|
4954
4922
|
`Found ${bomData.bomJson.components.length} java packages at ${path}`,
|
|
@@ -4963,22 +4931,14 @@ export async function createMultiXBom(pathList, options) {
|
|
|
4963
4931
|
parentSubComponents.push(bomData.parentComponent);
|
|
4964
4932
|
}
|
|
4965
4933
|
// Retain metadata.component.components
|
|
4966
|
-
if (
|
|
4967
|
-
bomData.parentComponent.components &&
|
|
4968
|
-
bomData.parentComponent.components.length
|
|
4969
|
-
) {
|
|
4934
|
+
if (bomData.parentComponent.components?.length) {
|
|
4970
4935
|
parentSubComponents = parentSubComponents.concat(
|
|
4971
4936
|
bomData.parentComponent.components,
|
|
4972
4937
|
);
|
|
4973
4938
|
}
|
|
4974
4939
|
}
|
|
4975
4940
|
bomData = await createPythonBom(path, options);
|
|
4976
|
-
if (
|
|
4977
|
-
bomData &&
|
|
4978
|
-
bomData.bomJson &&
|
|
4979
|
-
bomData.bomJson.components &&
|
|
4980
|
-
bomData.bomJson.components.length
|
|
4981
|
-
) {
|
|
4941
|
+
if (bomData?.bomJson?.components?.length) {
|
|
4982
4942
|
if (DEBUG_MODE) {
|
|
4983
4943
|
console.log(
|
|
4984
4944
|
`Found ${bomData.bomJson.components.length} python packages at ${path}`,
|
|
@@ -4994,12 +4954,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
4994
4954
|
}
|
|
4995
4955
|
}
|
|
4996
4956
|
bomData = await createGoBom(path, options);
|
|
4997
|
-
if (
|
|
4998
|
-
bomData &&
|
|
4999
|
-
bomData.bomJson &&
|
|
5000
|
-
bomData.bomJson.components &&
|
|
5001
|
-
bomData.bomJson.components.length
|
|
5002
|
-
) {
|
|
4957
|
+
if (bomData?.bomJson?.components?.length) {
|
|
5003
4958
|
if (DEBUG_MODE) {
|
|
5004
4959
|
console.log(
|
|
5005
4960
|
`Found ${bomData.bomJson.components.length} go packages at ${path}`,
|
|
@@ -5015,7 +4970,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5015
4970
|
}
|
|
5016
4971
|
}
|
|
5017
4972
|
bomData = await createRustBom(path, options);
|
|
5018
|
-
if (bomData
|
|
4973
|
+
if (bomData?.bomJson?.components) {
|
|
5019
4974
|
if (DEBUG_MODE) {
|
|
5020
4975
|
console.log(
|
|
5021
4976
|
`Found ${bomData.bomJson.components.length} rust packages at ${path}`,
|
|
@@ -5030,17 +4985,14 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5030
4985
|
parentSubComponents.push(bomData.parentComponent);
|
|
5031
4986
|
}
|
|
5032
4987
|
// Retain metadata.component.components
|
|
5033
|
-
if (
|
|
5034
|
-
bomData.parentComponent.components &&
|
|
5035
|
-
bomData.parentComponent.components.length
|
|
5036
|
-
) {
|
|
4988
|
+
if (bomData.parentComponent.components?.length) {
|
|
5037
4989
|
parentSubComponents = parentSubComponents.concat(
|
|
5038
4990
|
bomData.parentComponent.components,
|
|
5039
4991
|
);
|
|
5040
4992
|
}
|
|
5041
4993
|
}
|
|
5042
4994
|
bomData = createPHPBom(path, options);
|
|
5043
|
-
if (bomData
|
|
4995
|
+
if (bomData?.bomJson?.components) {
|
|
5044
4996
|
if (DEBUG_MODE) {
|
|
5045
4997
|
console.log(
|
|
5046
4998
|
`Found ${bomData.bomJson.components.length} php packages at ${path}`,
|
|
@@ -5056,7 +5008,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5056
5008
|
}
|
|
5057
5009
|
}
|
|
5058
5010
|
bomData = await createRubyBom(path, options);
|
|
5059
|
-
if (bomData
|
|
5011
|
+
if (bomData?.bomJson?.components) {
|
|
5060
5012
|
if (DEBUG_MODE) {
|
|
5061
5013
|
console.log(
|
|
5062
5014
|
`Found ${bomData.bomJson.components.length} ruby packages at ${path}`,
|
|
@@ -5076,12 +5028,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5076
5028
|
}
|
|
5077
5029
|
}
|
|
5078
5030
|
bomData = await createCsharpBom(path, options);
|
|
5079
|
-
if (
|
|
5080
|
-
bomData &&
|
|
5081
|
-
bomData.bomJson &&
|
|
5082
|
-
bomData.bomJson.components &&
|
|
5083
|
-
bomData.bomJson.components.length
|
|
5084
|
-
) {
|
|
5031
|
+
if (bomData?.bomJson?.components?.length) {
|
|
5085
5032
|
if (DEBUG_MODE) {
|
|
5086
5033
|
console.log(
|
|
5087
5034
|
`Found ${bomData.bomJson.components.length} csharp packages at ${path}`,
|
|
@@ -5097,7 +5044,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5097
5044
|
}
|
|
5098
5045
|
}
|
|
5099
5046
|
bomData = await createDartBom(path, options);
|
|
5100
|
-
if (bomData
|
|
5047
|
+
if (bomData?.bomJson?.components) {
|
|
5101
5048
|
if (DEBUG_MODE) {
|
|
5102
5049
|
console.log(
|
|
5103
5050
|
`Found ${bomData.bomJson.components.length} pub packages at ${path}`,
|
|
@@ -5113,7 +5060,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5113
5060
|
}
|
|
5114
5061
|
}
|
|
5115
5062
|
bomData = createHaskellBom(path, options);
|
|
5116
|
-
if (bomData
|
|
5063
|
+
if (bomData?.bomJson?.components) {
|
|
5117
5064
|
if (DEBUG_MODE) {
|
|
5118
5065
|
console.log(
|
|
5119
5066
|
`Found ${bomData.bomJson.components.length} hackage packages at ${path}`,
|
|
@@ -5129,7 +5076,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5129
5076
|
}
|
|
5130
5077
|
}
|
|
5131
5078
|
bomData = createElixirBom(path, options);
|
|
5132
|
-
if (bomData
|
|
5079
|
+
if (bomData?.bomJson?.components) {
|
|
5133
5080
|
if (DEBUG_MODE) {
|
|
5134
5081
|
console.log(
|
|
5135
5082
|
`Found ${bomData.bomJson.components.length} mix packages at ${path}`,
|
|
@@ -5145,7 +5092,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5145
5092
|
}
|
|
5146
5093
|
}
|
|
5147
5094
|
bomData = createCppBom(path, options);
|
|
5148
|
-
if (bomData
|
|
5095
|
+
if (bomData?.bomJson?.components) {
|
|
5149
5096
|
if (DEBUG_MODE) {
|
|
5150
5097
|
console.log(
|
|
5151
5098
|
`Found ${bomData.bomJson.components.length} cpp packages at ${path}`,
|
|
@@ -5161,7 +5108,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5161
5108
|
}
|
|
5162
5109
|
}
|
|
5163
5110
|
bomData = createClojureBom(path, options);
|
|
5164
|
-
if (bomData
|
|
5111
|
+
if (bomData?.bomJson?.components) {
|
|
5165
5112
|
if (DEBUG_MODE) {
|
|
5166
5113
|
console.log(
|
|
5167
5114
|
`Found ${bomData.bomJson.components.length} clojure packages at ${path}`,
|
|
@@ -5177,7 +5124,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5177
5124
|
}
|
|
5178
5125
|
}
|
|
5179
5126
|
bomData = createGitHubBom(path, options);
|
|
5180
|
-
if (bomData
|
|
5127
|
+
if (bomData?.bomJson?.components) {
|
|
5181
5128
|
if (DEBUG_MODE) {
|
|
5182
5129
|
console.log(
|
|
5183
5130
|
`Found ${bomData.bomJson.components.length} GitHub action packages at ${path}`,
|
|
@@ -5193,7 +5140,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5193
5140
|
}
|
|
5194
5141
|
}
|
|
5195
5142
|
bomData = createCloudBuildBom(path, options);
|
|
5196
|
-
if (bomData
|
|
5143
|
+
if (bomData?.bomJson?.components) {
|
|
5197
5144
|
if (DEBUG_MODE) {
|
|
5198
5145
|
console.log(
|
|
5199
5146
|
`Found ${bomData.bomJson.components.length} CloudBuild configuration at ${path}`,
|
|
@@ -5209,12 +5156,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5209
5156
|
}
|
|
5210
5157
|
}
|
|
5211
5158
|
bomData = await createSwiftBom(path, options);
|
|
5212
|
-
if (
|
|
5213
|
-
bomData &&
|
|
5214
|
-
bomData.bomJson &&
|
|
5215
|
-
bomData.bomJson.components &&
|
|
5216
|
-
bomData.bomJson.components.length
|
|
5217
|
-
) {
|
|
5159
|
+
if (bomData?.bomJson?.components?.length) {
|
|
5218
5160
|
if (DEBUG_MODE) {
|
|
5219
5161
|
console.log(
|
|
5220
5162
|
`Found ${bomData.bomJson.components.length} Swift packages at ${path}`,
|
|
@@ -5232,12 +5174,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5232
5174
|
// Jar scanning is enabled by default
|
|
5233
5175
|
// See #330
|
|
5234
5176
|
bomData = createJarBom(path, options);
|
|
5235
|
-
if (
|
|
5236
|
-
bomData &&
|
|
5237
|
-
bomData.bomJson &&
|
|
5238
|
-
bomData.bomJson.components &&
|
|
5239
|
-
bomData.bomJson.components.length
|
|
5240
|
-
) {
|
|
5177
|
+
if (bomData?.bomJson?.components?.length) {
|
|
5241
5178
|
if (DEBUG_MODE) {
|
|
5242
5179
|
console.log(
|
|
5243
5180
|
`Found ${bomData.bomJson.components.length} jar packages at ${path}`,
|
|
@@ -5255,12 +5192,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5255
5192
|
// Collect any crypto keys
|
|
5256
5193
|
if (options.specVersion >= 1.6 && options.includeCrypto) {
|
|
5257
5194
|
bomData = await createCryptoCertsBom(path, options);
|
|
5258
|
-
if (
|
|
5259
|
-
bomData &&
|
|
5260
|
-
bomData.bomJson &&
|
|
5261
|
-
bomData.bomJson.components &&
|
|
5262
|
-
bomData.bomJson.components.length
|
|
5263
|
-
) {
|
|
5195
|
+
if (bomData?.bomJson?.components?.length) {
|
|
5264
5196
|
if (DEBUG_MODE) {
|
|
5265
5197
|
console.log(
|
|
5266
5198
|
`Found ${bomData.bomJson.components.length} crypto assets at ${path}`,
|
|
@@ -5277,12 +5209,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5277
5209
|
!options.lastWorkingDir.includes("/home/")
|
|
5278
5210
|
) {
|
|
5279
5211
|
bomData = createJarBom(options.lastWorkingDir, options);
|
|
5280
|
-
if (
|
|
5281
|
-
bomData &&
|
|
5282
|
-
bomData.bomJson &&
|
|
5283
|
-
bomData.bomJson.components &&
|
|
5284
|
-
bomData.bomJson.components.length
|
|
5285
|
-
) {
|
|
5212
|
+
if (bomData?.bomJson?.components?.length) {
|
|
5286
5213
|
if (DEBUG_MODE) {
|
|
5287
5214
|
console.log(
|
|
5288
5215
|
`Found ${bomData.bomJson.components.length} jar packages at ${options.lastWorkingDir}`,
|
|
@@ -5310,8 +5237,8 @@ export async function createMultiXBom(pathList, options) {
|
|
|
5310
5237
|
);
|
|
5311
5238
|
parentComponent.components = trimComponents(parentSubComponents);
|
|
5312
5239
|
if (
|
|
5313
|
-
parentComponent.components.length
|
|
5314
|
-
parentComponent.components[0].name
|
|
5240
|
+
parentComponent.components.length === 1 &&
|
|
5241
|
+
parentComponent.components[0].name === parentComponent.name &&
|
|
5315
5242
|
!parentComponent.purl.startsWith("pkg:container")
|
|
5316
5243
|
) {
|
|
5317
5244
|
parentComponent = parentComponent.components[0];
|
|
@@ -5345,19 +5272,19 @@ export async function createXBom(path, options) {
|
|
|
5345
5272
|
// maven - pom.xml
|
|
5346
5273
|
const pomFiles = getAllFiles(
|
|
5347
5274
|
path,
|
|
5348
|
-
|
|
5275
|
+
`${options.multiProject ? "**/" : ""}pom.xml`,
|
|
5349
5276
|
options,
|
|
5350
5277
|
);
|
|
5351
5278
|
// gradle
|
|
5352
5279
|
const gradleFiles = getAllFiles(
|
|
5353
5280
|
path,
|
|
5354
|
-
|
|
5281
|
+
`${options.multiProject ? "**/" : ""}build.gradle*`,
|
|
5355
5282
|
options,
|
|
5356
5283
|
);
|
|
5357
5284
|
// scala sbt
|
|
5358
5285
|
const sbtFiles = getAllFiles(
|
|
5359
5286
|
path,
|
|
5360
|
-
|
|
5287
|
+
`${options.multiProject ? "**/" : ""}{build.sbt,Build.scala}*`,
|
|
5361
5288
|
options,
|
|
5362
5289
|
);
|
|
5363
5290
|
if (pomFiles.length || gradleFiles.length || sbtFiles.length) {
|
|
@@ -5373,19 +5300,18 @@ export async function createXBom(path, options) {
|
|
|
5373
5300
|
}
|
|
5374
5301
|
const reqFiles = getAllFiles(
|
|
5375
5302
|
path,
|
|
5376
|
-
|
|
5303
|
+
`${options.multiProject ? "**/" : ""}*requirements*.txt`,
|
|
5377
5304
|
options,
|
|
5378
5305
|
);
|
|
5379
5306
|
const reqDirFiles = getAllFiles(
|
|
5380
5307
|
path,
|
|
5381
|
-
|
|
5308
|
+
`${options.multiProject ? "**/" : ""}requirements/*.txt`,
|
|
5382
5309
|
options,
|
|
5383
5310
|
);
|
|
5384
|
-
const requirementsMode =
|
|
5385
|
-
(reqFiles && reqFiles.length) || (reqDirFiles && reqDirFiles.length);
|
|
5311
|
+
const requirementsMode = reqFiles?.length || reqDirFiles?.length;
|
|
5386
5312
|
const whlFiles = getAllFiles(
|
|
5387
5313
|
path,
|
|
5388
|
-
|
|
5314
|
+
`${options.multiProject ? "**/" : ""}*.whl`,
|
|
5389
5315
|
options,
|
|
5390
5316
|
);
|
|
5391
5317
|
if (requirementsMode || whlFiles.length) {
|
|
@@ -5394,17 +5320,17 @@ export async function createXBom(path, options) {
|
|
|
5394
5320
|
// go
|
|
5395
5321
|
const gosumFiles = getAllFiles(
|
|
5396
5322
|
path,
|
|
5397
|
-
|
|
5323
|
+
`${options.multiProject ? "**/" : ""}go.sum`,
|
|
5398
5324
|
options,
|
|
5399
5325
|
);
|
|
5400
5326
|
const gomodFiles = getAllFiles(
|
|
5401
5327
|
path,
|
|
5402
|
-
|
|
5328
|
+
`${options.multiProject ? "**/" : ""}go.mod`,
|
|
5403
5329
|
options,
|
|
5404
5330
|
);
|
|
5405
5331
|
const gopkgLockFiles = getAllFiles(
|
|
5406
5332
|
path,
|
|
5407
|
-
|
|
5333
|
+
`${options.multiProject ? "**/" : ""}Gopkg.lock`,
|
|
5408
5334
|
options,
|
|
5409
5335
|
);
|
|
5410
5336
|
if (gomodFiles.length || gosumFiles.length || gopkgLockFiles.length) {
|
|
@@ -5414,12 +5340,12 @@ export async function createXBom(path, options) {
|
|
|
5414
5340
|
// rust
|
|
5415
5341
|
const cargoLockFiles = getAllFiles(
|
|
5416
5342
|
path,
|
|
5417
|
-
|
|
5343
|
+
`${options.multiProject ? "**/" : ""}Cargo.lock`,
|
|
5418
5344
|
options,
|
|
5419
5345
|
);
|
|
5420
5346
|
const cargoFiles = getAllFiles(
|
|
5421
5347
|
path,
|
|
5422
|
-
|
|
5348
|
+
`${options.multiProject ? "**/" : ""}Cargo.toml`,
|
|
5423
5349
|
options,
|
|
5424
5350
|
);
|
|
5425
5351
|
if (cargoLockFiles.length || cargoFiles.length) {
|
|
@@ -5429,12 +5355,12 @@ export async function createXBom(path, options) {
|
|
|
5429
5355
|
// php
|
|
5430
5356
|
const composerJsonFiles = getAllFiles(
|
|
5431
5357
|
path,
|
|
5432
|
-
|
|
5358
|
+
`${options.multiProject ? "**/" : ""}composer.json`,
|
|
5433
5359
|
options,
|
|
5434
5360
|
);
|
|
5435
5361
|
const composerLockFiles = getAllFiles(
|
|
5436
5362
|
path,
|
|
5437
|
-
|
|
5363
|
+
`${options.multiProject ? "**/" : ""}composer.lock`,
|
|
5438
5364
|
options,
|
|
5439
5365
|
);
|
|
5440
5366
|
if (composerJsonFiles.length || composerLockFiles.length) {
|
|
@@ -5444,12 +5370,12 @@ export async function createXBom(path, options) {
|
|
|
5444
5370
|
// Ruby
|
|
5445
5371
|
const gemFiles = getAllFiles(
|
|
5446
5372
|
path,
|
|
5447
|
-
|
|
5373
|
+
`${options.multiProject ? "**/" : ""}Gemfile`,
|
|
5448
5374
|
options,
|
|
5449
5375
|
);
|
|
5450
5376
|
const gemLockFiles = getAllFiles(
|
|
5451
5377
|
path,
|
|
5452
|
-
|
|
5378
|
+
`${options.multiProject ? "**/" : ""}Gemfile*.lock`,
|
|
5453
5379
|
options,
|
|
5454
5380
|
);
|
|
5455
5381
|
if (gemFiles.length || gemLockFiles.length) {
|
|
@@ -5459,22 +5385,14 @@ export async function createXBom(path, options) {
|
|
|
5459
5385
|
// .Net
|
|
5460
5386
|
let csProjFiles = getAllFiles(
|
|
5461
5387
|
path,
|
|
5462
|
-
|
|
5388
|
+
`${options.multiProject ? "**/" : ""}*.csproj`,
|
|
5463
5389
|
options,
|
|
5464
5390
|
);
|
|
5465
5391
|
csProjFiles = csProjFiles.concat(
|
|
5466
|
-
getAllFiles(
|
|
5467
|
-
path,
|
|
5468
|
-
(options.multiProject ? "**/" : "") + "*.vbproj",
|
|
5469
|
-
options,
|
|
5470
|
-
),
|
|
5392
|
+
getAllFiles(path, `${options.multiProject ? "**/" : ""}*.vbproj`, options),
|
|
5471
5393
|
);
|
|
5472
5394
|
csProjFiles = csProjFiles.concat(
|
|
5473
|
-
getAllFiles(
|
|
5474
|
-
path,
|
|
5475
|
-
(options.multiProject ? "**/" : "") + "*.fsproj",
|
|
5476
|
-
options,
|
|
5477
|
-
),
|
|
5395
|
+
getAllFiles(path, `${options.multiProject ? "**/" : ""}*.fsproj`, options),
|
|
5478
5396
|
);
|
|
5479
5397
|
if (csProjFiles.length) {
|
|
5480
5398
|
return await createCsharpBom(path, options);
|
|
@@ -5483,12 +5401,12 @@ export async function createXBom(path, options) {
|
|
|
5483
5401
|
// Dart
|
|
5484
5402
|
const pubFiles = getAllFiles(
|
|
5485
5403
|
path,
|
|
5486
|
-
|
|
5404
|
+
`${options.multiProject ? "**/" : ""}pubspec.lock`,
|
|
5487
5405
|
options,
|
|
5488
5406
|
);
|
|
5489
5407
|
const pubSpecFiles = getAllFiles(
|
|
5490
5408
|
path,
|
|
5491
|
-
|
|
5409
|
+
`${options.multiProject ? "**/" : ""}pubspec.yaml`,
|
|
5492
5410
|
options,
|
|
5493
5411
|
);
|
|
5494
5412
|
if (pubFiles.length || pubSpecFiles.length) {
|
|
@@ -5498,7 +5416,7 @@ export async function createXBom(path, options) {
|
|
|
5498
5416
|
// Haskell
|
|
5499
5417
|
const hackageFiles = getAllFiles(
|
|
5500
5418
|
path,
|
|
5501
|
-
|
|
5419
|
+
`${options.multiProject ? "**/" : ""}cabal.project.freeze`,
|
|
5502
5420
|
options,
|
|
5503
5421
|
);
|
|
5504
5422
|
if (hackageFiles.length) {
|
|
@@ -5508,7 +5426,7 @@ export async function createXBom(path, options) {
|
|
|
5508
5426
|
// Elixir
|
|
5509
5427
|
const mixFiles = getAllFiles(
|
|
5510
5428
|
path,
|
|
5511
|
-
|
|
5429
|
+
`${options.multiProject ? "**/" : ""}mix.lock`,
|
|
5512
5430
|
options,
|
|
5513
5431
|
);
|
|
5514
5432
|
if (mixFiles.length) {
|
|
@@ -5518,22 +5436,22 @@ export async function createXBom(path, options) {
|
|
|
5518
5436
|
// cpp
|
|
5519
5437
|
const conanLockFiles = getAllFiles(
|
|
5520
5438
|
path,
|
|
5521
|
-
|
|
5439
|
+
`${options.multiProject ? "**/" : ""}conan.lock`,
|
|
5522
5440
|
options,
|
|
5523
5441
|
);
|
|
5524
5442
|
const conanFiles = getAllFiles(
|
|
5525
5443
|
path,
|
|
5526
|
-
|
|
5444
|
+
`${options.multiProject ? "**/" : ""}conanfile.txt`,
|
|
5527
5445
|
options,
|
|
5528
5446
|
);
|
|
5529
5447
|
const cmakeListFiles = getAllFiles(
|
|
5530
5448
|
path,
|
|
5531
|
-
|
|
5449
|
+
`${options.multiProject ? "**/" : ""}CMakeLists.txt`,
|
|
5532
5450
|
options,
|
|
5533
5451
|
);
|
|
5534
5452
|
const mesonBuildFiles = getAllFiles(
|
|
5535
5453
|
path,
|
|
5536
|
-
|
|
5454
|
+
`${options.multiProject ? "**/" : ""}meson.build`,
|
|
5537
5455
|
options,
|
|
5538
5456
|
);
|
|
5539
5457
|
if (
|
|
@@ -5548,12 +5466,12 @@ export async function createXBom(path, options) {
|
|
|
5548
5466
|
// clojure
|
|
5549
5467
|
const ednFiles = getAllFiles(
|
|
5550
5468
|
path,
|
|
5551
|
-
|
|
5469
|
+
`${options.multiProject ? "**/" : ""}deps.edn`,
|
|
5552
5470
|
options,
|
|
5553
5471
|
);
|
|
5554
5472
|
const leinFiles = getAllFiles(
|
|
5555
5473
|
path,
|
|
5556
|
-
|
|
5474
|
+
`${options.multiProject ? "**/" : ""}project.clj`,
|
|
5557
5475
|
options,
|
|
5558
5476
|
);
|
|
5559
5477
|
if (ednFiles.length || leinFiles.length) {
|
|
@@ -5573,7 +5491,7 @@ export async function createXBom(path, options) {
|
|
|
5573
5491
|
// Jenkins plugins
|
|
5574
5492
|
const hpiFiles = getAllFiles(
|
|
5575
5493
|
path,
|
|
5576
|
-
|
|
5494
|
+
`${options.multiProject ? "**/" : ""}*.hpi`,
|
|
5577
5495
|
options,
|
|
5578
5496
|
);
|
|
5579
5497
|
if (hpiFiles.length) {
|
|
@@ -5583,12 +5501,12 @@ export async function createXBom(path, options) {
|
|
|
5583
5501
|
// Helm charts
|
|
5584
5502
|
const chartFiles = getAllFiles(
|
|
5585
5503
|
path,
|
|
5586
|
-
|
|
5504
|
+
`${options.multiProject ? "**/" : ""}Chart.yaml`,
|
|
5587
5505
|
options,
|
|
5588
5506
|
);
|
|
5589
5507
|
const yamlFiles = getAllFiles(
|
|
5590
5508
|
path,
|
|
5591
|
-
|
|
5509
|
+
`${options.multiProject ? "**/" : ""}values.yaml`,
|
|
5592
5510
|
options,
|
|
5593
5511
|
);
|
|
5594
5512
|
if (chartFiles.length || yamlFiles.length) {
|
|
@@ -5598,27 +5516,27 @@ export async function createXBom(path, options) {
|
|
|
5598
5516
|
// Docker compose, dockerfile, containerfile, kubernetes and skaffold
|
|
5599
5517
|
const dcFiles = getAllFiles(
|
|
5600
5518
|
path,
|
|
5601
|
-
|
|
5519
|
+
`${options.multiProject ? "**/" : ""}docker-compose*.yml`,
|
|
5602
5520
|
options,
|
|
5603
5521
|
);
|
|
5604
5522
|
const dfFiles = getAllFiles(
|
|
5605
5523
|
path,
|
|
5606
|
-
|
|
5524
|
+
`${options.multiProject ? "**/" : ""}*Dockerfile*`,
|
|
5607
5525
|
options,
|
|
5608
5526
|
);
|
|
5609
5527
|
const cfFiles = getAllFiles(
|
|
5610
5528
|
path,
|
|
5611
|
-
|
|
5529
|
+
`${options.multiProject ? "**/" : ""}*Containerfile*`,
|
|
5612
5530
|
options,
|
|
5613
5531
|
);
|
|
5614
5532
|
const skFiles = getAllFiles(
|
|
5615
5533
|
path,
|
|
5616
|
-
|
|
5534
|
+
`${options.multiProject ? "**/" : ""}skaffold.yaml`,
|
|
5617
5535
|
options,
|
|
5618
5536
|
);
|
|
5619
5537
|
const deplFiles = getAllFiles(
|
|
5620
5538
|
path,
|
|
5621
|
-
|
|
5539
|
+
`${options.multiProject ? "**/" : ""}deployment.yaml`,
|
|
5622
5540
|
options,
|
|
5623
5541
|
);
|
|
5624
5542
|
if (
|
|
@@ -5634,7 +5552,7 @@ export async function createXBom(path, options) {
|
|
|
5634
5552
|
// Google CloudBuild
|
|
5635
5553
|
const cbFiles = getAllFiles(
|
|
5636
5554
|
path,
|
|
5637
|
-
|
|
5555
|
+
`${options.multiProject ? "**/" : ""}cloudbuild.yaml`,
|
|
5638
5556
|
options,
|
|
5639
5557
|
);
|
|
5640
5558
|
if (cbFiles.length) {
|
|
@@ -5644,12 +5562,12 @@ export async function createXBom(path, options) {
|
|
|
5644
5562
|
// Swift
|
|
5645
5563
|
const swiftFiles = getAllFiles(
|
|
5646
5564
|
path,
|
|
5647
|
-
|
|
5565
|
+
`${options.multiProject ? "**/" : ""}Package*.swift`,
|
|
5648
5566
|
options,
|
|
5649
5567
|
);
|
|
5650
5568
|
const pkgResolvedFiles = getAllFiles(
|
|
5651
5569
|
path,
|
|
5652
|
-
|
|
5570
|
+
`${options.multiProject ? "**/" : ""}Package.resolved`,
|
|
5653
5571
|
options,
|
|
5654
5572
|
);
|
|
5655
5573
|
if (swiftFiles.length || pkgResolvedFiles.length) {
|
|
@@ -5727,8 +5645,7 @@ export async function createBom(path, options) {
|
|
|
5727
5645
|
// Create parent component based on the inspect config
|
|
5728
5646
|
const inspectData = exportData.inspectData;
|
|
5729
5647
|
if (
|
|
5730
|
-
inspectData &&
|
|
5731
|
-
inspectData.RepoDigests &&
|
|
5648
|
+
inspectData?.RepoDigests &&
|
|
5732
5649
|
inspectData.RepoTags &&
|
|
5733
5650
|
Array.isArray(inspectData.RepoDigests) &&
|
|
5734
5651
|
Array.isArray(inspectData.RepoTags) &&
|
|
@@ -5743,7 +5660,7 @@ export async function createBom(path, options) {
|
|
|
5743
5660
|
name: tmpA[0],
|
|
5744
5661
|
version: tmpA[1],
|
|
5745
5662
|
type: "container",
|
|
5746
|
-
purl:
|
|
5663
|
+
purl: `pkg:oci/${inspectData.RepoDigests[0]}`,
|
|
5747
5664
|
_integrity: inspectData.RepoDigests[0].replace(
|
|
5748
5665
|
"sha256:",
|
|
5749
5666
|
"sha256-",
|
|
@@ -5760,7 +5677,7 @@ export async function createBom(path, options) {
|
|
|
5760
5677
|
.split("@")[1]
|
|
5761
5678
|
.replace("sha256:", ""),
|
|
5762
5679
|
type: "container",
|
|
5763
|
-
purl:
|
|
5680
|
+
purl: `pkg:oci/${inspectData.RepoDigests[0]}`,
|
|
5764
5681
|
_integrity: inspectData.RepoDigests[0].replace("sha256:", "sha256-"),
|
|
5765
5682
|
};
|
|
5766
5683
|
options.parentComponent["bom-ref"] = decodeURIComponent(
|
|
@@ -5782,10 +5699,7 @@ export async function createBom(path, options) {
|
|
|
5782
5699
|
[...new Set(exportData.pkgPathList)],
|
|
5783
5700
|
options,
|
|
5784
5701
|
);
|
|
5785
|
-
if (
|
|
5786
|
-
exportData.allLayersDir &&
|
|
5787
|
-
exportData.allLayersDir.startsWith(tmpdir())
|
|
5788
|
-
) {
|
|
5702
|
+
if (exportData.allLayersDir?.startsWith(tmpdir())) {
|
|
5789
5703
|
if (DEBUG_MODE) {
|
|
5790
5704
|
console.log(`Cleaning up ${exportData.allLayersDir}`);
|
|
5791
5705
|
}
|
|
@@ -5932,9 +5846,8 @@ export async function createBom(path, options) {
|
|
|
5932
5846
|
// https://github.com/cyclonedx/cdxgen/issues/95
|
|
5933
5847
|
if (options.multiProject) {
|
|
5934
5848
|
return await createMultiXBom([path], options);
|
|
5935
|
-
} else {
|
|
5936
|
-
return await createXBom(path, options);
|
|
5937
5849
|
}
|
|
5850
|
+
return await createXBom(path, options);
|
|
5938
5851
|
}
|
|
5939
5852
|
}
|
|
5940
5853
|
|
|
@@ -5945,7 +5858,7 @@ export async function createBom(path, options) {
|
|
|
5945
5858
|
* @param {Object} bomContents BOM Json
|
|
5946
5859
|
*/
|
|
5947
5860
|
export async function submitBom(args, bomContents) {
|
|
5948
|
-
const serverUrl = args.serverUrl.replace(/\/$/, "")
|
|
5861
|
+
const serverUrl = `${args.serverUrl.replace(/\/$/, "")}/api/v1/bom`;
|
|
5949
5862
|
let encodedBomContents = Buffer.from(JSON.stringify(bomContents)).toString(
|
|
5950
5863
|
"base64",
|
|
5951
5864
|
);
|