@cyclonedx/cdxgen 8.4.13 → 8.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -53,7 +53,7 @@ NOTE:
53
53
  Footnotes:
54
54
 
55
55
  - [1] - For multi-module application, the BoM file could include components that may not be included in the packaged war or ear file.
56
- - [2] - Pip freeze is automatically performed to improve precision.
56
+ - [2] - Pip freeze is automatically performed to improve precision. Requires virtual environment.
57
57
  - [3] - Perform dotnet or nuget restore to generate project.assets.json. Without this file cdxgen would not include indirect dependencies.
58
58
  - [4] - See section on plugins
59
59
  - [5] - Powered by osquery. See section on plugins
@@ -254,7 +254,7 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
254
254
  | MVN_ARGS | Set to pass additional arguments such as profile or settings to maven |
255
255
  | MAVEN_HOME | Specify maven home |
256
256
  | GRADLE_CACHE_DIR | Specify gradle cache directory. Useful for class name resolving |
257
- | GRADLE_MULTI_PROJECT_MODE | Set this variable for gradle multi-project applications. Do not use this with recurse mode. |
257
+ | GRADLE_MULTI_PROJECT_MODE | Unused. Automatically handled |
258
258
  | GRADLE_ARGS | Set to pass additional arguments such as profile or settings to gradle. Eg: --configuration runtimeClassPath |
259
259
  | GRADLE_HOME | Specify gradle home |
260
260
  | GRADLE_CMD | Set to override gradle command |
package/docker.test.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const dockerLib = require("./docker");
2
- const { jest, expect, test } = require("@jest/globals");
2
+ const { expect, test } = require("@jest/globals");
3
3
 
4
4
  test("docker connection", async () => {
5
5
  const dockerConn = await dockerLib.getConnection();
@@ -58,16 +58,14 @@ test("parseImageName tests", () => {
58
58
  });
59
59
 
60
60
  test("docker getImage", async () => {
61
- jest.setTimeout(120000);
62
61
  const imageData = await dockerLib.getImage("hello-world:latest");
63
62
  if (imageData) {
64
63
  const removeData = await dockerLib.removeImage("hello-world:latest");
65
64
  expect(removeData);
66
65
  }
67
- });
66
+ }, 120000);
68
67
 
69
68
  test("docker getImage", async () => {
70
- jest.setTimeout(120000);
71
69
  const imageData = await dockerLib.exportImage("hello-world:latest");
72
70
  expect(imageData);
73
- });
71
+ }, 120000);
package/index.js CHANGED
@@ -248,6 +248,11 @@ function addMetadata(parentComponent = {}, format = "xml", options = {}) {
248
248
  if (format == "xml" && firstPComp.component) {
249
249
  metadata.component = firstPComp.component;
250
250
  } else {
251
+ // Retain the components of parent component
252
+ // Bug #317 fix
253
+ if (parentComponent && parentComponent.components) {
254
+ firstPComp.components = parentComponent.components;
255
+ }
251
256
  metadata.component = firstPComp;
252
257
  }
253
258
  } else {
@@ -1158,268 +1163,157 @@ const createJavaBom = async (path, options) => {
1158
1163
  path,
1159
1164
  (options.multiProject ? "**/" : "") + "build.gradle*"
1160
1165
  );
1166
+ let allProjects = [];
1167
+ const allProjectsAddedPurls = [];
1168
+ const rootDependsOn = [];
1169
+ // Execute gradle properties
1170
+ if (gradleFiles && gradleFiles.length) {
1171
+ let retMap = utils.executeGradleProperties(path, null, null);
1172
+ const allProjectsStr = retMap.projects || [];
1173
+ let rootProject = retMap.rootProject;
1174
+ if (rootProject) {
1175
+ parentComponent = {
1176
+ name: rootProject,
1177
+ type: "application",
1178
+ qualifiers: { type: "jar" },
1179
+ ...(retMap.metadata || {})
1180
+ };
1181
+ const parentPurl = decodeURIComponent(
1182
+ new PackageURL(
1183
+ "maven",
1184
+ parentComponent.group || "",
1185
+ parentComponent.name,
1186
+ parentComponent.version,
1187
+ parentComponent.qualifiers,
1188
+ null
1189
+ ).toString()
1190
+ );
1191
+ parentComponent["purl"] = parentPurl;
1192
+ parentComponent["bom-ref"] = parentPurl;
1193
+ }
1194
+ // Get the sub-project properties and set the root dependencies
1195
+ if (allProjectsStr && allProjectsStr.length) {
1196
+ for (let spstr of allProjectsStr) {
1197
+ retMap = utils.executeGradleProperties(path, null, spstr);
1198
+ let rootSubProject = retMap.rootProject;
1199
+ if (rootSubProject) {
1200
+ let rspName = rootSubProject.replace(/^:/, "").replace(/:/, "/");
1201
+ const rootSubProjectObj = {
1202
+ name: rspName,
1203
+ type: "application",
1204
+ qualifiers: { type: "jar" },
1205
+ ...(retMap.metadata || {})
1206
+ };
1207
+ const rootSubProjectPurl = decodeURIComponent(
1208
+ new PackageURL(
1209
+ "maven",
1210
+ rootSubProjectObj.group || parentComponent.group || "",
1211
+ rootSubProjectObj.name,
1212
+ rootSubProjectObj.version,
1213
+ rootSubProjectObj.qualifiers,
1214
+ null
1215
+ ).toString()
1216
+ );
1217
+ rootSubProjectObj["purl"] = rootSubProjectPurl;
1218
+ rootSubProjectObj["bom-ref"] = rootSubProjectPurl;
1219
+ if (!allProjectsAddedPurls.includes(rootSubProjectPurl)) {
1220
+ allProjects.push(rootSubProjectObj);
1221
+ rootDependsOn.push(rootSubProjectPurl);
1222
+ allProjectsAddedPurls.push(rootSubProjectPurl);
1223
+ }
1224
+ }
1225
+ }
1226
+ // Bug #317 fix
1227
+ parentComponent.components = allProjects.flatMap((s) => {
1228
+ delete s.qualifiers;
1229
+ return s;
1230
+ });
1231
+ dependencies.push({
1232
+ ref: parentComponent["bom-ref"],
1233
+ dependsOn: rootDependsOn
1234
+ });
1235
+ }
1236
+ }
1161
1237
  if (gradleFiles && gradleFiles.length && options.installDeps) {
1162
1238
  let gradleCmd = utils.getGradleCommand(path, null);
1163
- const multiProjectMode = process.env.GRADLE_MULTI_PROJECT_MODE || "";
1164
- // Support for multi-project applications
1165
- // Let's experiment with defaulting to multi-project mode when multiple gradle files gets detected
1166
- if (
1167
- ["true", "1"].includes(multiProjectMode) ||
1168
- (gradleFiles.length > 1 && !["false", "0"].includes(multiProjectMode))
1169
- ) {
1170
- let gradleProjectsArgs = ["projects", "-q", "--console", "plain"];
1239
+ if (!allProjects || !allProjects.length) {
1240
+ allProjects.push(parentComponent);
1241
+ }
1242
+ for (let sp of allProjects) {
1243
+ let gradleDepArgs = [
1244
+ sp.name === parentComponent.name
1245
+ ? "dependencies"
1246
+ : `:${sp.name}:dependencies`,
1247
+ "-q",
1248
+ "--console",
1249
+ "plain",
1250
+ "--build-cache"
1251
+ ];
1252
+ // Support custom GRADLE_ARGS such as --configuration runtimeClassPath
1171
1253
  if (process.env.GRADLE_ARGS) {
1172
1254
  const addArgs = process.env.GRADLE_ARGS.split(" ");
1173
- gradleProjectsArgs = gradleProjectsArgs.concat(addArgs);
1255
+ gradleDepArgs = gradleDepArgs.concat(addArgs);
1174
1256
  }
1175
1257
  console.log(
1176
1258
  "Executing",
1177
1259
  gradleCmd,
1178
- gradleProjectsArgs.join(" "),
1179
- "projects in",
1260
+ gradleDepArgs.join(" "),
1261
+ "in",
1180
1262
  path
1181
1263
  );
1182
- const result = spawnSync(gradleCmd, gradleProjectsArgs, {
1264
+ const sresult = spawnSync(gradleCmd, gradleDepArgs, {
1183
1265
  cwd: path,
1184
1266
  encoding: "utf-8",
1185
1267
  timeout: TIMEOUT_MS
1186
1268
  });
1187
- if (result.status !== 0 || result.error) {
1188
- if (result.stderr) {
1189
- console.error(result.stdout, result.stderr);
1190
- }
1191
- console.log(
1192
- "1. Check if the correct version of java and gradle are installed and available in PATH. For example, some project might require Java 11 with gradle 7.\n cdxgen container image bundles Java 17 with gradle 8 which might be incompatible."
1193
- );
1194
- options.failOnError && process.exit(1);
1195
- }
1196
- const stdout = result.stdout;
1197
- if (stdout) {
1198
- const cmdOutput = Buffer.from(stdout).toString();
1199
- const retMap = utils.parseGradleProjects(cmdOutput);
1200
- const allProjects = retMap.projects || [];
1201
- let rootProject = retMap.rootProject;
1202
- if (rootProject) {
1203
- parentComponent = {
1204
- group: "",
1205
- name: rootProject,
1206
- version: "latest",
1207
- type: "maven",
1208
- qualifiers: { type: "jar" }
1209
- };
1210
- }
1211
- if (!allProjects) {
1212
- console.log(
1213
- "No projects found. Is this a gradle multi-project application?"
1214
- );
1215
- options.failOnError && process.exit(1);
1216
- } else {
1217
- console.log(
1218
- "Found",
1219
- allProjects.length,
1220
- "gradle sub-projects. This might take a while ..."
1221
- );
1222
- // We need the first dependency between the root project and child projects
1223
- // See: #249 and #315
1224
- const rootDependsOn = [];
1225
- for (let sp of allProjects) {
1226
- sp = sp.replace(":", "");
1227
- rootDependsOn.push(
1228
- decodeURIComponent(
1229
- new PackageURL(
1230
- "maven",
1231
- "",
1232
- sp,
1233
- parentComponent.version,
1234
- parentComponent.qualifiers,
1235
- null
1236
- ).toString()
1237
- )
1238
- );
1239
- }
1240
- dependencies.push({
1241
- ref: decodeURIComponent(
1242
- new PackageURL(
1243
- "maven",
1244
- parentComponent.group,
1245
- parentComponent.name,
1246
- parentComponent.version,
1247
- parentComponent.qualifiers,
1248
- null
1249
- ).toString()
1250
- ),
1251
- dependsOn: rootDependsOn
1252
- });
1253
- for (let sp of allProjects) {
1254
- let gradleDepArgs = [
1255
- sp + ":dependencies",
1256
- "-q",
1257
- "--console",
1258
- "plain"
1259
- ];
1260
- // Support custom GRADLE_ARGS such as --configuration runtimeClassPath
1261
- if (process.env.GRADLE_ARGS) {
1262
- const addArgs = process.env.GRADLE_ARGS.split(" ");
1263
- gradleDepArgs = gradleDepArgs.concat(addArgs);
1264
- }
1265
- console.log(
1266
- "Executing",
1267
- gradleCmd,
1268
- gradleDepArgs.join(" "),
1269
- "in",
1270
- path
1271
- );
1272
- const sresult = spawnSync(gradleCmd, gradleDepArgs, {
1273
- cwd: path,
1274
- encoding: "utf-8",
1275
- timeout: TIMEOUT_MS
1276
- });
1277
- if (sresult.status !== 0 || sresult.error) {
1278
- if (options.failOnError || DEBUG_MODE) {
1279
- console.error(sresult.stdout, sresult.stderr);
1280
- }
1281
- options.failOnError && process.exit(1);
1282
- }
1283
- const sstdout = sresult.stdout;
1284
- if (sstdout) {
1285
- sp = sp.replace(":", "");
1286
- const cmdOutput = Buffer.from(sstdout).toString();
1287
- const parsedList = utils.parseGradleDep(cmdOutput, sp);
1288
- const dlist = parsedList.pkgList;
1289
- // Do not overwrite the parentComponent in multi-project mode
1290
- if (!parentComponent || !Object.keys(parentComponent).length) {
1291
- parentComponent = dlist.splice(0, 1)[0];
1292
- }
1293
- if (
1294
- parsedList.dependenciesList &&
1295
- parsedList.dependenciesList
1296
- ) {
1297
- dependencies = mergeDependencies(
1298
- dependencies,
1299
- parsedList.dependenciesList
1300
- );
1301
- }
1302
- if (dlist && dlist.length) {
1303
- if (DEBUG_MODE) {
1304
- console.log(
1305
- "Found",
1306
- dlist.length,
1307
- "packages in gradle project",
1308
- sp
1309
- );
1310
- }
1311
- pkgList = pkgList.concat(dlist);
1312
- } else {
1313
- if (options.failOnError || DEBUG_MODE) {
1314
- console.log("No packages were found in gradle project", sp);
1315
- }
1316
- options.failOnError && process.exit(1);
1317
- }
1318
- }
1319
- }
1320
- if (pkgList.length) {
1321
- console.log(
1322
- "Obtained",
1323
- pkgList.length,
1324
- "from this gradle multi-project. De-duping this list ..."
1325
- );
1326
- } else {
1327
- console.log(
1328
- "No packages found. Unset the environment variable GRADLE_MULTI_PROJECT_MODE and try again."
1329
- );
1330
- options.failOnError && process.exit(1);
1331
- }
1269
+ if (sresult.status !== 0 || sresult.error) {
1270
+ if (options.failOnError || DEBUG_MODE) {
1271
+ console.error(sresult.stdout, sresult.stderr);
1332
1272
  }
1333
- } else {
1334
- console.error("Gradle unexpectedly didn't return any output");
1335
1273
  options.failOnError && process.exit(1);
1336
1274
  }
1337
- } else {
1338
- let gradleDepArgs = ["dependencies", "-q", "--console", "plain"];
1339
- // Support for overriding the gradle task name. Issue# 90
1340
- if (process.env.GRADLE_DEPENDENCY_TASK) {
1341
- gradleDepArgs = process.env.GRADLE_DEPENDENCY_TASK.split(" ");
1342
- } else if (process.env.GRADLE_ARGS) {
1343
- // Support custom GRADLE_ARGS such as --configuration runtimeClassPath
1344
- const addArgs = process.env.GRADLE_ARGS.split(" ");
1345
- gradleDepArgs = gradleDepArgs.concat(addArgs);
1346
- }
1347
- for (let f of gradleFiles) {
1348
- const basePath = pathLib.dirname(f);
1349
- // Fixes #157. Look for wrapper script in the nested directory
1350
- gradleCmd = utils.getGradleCommand(basePath, path);
1351
- console.log(
1352
- "Executing",
1353
- gradleCmd,
1354
- gradleDepArgs.join(" "),
1355
- "in",
1356
- basePath
1275
+ const sstdout = sresult.stdout;
1276
+ if (sstdout) {
1277
+ const cmdOutput = Buffer.from(sstdout).toString();
1278
+ const parsedList = utils.parseGradleDep(
1279
+ cmdOutput,
1280
+ sp.group,
1281
+ sp.name,
1282
+ sp.version
1357
1283
  );
1358
- const result = spawnSync(gradleCmd, gradleDepArgs, {
1359
- cwd: basePath,
1360
- encoding: "utf-8",
1361
- timeout: TIMEOUT_MS
1362
- });
1363
- if (result.status !== 0 || result.error) {
1364
- if (result.stderr) {
1365
- const cmdError = Buffer.from(result.stderr).toString();
1366
- if (
1367
- cmdError.includes(
1368
- "is not part of the build defined by settings file"
1369
- ) ||
1370
- cmdError.includes(
1371
- "was not found in any of the following sources"
1372
- )
1373
- ) {
1374
- console.log(
1375
- "This is a multi-project gradle application. Set the environment variable GRADLE_MULTI_PROJECT_MODE to true to improve SBoM accuracy."
1376
- );
1377
- }
1378
- if (DEBUG_MODE) {
1379
- console.log("-----------------------");
1380
- }
1381
- console.error(result.stdout, result.stderr);
1382
- if (DEBUG_MODE) {
1383
- console.log("-----------------------");
1384
- }
1385
- options.failOnError && process.exit(1);
1386
- }
1387
-
1388
- if (DEBUG_MODE || !result.stderr || options.failOnError) {
1389
- console.log(
1390
- "1. Check if the correct version of java and gradle are installed and available in PATH. For example, some project might require Java 11 with gradle 7.\n cdxgen container image bundles Java 17 with gradle 8 which might be incompatible."
1391
- );
1392
- console.log(
1393
- "2. When using tools such as sdkman, the init script must be invoked to set the PATH variables correctly."
1394
- );
1395
- options.failOnError && process.exit(1);
1396
- }
1284
+ const dlist = parsedList.pkgList;
1285
+ if (parsedList.dependenciesList && parsedList.dependenciesList) {
1286
+ dependencies = mergeDependencies(
1287
+ dependencies,
1288
+ parsedList.dependenciesList
1289
+ );
1397
1290
  }
1398
- const stdout = result.stdout;
1399
- if (stdout) {
1400
- const cmdOutput = Buffer.from(stdout).toString();
1401
- const parsedList = utils.parseGradleDep(cmdOutput);
1402
- const dlist = parsedList.pkgList;
1403
- if (!parentComponent || !Object.keys(parentComponent).length) {
1404
- parentComponent = dlist.splice(0, 1)[0];
1405
- }
1406
- if (parsedList.dependenciesList && parsedList.dependenciesList) {
1407
- dependencies = mergeDependencies(
1408
- dependencies,
1409
- parsedList.dependenciesList
1410
- );
1411
- }
1412
- if (dlist && dlist.length) {
1413
- pkgList = pkgList.concat(dlist);
1414
- } else {
1291
+ if (dlist && dlist.length) {
1292
+ if (DEBUG_MODE) {
1415
1293
  console.log(
1416
- "No packages were detected. If this is a multi-project gradle application set the environment variable GRADLE_MULTI_PROJECT_MODE to true and try again."
1294
+ "Found",
1295
+ dlist.length,
1296
+ "packages in gradle project",
1297
+ sp.name
1417
1298
  );
1418
- options.failOnError && process.exit(1);
1419
1299
  }
1300
+ pkgList = pkgList.concat(dlist);
1420
1301
  }
1421
1302
  }
1303
+ } // for
1304
+ if (pkgList.length) {
1305
+ console.log(
1306
+ "Obtained",
1307
+ pkgList.length,
1308
+ "from this gradle project. De-duping this list ..."
1309
+ );
1310
+ } else {
1311
+ console.log(
1312
+ "No packages found. Set the environment variable 'CDXGEN_DEBUG_MODE=debug' to troubleshoot any gradle related errors."
1313
+ );
1314
+ options.failOnError && process.exit(1);
1422
1315
  }
1316
+
1423
1317
  pkgList = await utils.getMvnMetadata(pkgList);
1424
1318
  // Should we attempt to resolve class names
1425
1319
  if (options.resolveClass) {
@@ -1802,7 +1696,7 @@ const createNodejsBom = async (path, options) => {
1802
1696
  type: "application"
1803
1697
  };
1804
1698
  ppurl = new PackageURL(
1805
- "application",
1699
+ "npm",
1806
1700
  parentComponent.group,
1807
1701
  parentComponent.name,
1808
1702
  parentComponent.version,
@@ -1933,7 +1827,7 @@ const createNodejsBom = async (path, options) => {
1933
1827
  type: "application"
1934
1828
  };
1935
1829
  ppurl = new PackageURL(
1936
- "application",
1830
+ "npm",
1937
1831
  parentComponent.group,
1938
1832
  parentComponent.name,
1939
1833
  parentComponent.version,
@@ -1961,7 +1855,7 @@ const createNodejsBom = async (path, options) => {
1961
1855
  // Fixes: 212. Handle case where there are no package.json to determine the parent package
1962
1856
  if (Object.keys(parentComponent).length && parentComponent.name) {
1963
1857
  const ppurl = new PackageURL(
1964
- "application",
1858
+ "npm",
1965
1859
  parentComponent.group,
1966
1860
  parentComponent.name,
1967
1861
  parentComponent.version,
@@ -2030,7 +1924,7 @@ const createPythonBom = async (path, options) => {
2030
1924
  );
2031
1925
  const reqFiles = utils.getAllFiles(
2032
1926
  path,
2033
- (options.multiProject ? "**/" : "") + "*requirements.txt"
1927
+ (options.multiProject ? "**/" : "") + "*requirements*.txt"
2034
1928
  );
2035
1929
  const reqDirFiles = utils.getAllFiles(
2036
1930
  path,
@@ -2102,7 +1996,7 @@ const createPythonBom = async (path, options) => {
2102
1996
  }
2103
1997
  }
2104
1998
  }
2105
- if (requirementsMode || pipenvMode || setupPyMode) {
1999
+ if (requirementsMode || pipenvMode) {
2106
2000
  if (pipenvMode) {
2107
2001
  spawnSync("pipenv", ["install"], { cwd: path, encoding: "utf-8" });
2108
2002
  const piplockFile = pathLib.join(path, "Pipfile.lock");
@@ -2119,61 +2013,77 @@ const createPythonBom = async (path, options) => {
2119
2013
  } else if (requirementsMode) {
2120
2014
  metadataFilename = "requirements.txt";
2121
2015
  if (reqFiles && reqFiles.length) {
2016
+ let pipWarningShown = false;
2122
2017
  for (let f of reqFiles) {
2123
2018
  const basePath = pathLib.dirname(f);
2124
2019
  let reqData = undefined;
2125
- // Attempt to pip freeze to improve precision
2020
+ let frozenMode = false;
2021
+ // Attempt to pip freeze to improve precision. First try in venv mode
2126
2022
  if (options.installDeps) {
2127
- const result = spawnSync(PIP_CMD, ["freeze", "-r", f, "-l"], {
2128
- cwd: basePath,
2129
- encoding: "utf-8",
2130
- timeout: TIMEOUT_MS
2131
- });
2023
+ const result = spawnSync(
2024
+ PIP_CMD,
2025
+ ["freeze", "-r", f, "-l", "--require-virtualenv"],
2026
+ {
2027
+ cwd: basePath,
2028
+ encoding: "utf-8",
2029
+ timeout: TIMEOUT_MS
2030
+ }
2031
+ );
2132
2032
  if (result.status === 0 && result.stdout) {
2133
2033
  reqData = Buffer.from(result.stdout).toString();
2034
+ const dlist = await utils.parseReqFile(reqData, false);
2035
+ if (dlist && dlist.length) {
2036
+ pkgList = pkgList.concat(dlist);
2037
+ }
2038
+ frozenMode = true;
2039
+ } else if (result.status !== 0 || result.error) {
2040
+ if (DEBUG_MODE && !pipWarningShown) {
2041
+ pipWarningShown = true;
2042
+ console.log(
2043
+ "NOTE: Setup and activate a python virtual environment for this project prior to invoking cdxgen to improve SBoM accuracy."
2044
+ );
2045
+ }
2134
2046
  }
2135
2047
  }
2136
- // Fallback to parsing requirements file
2137
- if (!reqData) {
2048
+ // Fallback to parsing manually
2049
+ if (!frozenMode) {
2138
2050
  if (DEBUG_MODE) {
2139
2051
  console.log(
2140
- `Falling back to manually parsing ${f}. The result would be incomplete!`
2052
+ `Manually parsing ${f}. The result would include only direct dependencies.`
2141
2053
  );
2142
2054
  }
2143
2055
  reqData = fs.readFileSync(f, { encoding: "utf-8" });
2056
+ const dlist = await utils.parseReqFile(reqData, true);
2057
+ if (dlist && dlist.length) {
2058
+ pkgList = pkgList.concat(dlist);
2059
+ }
2144
2060
  }
2145
- const dlist = await utils.parseReqFile(reqData);
2146
- if (dlist && dlist.length) {
2147
- pkgList = pkgList.concat(dlist);
2148
- }
2149
- }
2061
+ } // for
2150
2062
  metadataFilename = reqFiles.join(", ");
2151
2063
  } else if (reqDirFiles && reqDirFiles.length) {
2152
2064
  for (let j in reqDirFiles) {
2153
2065
  const f = reqDirFiles[j];
2154
2066
  const reqData = fs.readFileSync(f, { encoding: "utf-8" });
2155
- const dlist = await utils.parseReqFile(reqData);
2067
+ const dlist = await utils.parseReqFile(reqData, false);
2156
2068
  if (dlist && dlist.length) {
2157
2069
  pkgList = pkgList.concat(dlist);
2158
2070
  }
2159
2071
  }
2160
2072
  metadataFilename = reqDirFiles.join(", ");
2161
2073
  }
2162
- } else if (setupPyMode) {
2163
- const setupPyData = fs.readFileSync(setupPy, { encoding: "utf-8" });
2164
- dlist = await utils.parseSetupPyFile(setupPyData);
2165
- if (dlist && dlist.length) {
2166
- pkgList = pkgList.concat(dlist);
2167
- }
2168
2074
  }
2169
2075
  }
2170
- if (pkgList.length) {
2171
- return buildBomNSData(options, pkgList, "pypi", {
2172
- src: path,
2173
- filename: metadataFilename
2174
- });
2076
+ if (!pkgList.length && setupPyMode) {
2077
+ const setupPyData = fs.readFileSync(setupPy, { encoding: "utf-8" });
2078
+ dlist = await utils.parseSetupPyFile(setupPyData);
2079
+ if (dlist && dlist.length) {
2080
+ pkgList = pkgList.concat(dlist);
2081
+ }
2175
2082
  }
2176
- return {};
2083
+ return buildBomNSData(options, pkgList, "pypi", {
2084
+ src: path,
2085
+ filename: metadataFilename
2086
+ });
2177
2087
  };
2178
2088
 
2179
2089
  /**
@@ -3712,7 +3622,12 @@ const createMultiXBom = async (pathList, options) => {
3712
3622
  console.log("Scanning", path);
3713
3623
  }
3714
3624
  bomData = await createNodejsBom(path, options);
3715
- if (bomData && bomData.bomJson && bomData.bomJson.components) {
3625
+ if (
3626
+ bomData &&
3627
+ bomData.bomJson &&
3628
+ bomData.bomJson.components &&
3629
+ bomData.bomJson.components.length
3630
+ ) {
3716
3631
  if (DEBUG_MODE) {
3717
3632
  console.log(
3718
3633
  `Found ${bomData.bomJson.components.length} npm packages at ${path}`
@@ -3976,7 +3891,12 @@ const createMultiXBom = async (pathList, options) => {
3976
3891
  );
3977
3892
  }
3978
3893
  bomData = await createSwiftBom(path, options);
3979
- if (bomData && bomData.bomJson && bomData.bomJson.components) {
3894
+ if (
3895
+ bomData &&
3896
+ bomData.bomJson &&
3897
+ bomData.bomJson.components &&
3898
+ bomData.bomJson.components.length
3899
+ ) {
3980
3900
  if (DEBUG_MODE) {
3981
3901
  console.log(
3982
3902
  `Found ${bomData.bomJson.components.length} Swift packages at ${path}`
@@ -4088,7 +4008,7 @@ const createXBom = async (path, options) => {
4088
4008
  const poetryMode = fs.existsSync(pathLib.join(path, "poetry.lock"));
4089
4009
  const reqFiles = utils.getAllFiles(
4090
4010
  path,
4091
- (options.multiProject ? "**/" : "") + "*requirements.txt"
4011
+ (options.multiProject ? "**/" : "") + "*requirements*.txt"
4092
4012
  );
4093
4013
  const reqDirFiles = utils.getAllFiles(
4094
4014
  path,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyclonedx/cdxgen",
3
- "version": "8.4.13",
3
+ "version": "8.5.1",
4
4
  "description": "Creates CycloneDX Software Bill-of-Materials (SBOM) from source or container image",
5
5
  "homepage": "http://github.com/cyclonedx/cdxgen",
6
6
  "author": "Prabhu Subramanian <prabhu@appthreat.com>",