@cyclonedx/cdxgen 9.9.9 → 9.10.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 +4 -3
- package/evinser.js +17 -5
- package/index.js +11 -7
- package/package.json +3 -3
- package/utils.js +143 -151
- package/utils.test.js +44 -24
package/README.md
CHANGED
|
@@ -229,14 +229,14 @@ To generate SBOM for an older specification version, such as 1.4, pass the versi
|
|
|
229
229
|
cdxgen -r -o bom.json --spec-version 1.4
|
|
230
230
|
```
|
|
231
231
|
|
|
232
|
-
To generate SBOM for C or Python, ensure Java >=
|
|
232
|
+
To generate SBOM for C or Python, ensure Java >= 21 is installed.
|
|
233
233
|
|
|
234
234
|
```shell
|
|
235
|
-
# Install java >=
|
|
235
|
+
# Install java >= 21
|
|
236
236
|
cdxgen -t c -o bom.json
|
|
237
237
|
```
|
|
238
238
|
|
|
239
|
-
NOTE: cdxgen is known to freeze with Java 8 or 11, so ensure >=
|
|
239
|
+
NOTE: cdxgen is known to freeze with Java 8 or 11, so ensure >= 21 is installed and JAVA_HOME environment variable is configured correctly. If in doubt, use the cdxgen container image.
|
|
240
240
|
|
|
241
241
|
## Universal SBOM
|
|
242
242
|
|
|
@@ -358,6 +358,7 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
|
|
|
358
358
|
| MVN_ARGS | Set to pass additional arguments such as profile or settings to maven |
|
|
359
359
|
| MAVEN_HOME | Specify maven home |
|
|
360
360
|
| MAVEN_CENTRAL_URL | Specify URL of Maven Central for metadata fetching (e.g. when private repo is used) |
|
|
361
|
+
| ANDROID_MAVEN_URL | Specify URL of Android Maven Repository for metadata fetching (e.g. when private repo is used) |
|
|
361
362
|
| BAZEL_TARGET | Bazel target to build. Default :all (Eg: //java-maven) |
|
|
362
363
|
| BAZEL_STRIP_MAVEN_PREFIX | Strip Maven group prefix (e.g. useful when private repo is used, defaults to `/maven2/`) |
|
|
363
364
|
| BAZEL_USE_ACTION_GRAPH | SBOM for specific Bazel target, uses `bazel aquery 'outputs(".*.jar", deps(<BAZEL_TARGET>))'` (defaults to `false`) |
|
package/evinser.js
CHANGED
|
@@ -478,13 +478,15 @@ export const parseSliceUsages = async (
|
|
|
478
478
|
purlLocationMap,
|
|
479
479
|
purlImportsMap
|
|
480
480
|
) => {
|
|
481
|
-
const usages = slice.usages;
|
|
482
|
-
if (!usages || !usages.length) {
|
|
483
|
-
return undefined;
|
|
484
|
-
}
|
|
485
481
|
const fileName = slice.fileName;
|
|
486
482
|
const typesToLookup = new Set();
|
|
487
483
|
const lKeyOverrides = {};
|
|
484
|
+
const usages = slice.usages || [];
|
|
485
|
+
// Annotations from usages
|
|
486
|
+
if (slice.signature && slice.signature.startsWith("@") && !usages.length) {
|
|
487
|
+
typesToLookup.add(slice.fullName);
|
|
488
|
+
addToOverrides(lKeyOverrides, slice.fullName, fileName, slice.lineNumber);
|
|
489
|
+
}
|
|
488
490
|
for (const ausage of usages) {
|
|
489
491
|
const ausageLine =
|
|
490
492
|
ausage?.targetObj?.lineNumber || ausage?.definedBy?.lineNumber;
|
|
@@ -527,7 +529,17 @@ export const parseSliceUsages = async (
|
|
|
527
529
|
.concat(ausage?.invokedCalls || [])
|
|
528
530
|
.concat(ausage?.argToCalls || [])
|
|
529
531
|
.concat(ausage?.procedures || [])) {
|
|
530
|
-
if (acall.
|
|
532
|
+
if (acall.resolvedMethod && acall.resolvedMethod.startsWith("@")) {
|
|
533
|
+
typesToLookup.add(acall.callName);
|
|
534
|
+
if (acall.lineNumber) {
|
|
535
|
+
addToOverrides(
|
|
536
|
+
lKeyOverrides,
|
|
537
|
+
acall.callName,
|
|
538
|
+
fileName,
|
|
539
|
+
acall.lineNumber
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
} else if (acall.isExternal == false) {
|
|
531
543
|
continue;
|
|
532
544
|
}
|
|
533
545
|
if (
|
package/index.js
CHANGED
|
@@ -108,7 +108,8 @@ import {
|
|
|
108
108
|
parseContainerFile,
|
|
109
109
|
parseBitbucketPipelinesFile,
|
|
110
110
|
getPyMetadata,
|
|
111
|
-
addEvidenceForDotnet
|
|
111
|
+
addEvidenceForDotnet,
|
|
112
|
+
getSwiftPackageMetadata
|
|
112
113
|
} from "./utils.js";
|
|
113
114
|
import { spawnSync } from "node:child_process";
|
|
114
115
|
import { fileURLToPath } from "node:url";
|
|
@@ -1266,7 +1267,7 @@ export const createJavaBom = async (path, options) => {
|
|
|
1266
1267
|
);
|
|
1267
1268
|
} else {
|
|
1268
1269
|
console.log(
|
|
1269
|
-
"1. Java version requirement: cdxgen container image bundles Java
|
|
1270
|
+
"1. Java version requirement: cdxgen container image bundles Java 21 with maven 3.9 which might be incompatible."
|
|
1270
1271
|
);
|
|
1271
1272
|
}
|
|
1272
1273
|
console.log(
|
|
@@ -3169,7 +3170,7 @@ export const createCppBom = (path, options) => {
|
|
|
3169
3170
|
}
|
|
3170
3171
|
}
|
|
3171
3172
|
}
|
|
3172
|
-
// The need for java >=
|
|
3173
|
+
// The need for java >= 21 with atom is causing confusions since there could be C projects
|
|
3173
3174
|
// inside of other project types. So we currently limit this analyis only when -t argument
|
|
3174
3175
|
// is used.
|
|
3175
3176
|
if (
|
|
@@ -3628,7 +3629,7 @@ export const createHelmBom = (path, options) => {
|
|
|
3628
3629
|
* @param path to the project
|
|
3629
3630
|
* @param options Parse options from the cli
|
|
3630
3631
|
*/
|
|
3631
|
-
export const createSwiftBom = (path, options) => {
|
|
3632
|
+
export const createSwiftBom = async (path, options) => {
|
|
3632
3633
|
const swiftFiles = getAllFiles(
|
|
3633
3634
|
path,
|
|
3634
3635
|
(options.multiProject ? "**/" : "") + "Package*.swift",
|
|
@@ -3704,6 +3705,9 @@ export const createSwiftBom = (path, options) => {
|
|
|
3704
3705
|
}
|
|
3705
3706
|
}
|
|
3706
3707
|
}
|
|
3708
|
+
if (FETCH_LICENSE) {
|
|
3709
|
+
pkgList = await getSwiftPackageMetadata(pkgList);
|
|
3710
|
+
}
|
|
3707
3711
|
return buildBomNSData(options, pkgList, "swift", {
|
|
3708
3712
|
src: path,
|
|
3709
3713
|
filename: swiftFiles.join(", "),
|
|
@@ -4899,7 +4903,7 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
4899
4903
|
)
|
|
4900
4904
|
);
|
|
4901
4905
|
}
|
|
4902
|
-
bomData = createSwiftBom(path, options);
|
|
4906
|
+
bomData = await createSwiftBom(path, options);
|
|
4903
4907
|
if (
|
|
4904
4908
|
bomData &&
|
|
4905
4909
|
bomData.bomJson &&
|
|
@@ -5329,7 +5333,7 @@ export const createXBom = async (path, options) => {
|
|
|
5329
5333
|
options
|
|
5330
5334
|
);
|
|
5331
5335
|
if (swiftFiles.length || pkgResolvedFiles.length) {
|
|
5332
|
-
return createSwiftBom(path, options);
|
|
5336
|
+
return await createSwiftBom(path, options);
|
|
5333
5337
|
}
|
|
5334
5338
|
};
|
|
5335
5339
|
|
|
@@ -5585,7 +5589,7 @@ export const createBom = async (path, options) => {
|
|
|
5585
5589
|
case "cloudbuild":
|
|
5586
5590
|
return createCloudBuildBom(path, options);
|
|
5587
5591
|
case "swift":
|
|
5588
|
-
return createSwiftBom(path, options);
|
|
5592
|
+
return await createSwiftBom(path, options);
|
|
5589
5593
|
default:
|
|
5590
5594
|
// In recurse mode return multi-language Bom
|
|
5591
5595
|
// https://github.com/cyclonedx/cdxgen/issues/95
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyclonedx/cdxgen",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.10.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>",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"yargs": "^17.7.2"
|
|
84
84
|
},
|
|
85
85
|
"optionalDependencies": {
|
|
86
|
-
"@appthreat/atom": "1.7.
|
|
86
|
+
"@appthreat/atom": "1.7.5",
|
|
87
87
|
"@cyclonedx/cdxgen-plugins-bin": "^1.5.4",
|
|
88
88
|
"@cyclonedx/cdxgen-plugins-bin-windows-amd64": "^1.5.4",
|
|
89
89
|
"@cyclonedx/cdxgen-plugins-bin-arm64": "^1.5.4",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"devDependencies": {
|
|
104
104
|
"caxa": "^3.0.1",
|
|
105
105
|
"docsify-cli": "^4.4.4",
|
|
106
|
-
"eslint": "^8.
|
|
106
|
+
"eslint": "^8.56.0",
|
|
107
107
|
"eslint-config-prettier": "^9.1.0",
|
|
108
108
|
"eslint-plugin-prettier": "^5.0.1",
|
|
109
109
|
"jest": "^29.7.0",
|
package/utils.js
CHANGED
|
@@ -404,6 +404,34 @@ export function readLicenseText(
|
|
|
404
404
|
return null;
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
+
export const getSwiftPackageMetadata = async (pkgList) => {
|
|
408
|
+
const cdepList = [];
|
|
409
|
+
for (const p of pkgList) {
|
|
410
|
+
if (p.repository && p.repository.url) {
|
|
411
|
+
if (p.repository.url.includes("://github.com/")) {
|
|
412
|
+
try {
|
|
413
|
+
p.license = await getRepoLicense(p.repository.url, undefined);
|
|
414
|
+
} catch (e) {
|
|
415
|
+
console.error("error fetching repo license from", p.repository.url);
|
|
416
|
+
}
|
|
417
|
+
} else {
|
|
418
|
+
if (DEBUG_MODE) {
|
|
419
|
+
console.log(
|
|
420
|
+
p.repository.url,
|
|
421
|
+
"is currently not supported to fetch for licenses"
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
} else {
|
|
426
|
+
if (DEBUG_MODE) {
|
|
427
|
+
console.warn("no repository url found for", p.name);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
cdepList.push(p);
|
|
431
|
+
}
|
|
432
|
+
return cdepList;
|
|
433
|
+
};
|
|
434
|
+
|
|
407
435
|
/**
|
|
408
436
|
* Method to retrieve metadata for npm packages by querying npmjs
|
|
409
437
|
*
|
|
@@ -1323,6 +1351,8 @@ export const parsePnpmLock = async function (pnpmLock, parentComponent = null) {
|
|
|
1323
1351
|
group: group,
|
|
1324
1352
|
name: name,
|
|
1325
1353
|
version: version,
|
|
1354
|
+
purl: purlString,
|
|
1355
|
+
"bom-ref": decodeURIComponent(purlString),
|
|
1326
1356
|
scope,
|
|
1327
1357
|
_integrity: integrity,
|
|
1328
1358
|
properties: [
|
|
@@ -2107,7 +2137,7 @@ export const executeGradleProperties = function (dir, rootPath, subProject) {
|
|
|
2107
2137
|
} else {
|
|
2108
2138
|
console.error(result.stdout, result.stderr);
|
|
2109
2139
|
console.log(
|
|
2110
|
-
"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
|
|
2140
|
+
"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 21 with gradle 8 which might be incompatible."
|
|
2111
2141
|
);
|
|
2112
2142
|
}
|
|
2113
2143
|
if (result.stderr.includes("not get unknown property")) {
|
|
@@ -2338,7 +2368,8 @@ export const guessLicenseId = function (content) {
|
|
|
2338
2368
|
export const getMvnMetadata = async function (pkgList, jarNSMapping = {}) {
|
|
2339
2369
|
const MAVEN_CENTRAL_URL =
|
|
2340
2370
|
process.env.MAVEN_CENTRAL_URL || "https://repo1.maven.org/maven2/";
|
|
2341
|
-
const
|
|
2371
|
+
const ANDROID_MAVEN_URL =
|
|
2372
|
+
process.env.ANDROID_MAVEN_URL || "https://maven.google.com/";
|
|
2342
2373
|
const cdepList = [];
|
|
2343
2374
|
if (!pkgList || !pkgList.length) {
|
|
2344
2375
|
return pkgList;
|
|
@@ -2386,7 +2417,7 @@ export const getMvnMetadata = async function (pkgList, jarNSMapping = {}) {
|
|
|
2386
2417
|
let urlPrefix = MAVEN_CENTRAL_URL;
|
|
2387
2418
|
// Ideally we should try one resolver after the other. But it increases the time taken
|
|
2388
2419
|
if (group.indexOf("android") !== -1) {
|
|
2389
|
-
urlPrefix =
|
|
2420
|
+
urlPrefix = ANDROID_MAVEN_URL;
|
|
2390
2421
|
}
|
|
2391
2422
|
// Querying maven requires a valid group name
|
|
2392
2423
|
if (!group || group === "") {
|
|
@@ -3333,21 +3364,30 @@ export const repoMetadataToGitHubApiUrl = function (repoMetadata) {
|
|
|
3333
3364
|
};
|
|
3334
3365
|
|
|
3335
3366
|
/**
|
|
3336
|
-
* Method to
|
|
3367
|
+
* Method to split GitHub url into its parts
|
|
3337
3368
|
* @param {String} repoUrl Repository url
|
|
3338
|
-
* @
|
|
3339
|
-
* @return {String|undefined} github api url (or undefined - if not a GitHub repo)
|
|
3369
|
+
* @return {[String]} parts from url
|
|
3340
3370
|
*/
|
|
3341
|
-
export const
|
|
3342
|
-
if (!repoUrl || !repoUrl.includes("://github.com/")) {
|
|
3343
|
-
return repoMetadataToGitHubApiUrl(repoMetadata);
|
|
3344
|
-
}
|
|
3371
|
+
export const getGithubUrlParts = (repoUrl) => {
|
|
3345
3372
|
if (repoUrl.toLowerCase().endsWith(".git")) {
|
|
3346
3373
|
repoUrl = repoUrl.slice(0, -4);
|
|
3347
3374
|
}
|
|
3348
3375
|
repoUrl.replace(/\/$/, "");
|
|
3349
3376
|
const parts = repoUrl.split("/");
|
|
3377
|
+
return parts;
|
|
3378
|
+
};
|
|
3350
3379
|
|
|
3380
|
+
/**
|
|
3381
|
+
* Method to construct GitHub api url from repo metadata or one of multiple formats of repo URLs
|
|
3382
|
+
* @param {String} repoUrl Repository url
|
|
3383
|
+
* @param {Object} repoMetadata Object containing group and package name strings
|
|
3384
|
+
* @return {String|undefined} github api url (or undefined - if not a GitHub repo)
|
|
3385
|
+
*/
|
|
3386
|
+
export const toGitHubApiUrl = function (repoUrl, repoMetadata) {
|
|
3387
|
+
if (repoMetadata) {
|
|
3388
|
+
return repoMetadataToGitHubApiUrl(repoMetadata);
|
|
3389
|
+
}
|
|
3390
|
+
const parts = getGithubUrlParts(repoUrl);
|
|
3351
3391
|
if (parts.length < 5 || parts[2] !== "github.com") {
|
|
3352
3392
|
return undefined; // Not a valid GitHub repo URL
|
|
3353
3393
|
} else {
|
|
@@ -6122,87 +6162,89 @@ export const convertOSQueryResults = function (
|
|
|
6122
6162
|
return pkgList;
|
|
6123
6163
|
};
|
|
6124
6164
|
|
|
6125
|
-
|
|
6165
|
+
const purlFromUrlString = (type, repoUrl, version) => {
|
|
6166
|
+
let namespace = "",
|
|
6167
|
+
name;
|
|
6168
|
+
if (repoUrl && repoUrl.includes("://github.com/")) {
|
|
6169
|
+
const parts = getGithubUrlParts(repoUrl);
|
|
6170
|
+
if (parts.length < 5 || parts[2] !== "github.com") {
|
|
6171
|
+
return undefined; // Not a valid GitHub repo URL
|
|
6172
|
+
} else {
|
|
6173
|
+
namespace = parts[2] + "/" + parts[3];
|
|
6174
|
+
name = parts[4];
|
|
6175
|
+
}
|
|
6176
|
+
} else if (repoUrl && repoUrl.startsWith("/")) {
|
|
6177
|
+
const parts = repoUrl.split("/");
|
|
6178
|
+
name = parts[parts.length - 1];
|
|
6179
|
+
} else {
|
|
6180
|
+
if (DEBUG_MODE) {
|
|
6181
|
+
console.warn("unsupported repo url for swift type");
|
|
6182
|
+
}
|
|
6183
|
+
return undefined;
|
|
6184
|
+
}
|
|
6185
|
+
|
|
6186
|
+
const purl = new PackageURL(type, namespace, name, version, null, null);
|
|
6187
|
+
return purl;
|
|
6188
|
+
};
|
|
6189
|
+
|
|
6190
|
+
/**
|
|
6191
|
+
* Parse swift dependency tree output json object
|
|
6192
|
+
* @param {string} jsonObject Swift dependencies json object
|
|
6193
|
+
* @param {string} pkgFile Package.swift file
|
|
6194
|
+
*/
|
|
6195
|
+
export const parseSwiftJsonTreeObject = (
|
|
6126
6196
|
pkgList,
|
|
6127
6197
|
dependenciesList,
|
|
6128
|
-
|
|
6129
|
-
|
|
6198
|
+
jsonObject,
|
|
6199
|
+
pkgFile
|
|
6130
6200
|
) => {
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
}
|
|
6157
|
-
];
|
|
6158
|
-
}
|
|
6159
|
-
} else {
|
|
6160
|
-
apkg.properties = [
|
|
6161
|
-
{
|
|
6162
|
-
name: "SrcPath",
|
|
6163
|
-
value: urlOrPath
|
|
6164
|
-
}
|
|
6165
|
-
];
|
|
6166
|
-
}
|
|
6167
|
-
}
|
|
6168
|
-
pkgList.push(apkg);
|
|
6169
|
-
// Handle the immediate dependencies before recursing
|
|
6170
|
-
if (adep.dependencies && adep.dependencies.length) {
|
|
6171
|
-
const deplist = [];
|
|
6172
|
-
for (const cdep of adep.dependencies) {
|
|
6173
|
-
const deppurl = new PackageURL(
|
|
6174
|
-
"swift",
|
|
6175
|
-
cdep.identity || "",
|
|
6176
|
-
cdep.name,
|
|
6177
|
-
cdep.version,
|
|
6178
|
-
null,
|
|
6179
|
-
null
|
|
6180
|
-
);
|
|
6181
|
-
const deppurlString = decodeURIComponent(deppurl.toString());
|
|
6182
|
-
deplist.push(deppurlString);
|
|
6183
|
-
}
|
|
6184
|
-
if (!depKeys[purlString]) {
|
|
6185
|
-
dependenciesList.push({
|
|
6186
|
-
ref: purlString,
|
|
6187
|
-
dependsOn: deplist
|
|
6188
|
-
});
|
|
6189
|
-
depKeys[purlString] = true;
|
|
6190
|
-
}
|
|
6191
|
-
if (adep.dependencies && adep.dependencies.length) {
|
|
6192
|
-
_swiftDepPkgList(pkgList, dependenciesList, depKeys, adep);
|
|
6193
|
-
}
|
|
6194
|
-
} else {
|
|
6195
|
-
if (!depKeys[purlString]) {
|
|
6196
|
-
dependenciesList.push({
|
|
6197
|
-
ref: purlString,
|
|
6198
|
-
dependsOn: []
|
|
6199
|
-
});
|
|
6200
|
-
depKeys[purlString] = true;
|
|
6201
|
-
}
|
|
6201
|
+
const urlOrPath = jsonObject.url || jsonObject.path;
|
|
6202
|
+
const version = jsonObject.version;
|
|
6203
|
+
const purl = purlFromUrlString("swift", urlOrPath, version);
|
|
6204
|
+
const purlString = decodeURIComponent(purl.toString());
|
|
6205
|
+
const rootPkg = {
|
|
6206
|
+
name: purl.name,
|
|
6207
|
+
group: purl.namespace,
|
|
6208
|
+
version: purl.version,
|
|
6209
|
+
purl: purlString,
|
|
6210
|
+
"bom-ref": purlString
|
|
6211
|
+
};
|
|
6212
|
+
if (urlOrPath) {
|
|
6213
|
+
if (urlOrPath.startsWith("http")) {
|
|
6214
|
+
rootPkg.repository = { url: urlOrPath };
|
|
6215
|
+
} else {
|
|
6216
|
+
const properties = [];
|
|
6217
|
+
properties.push({
|
|
6218
|
+
name: "SrcPath",
|
|
6219
|
+
value: urlOrPath
|
|
6220
|
+
});
|
|
6221
|
+
if (pkgFile) {
|
|
6222
|
+
properties.push({
|
|
6223
|
+
name: "SrcFile",
|
|
6224
|
+
value: pkgFile
|
|
6225
|
+
});
|
|
6202
6226
|
}
|
|
6227
|
+
rootPkg.properties = properties;
|
|
6203
6228
|
}
|
|
6204
6229
|
}
|
|
6205
|
-
|
|
6230
|
+
pkgList.push(rootPkg);
|
|
6231
|
+
const depList = [];
|
|
6232
|
+
if (jsonObject.dependencies) {
|
|
6233
|
+
for (const dependency of jsonObject.dependencies) {
|
|
6234
|
+
const res = parseSwiftJsonTreeObject(
|
|
6235
|
+
pkgList,
|
|
6236
|
+
dependenciesList,
|
|
6237
|
+
dependency,
|
|
6238
|
+
pkgFile
|
|
6239
|
+
);
|
|
6240
|
+
depList.push(res);
|
|
6241
|
+
}
|
|
6242
|
+
}
|
|
6243
|
+
dependenciesList.push({
|
|
6244
|
+
ref: purlString,
|
|
6245
|
+
dependsOn: depList
|
|
6246
|
+
});
|
|
6247
|
+
return purlString;
|
|
6206
6248
|
};
|
|
6207
6249
|
|
|
6208
6250
|
/**
|
|
@@ -6216,64 +6258,9 @@ export const parseSwiftJsonTree = (rawOutput, pkgFile) => {
|
|
|
6216
6258
|
}
|
|
6217
6259
|
const pkgList = [];
|
|
6218
6260
|
const dependenciesList = [];
|
|
6219
|
-
const depKeys = {};
|
|
6220
|
-
let rootPkg = {};
|
|
6221
|
-
let jsonData = {};
|
|
6222
6261
|
try {
|
|
6223
|
-
jsonData = JSON.parse(rawOutput);
|
|
6224
|
-
|
|
6225
|
-
rootPkg = {
|
|
6226
|
-
group: jsonData.identity || "",
|
|
6227
|
-
name: jsonData.name,
|
|
6228
|
-
version: jsonData.version
|
|
6229
|
-
};
|
|
6230
|
-
const urlOrPath = jsonData.url || jsonData.path;
|
|
6231
|
-
if (urlOrPath) {
|
|
6232
|
-
if (urlOrPath.startsWith("http")) {
|
|
6233
|
-
rootPkg.repository = { url: urlOrPath };
|
|
6234
|
-
} else {
|
|
6235
|
-
rootPkg.properties = [
|
|
6236
|
-
{
|
|
6237
|
-
name: "SrcPath",
|
|
6238
|
-
value: urlOrPath
|
|
6239
|
-
},
|
|
6240
|
-
{
|
|
6241
|
-
name: "SrcFile",
|
|
6242
|
-
value: pkgFile
|
|
6243
|
-
}
|
|
6244
|
-
];
|
|
6245
|
-
}
|
|
6246
|
-
}
|
|
6247
|
-
const purl = new PackageURL(
|
|
6248
|
-
"swift",
|
|
6249
|
-
rootPkg.group,
|
|
6250
|
-
rootPkg.name,
|
|
6251
|
-
rootPkg.version,
|
|
6252
|
-
null,
|
|
6253
|
-
null
|
|
6254
|
-
);
|
|
6255
|
-
const bomRefString = decodeURIComponent(purl.toString());
|
|
6256
|
-
rootPkg["bom-ref"] = bomRefString;
|
|
6257
|
-
pkgList.push(rootPkg);
|
|
6258
|
-
const deplist = [];
|
|
6259
|
-
for (const rd of jsonData.dependencies) {
|
|
6260
|
-
const deppurl = new PackageURL(
|
|
6261
|
-
"swift",
|
|
6262
|
-
rd.identity || "",
|
|
6263
|
-
rd.name,
|
|
6264
|
-
rd.version,
|
|
6265
|
-
null,
|
|
6266
|
-
null
|
|
6267
|
-
);
|
|
6268
|
-
const deppurlString = decodeURIComponent(deppurl.toString());
|
|
6269
|
-
deplist.push(deppurlString);
|
|
6270
|
-
}
|
|
6271
|
-
dependenciesList.push({
|
|
6272
|
-
ref: bomRefString,
|
|
6273
|
-
dependsOn: deplist
|
|
6274
|
-
});
|
|
6275
|
-
_swiftDepPkgList(pkgList, dependenciesList, depKeys, jsonData);
|
|
6276
|
-
}
|
|
6262
|
+
const jsonData = JSON.parse(rawOutput);
|
|
6263
|
+
parseSwiftJsonTreeObject(pkgList, dependenciesList, jsonData, pkgFile);
|
|
6277
6264
|
} catch (e) {
|
|
6278
6265
|
if (DEBUG_MODE) {
|
|
6279
6266
|
console.log(e);
|
|
@@ -6304,10 +6291,16 @@ export const parseSwiftResolved = (resolvedFile) => {
|
|
|
6304
6291
|
resolvedList = pkgData.object.pins;
|
|
6305
6292
|
}
|
|
6306
6293
|
for (const adep of resolvedList) {
|
|
6307
|
-
const
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6294
|
+
const locationOrUrl = adep.location || adep.repositoryURL;
|
|
6295
|
+
const version = adep.state.version || adep.state.revision;
|
|
6296
|
+
const purl = purlFromUrlString("swift", locationOrUrl, version);
|
|
6297
|
+
const purlString = decodeURIComponent(purl.toString());
|
|
6298
|
+
const rootPkg = {
|
|
6299
|
+
name: purl.name,
|
|
6300
|
+
group: purl.namespace,
|
|
6301
|
+
version: purl.version,
|
|
6302
|
+
purl: purlString,
|
|
6303
|
+
"bom-ref": purlString,
|
|
6311
6304
|
properties: [
|
|
6312
6305
|
{
|
|
6313
6306
|
name: "SrcFile",
|
|
@@ -6328,11 +6321,10 @@ export const parseSwiftResolved = (resolvedFile) => {
|
|
|
6328
6321
|
}
|
|
6329
6322
|
}
|
|
6330
6323
|
};
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
apkg.repository = { url: repLocation };
|
|
6324
|
+
if (locationOrUrl) {
|
|
6325
|
+
rootPkg.repository = { url: locationOrUrl };
|
|
6334
6326
|
}
|
|
6335
|
-
pkgList.push(
|
|
6327
|
+
pkgList.push(rootPkg);
|
|
6336
6328
|
}
|
|
6337
6329
|
} catch (err) {
|
|
6338
6330
|
// continue regardless of error
|
|
@@ -6595,7 +6587,7 @@ export const collectJarNS = function (jarPath, pomPathMap = {}) {
|
|
|
6595
6587
|
) {
|
|
6596
6588
|
jarCommandAvailable = false;
|
|
6597
6589
|
console.log(
|
|
6598
|
-
"jar command is not available in PATH. Ensure JDK >=
|
|
6590
|
+
"jar command is not available in PATH. Ensure JDK >= 21 is installed and set the environment variables JAVA_HOME and PATH to the bin directory inside JAVA_HOME."
|
|
6599
6591
|
);
|
|
6600
6592
|
}
|
|
6601
6593
|
const consolelines = (jarResult.stdout || "").split("\n");
|
package/utils.test.js
CHANGED
|
@@ -1807,6 +1807,8 @@ test("parsePnpmLock", async () => {
|
|
|
1807
1807
|
"sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==",
|
|
1808
1808
|
group: "@babel",
|
|
1809
1809
|
name: "code-frame",
|
|
1810
|
+
"bom-ref": "pkg:npm/@babel/code-frame@7.10.1",
|
|
1811
|
+
purl: "pkg:npm/%40babel/code-frame@7.10.1",
|
|
1810
1812
|
scope: undefined,
|
|
1811
1813
|
version: "7.10.1",
|
|
1812
1814
|
properties: [
|
|
@@ -1837,6 +1839,8 @@ test("parsePnpmLock", async () => {
|
|
|
1837
1839
|
"sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==",
|
|
1838
1840
|
group: "@babel",
|
|
1839
1841
|
name: "code-frame",
|
|
1842
|
+
"bom-ref": "pkg:npm/@babel/code-frame@7.16.7",
|
|
1843
|
+
purl: "pkg:npm/%40babel/code-frame@7.16.7",
|
|
1840
1844
|
scope: "optional",
|
|
1841
1845
|
version: "7.16.7",
|
|
1842
1846
|
properties: [
|
|
@@ -1866,6 +1870,8 @@ test("parsePnpmLock", async () => {
|
|
|
1866
1870
|
group: "",
|
|
1867
1871
|
name: "ansi-regex",
|
|
1868
1872
|
version: "2.1.1",
|
|
1873
|
+
"bom-ref": "pkg:npm/ansi-regex@2.1.1",
|
|
1874
|
+
purl: "pkg:npm/ansi-regex@2.1.1",
|
|
1869
1875
|
scope: undefined,
|
|
1870
1876
|
_integrity: "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
|
1871
1877
|
properties: [{ name: "SrcFile", value: "./test/data/pnpm-lock2.yaml" }],
|
|
@@ -1900,6 +1906,8 @@ test("parsePnpmLock", async () => {
|
|
|
1900
1906
|
group: "@nodelib",
|
|
1901
1907
|
name: "fs.scandir",
|
|
1902
1908
|
version: "2.1.5",
|
|
1909
|
+
"bom-ref": "pkg:npm/@nodelib/fs.scandir@2.1.5",
|
|
1910
|
+
purl: "pkg:npm/%40nodelib/fs.scandir@2.1.5",
|
|
1903
1911
|
scope: undefined,
|
|
1904
1912
|
_integrity:
|
|
1905
1913
|
"sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
|
@@ -1933,6 +1941,8 @@ test("parsePnpmLock", async () => {
|
|
|
1933
1941
|
group: "@babel",
|
|
1934
1942
|
name: "code-frame",
|
|
1935
1943
|
version: "7.18.6",
|
|
1944
|
+
"bom-ref": "pkg:npm/@babel/code-frame@7.18.6",
|
|
1945
|
+
purl: "pkg:npm/%40babel/code-frame@7.18.6",
|
|
1936
1946
|
scope: "optional",
|
|
1937
1947
|
_integrity:
|
|
1938
1948
|
"sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
|
|
@@ -1955,6 +1965,8 @@ test("parsePnpmLock", async () => {
|
|
|
1955
1965
|
group: "",
|
|
1956
1966
|
name: "yargs",
|
|
1957
1967
|
version: "17.7.1",
|
|
1968
|
+
"bom-ref": "pkg:npm/yargs@17.7.1",
|
|
1969
|
+
purl: "pkg:npm/yargs@17.7.1",
|
|
1958
1970
|
scope: "optional",
|
|
1959
1971
|
_integrity:
|
|
1960
1972
|
"sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
|
|
@@ -1980,6 +1992,8 @@ test("parsePnpmLock", async () => {
|
|
|
1980
1992
|
group: "@babel",
|
|
1981
1993
|
name: "code-frame",
|
|
1982
1994
|
version: "7.18.6",
|
|
1995
|
+
"bom-ref": "pkg:npm/@babel/code-frame@7.18.6",
|
|
1996
|
+
purl: "pkg:npm/%40babel/code-frame@7.18.6",
|
|
1983
1997
|
scope: "optional",
|
|
1984
1998
|
_integrity:
|
|
1985
1999
|
"sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
|
|
@@ -2919,28 +2933,29 @@ test("parse swift deps files", () => {
|
|
|
2919
2933
|
);
|
|
2920
2934
|
expect(retData.pkgList.length).toEqual(5);
|
|
2921
2935
|
expect(retData.pkgList[0]).toEqual({
|
|
2922
|
-
group: "swift-markdown",
|
|
2923
2936
|
name: "swift-markdown",
|
|
2937
|
+
group: "",
|
|
2938
|
+
purl: "pkg:swift/swift-markdown@unspecified",
|
|
2924
2939
|
version: "unspecified",
|
|
2925
2940
|
properties: [
|
|
2926
2941
|
{ name: "SrcPath", value: "/Volumes/Work/sandbox/swift-markdown" },
|
|
2927
2942
|
{ name: "SrcFile", value: "./test/data/swift-deps.json" }
|
|
2928
2943
|
],
|
|
2929
|
-
"bom-ref": "pkg:swift/swift-markdown
|
|
2944
|
+
"bom-ref": "pkg:swift/swift-markdown@unspecified"
|
|
2930
2945
|
});
|
|
2931
2946
|
expect(retData.dependenciesList.length).toEqual(5);
|
|
2932
2947
|
expect(retData.dependenciesList[0]).toEqual({
|
|
2933
|
-
ref: "pkg:swift/
|
|
2934
|
-
dependsOn: [
|
|
2935
|
-
"pkg:swift/swift-cmark/cmark-gfm@unspecified",
|
|
2936
|
-
"pkg:swift/swift-argument-parser/swift-argument-parser@1.0.3",
|
|
2937
|
-
"pkg:swift/swift-docc-plugin/SwiftDocCPlugin@1.1.0"
|
|
2938
|
-
]
|
|
2948
|
+
ref: "pkg:swift/github.com/apple/swift-cmark@unspecified",
|
|
2949
|
+
dependsOn: []
|
|
2939
2950
|
});
|
|
2940
2951
|
expect(retData.dependenciesList[retData.dependenciesList.length - 1]).toEqual(
|
|
2941
2952
|
{
|
|
2942
|
-
ref: "pkg:swift/swift-
|
|
2943
|
-
dependsOn: [
|
|
2953
|
+
ref: "pkg:swift/swift-markdown@unspecified",
|
|
2954
|
+
dependsOn: [
|
|
2955
|
+
"pkg:swift/github.com/apple/swift-cmark@unspecified",
|
|
2956
|
+
"pkg:swift/github.com/apple/swift-argument-parser@1.0.3",
|
|
2957
|
+
"pkg:swift/github.com/apple/swift-docc-plugin@1.1.0"
|
|
2958
|
+
]
|
|
2944
2959
|
}
|
|
2945
2960
|
);
|
|
2946
2961
|
retData = parseSwiftJsonTree(
|
|
@@ -2949,8 +2964,9 @@ test("parse swift deps files", () => {
|
|
|
2949
2964
|
);
|
|
2950
2965
|
expect(retData.pkgList.length).toEqual(5);
|
|
2951
2966
|
expect(retData.pkgList[0]).toEqual({
|
|
2952
|
-
group: "swift-certificates",
|
|
2953
2967
|
name: "swift-certificates",
|
|
2968
|
+
group: "",
|
|
2969
|
+
purl: "pkg:swift/swift-certificates@unspecified",
|
|
2954
2970
|
version: "unspecified",
|
|
2955
2971
|
properties: [
|
|
2956
2972
|
{
|
|
@@ -2959,36 +2975,37 @@ test("parse swift deps files", () => {
|
|
|
2959
2975
|
},
|
|
2960
2976
|
{ name: "SrcFile", value: "./test/data/swift-deps.json" }
|
|
2961
2977
|
],
|
|
2962
|
-
"bom-ref": "pkg:swift/swift-certificates
|
|
2978
|
+
"bom-ref": "pkg:swift/swift-certificates@unspecified"
|
|
2963
2979
|
});
|
|
2964
2980
|
expect(retData.dependenciesList).toEqual([
|
|
2965
2981
|
{
|
|
2966
|
-
ref: "pkg:swift/
|
|
2967
|
-
dependsOn: [
|
|
2982
|
+
ref: "pkg:swift/github.com/apple/swift-docc-symbolkit@1.0.0",
|
|
2983
|
+
dependsOn: []
|
|
2968
2984
|
},
|
|
2969
2985
|
{
|
|
2970
|
-
ref: "pkg:swift/
|
|
2971
|
-
dependsOn: ["pkg:swift/
|
|
2986
|
+
ref: "pkg:swift/github.com/apple/swift-docc-plugin@1.1.0",
|
|
2987
|
+
dependsOn: ["pkg:swift/github.com/apple/swift-docc-symbolkit@1.0.0"]
|
|
2972
2988
|
},
|
|
2973
2989
|
{
|
|
2974
|
-
ref: "pkg:swift/
|
|
2975
|
-
dependsOn: ["pkg:swift/swift-docc-plugin
|
|
2990
|
+
ref: "pkg:swift/github.com/apple/swift-asn1@0.7.0",
|
|
2991
|
+
dependsOn: ["pkg:swift/github.com/apple/swift-docc-plugin@1.1.0"]
|
|
2976
2992
|
},
|
|
2977
2993
|
{
|
|
2978
|
-
ref: "pkg:swift/swift-
|
|
2979
|
-
dependsOn: ["pkg:swift/swift-
|
|
2994
|
+
ref: "pkg:swift/github.com/apple/swift-crypto@2.4.0",
|
|
2995
|
+
dependsOn: ["pkg:swift/github.com/apple/swift-asn1@0.7.0"]
|
|
2980
2996
|
},
|
|
2981
2997
|
{
|
|
2982
|
-
ref: "pkg:swift/swift-
|
|
2983
|
-
dependsOn: []
|
|
2998
|
+
ref: "pkg:swift/swift-certificates@unspecified",
|
|
2999
|
+
dependsOn: ["pkg:swift/github.com/apple/swift-crypto@2.4.0"]
|
|
2984
3000
|
}
|
|
2985
3001
|
]);
|
|
2986
3002
|
let pkgList = parseSwiftResolved("./test/data/Package.resolved");
|
|
2987
3003
|
expect(pkgList.length).toEqual(4);
|
|
2988
3004
|
expect(pkgList[0]).toEqual({
|
|
2989
3005
|
name: "swift-argument-parser",
|
|
2990
|
-
group: "",
|
|
3006
|
+
group: "github.com/apple",
|
|
2991
3007
|
version: "1.0.3",
|
|
3008
|
+
purl: "pkg:swift/github.com/apple/swift-argument-parser@1.0.3",
|
|
2992
3009
|
properties: [{ name: "SrcFile", value: "./test/data/Package.resolved" }],
|
|
2993
3010
|
evidence: {
|
|
2994
3011
|
identity: {
|
|
@@ -3003,14 +3020,16 @@ test("parse swift deps files", () => {
|
|
|
3003
3020
|
]
|
|
3004
3021
|
}
|
|
3005
3022
|
},
|
|
3023
|
+
"bom-ref": "pkg:swift/github.com/apple/swift-argument-parser@1.0.3",
|
|
3006
3024
|
repository: { url: "https://github.com/apple/swift-argument-parser" }
|
|
3007
3025
|
});
|
|
3008
3026
|
pkgList = parseSwiftResolved("./test/data/Package2.resolved");
|
|
3009
3027
|
expect(pkgList.length).toEqual(4);
|
|
3010
3028
|
expect(pkgList[0]).toEqual({
|
|
3011
3029
|
name: "swift-argument-parser",
|
|
3012
|
-
group: "",
|
|
3030
|
+
group: "github.com/apple",
|
|
3013
3031
|
version: "1.2.2",
|
|
3032
|
+
purl: "pkg:swift/github.com/apple/swift-argument-parser@1.2.2",
|
|
3014
3033
|
properties: [{ name: "SrcFile", value: "./test/data/Package2.resolved" }],
|
|
3015
3034
|
evidence: {
|
|
3016
3035
|
identity: {
|
|
@@ -3025,6 +3044,7 @@ test("parse swift deps files", () => {
|
|
|
3025
3044
|
]
|
|
3026
3045
|
}
|
|
3027
3046
|
},
|
|
3047
|
+
"bom-ref": "pkg:swift/github.com/apple/swift-argument-parser@1.2.2",
|
|
3028
3048
|
repository: { url: "https://github.com/apple/swift-argument-parser.git" }
|
|
3029
3049
|
});
|
|
3030
3050
|
});
|