From 21feaf6a461d702a624cf75b04129445a3b3158c Mon Sep 17 00:00:00 2001 From: prabhu Date: Fri, 11 Aug 2023 20:48:34 +0100 Subject: [PATCH] Fix/issue 447 (#457) * Temp commit Signed-off-by: Prabhu Subramanian * Override root project name and version Signed-off-by: Prabhu Subramanian --------- Signed-off-by: Prabhu Subramanian --- index.js | 53 ++++++++++++++++++++++++++++++++------------------- utils.js | 26 ++++++++++++++----------- utils.test.js | 11 +++++++---- 3 files changed, 55 insertions(+), 35 deletions(-) diff --git a/index.js b/index.js index 18088377de..f76bbdb533 100644 --- a/index.js +++ b/index.js @@ -199,18 +199,25 @@ const createDefaultParentComponent = (path, type = "application") => { const determineParentComponent = (options) => { let parentComponent = undefined; - if (options.projectName && options.projectVersion) { + if (options.parentComponent && Object.keys(options.parentComponent).length) { + return options.parentComponent; + } else if (options.projectName && options.projectVersion) { parentComponent = { group: options.projectGroup || "", name: options.projectName, version: "" + options.projectVersion || "", type: "application" }; - } else if ( - options.parentComponent && - Object.keys(options.parentComponent).length - ) { - return options.parentComponent; + const ppurl = new PackageURL( + parentComponent.type, + parentComponent.group, + parentComponent.name, + parentComponent.version, + null, + null + ).toString(); + parentComponent["bom-ref"] = ppurl; + parentComponent["purl"] = decodeURIComponent(ppurl); } return parentComponent; }; @@ -324,6 +331,11 @@ function addMetadata(parentComponent = {}, format = "xml", options = {}) { delete parentComponent.evidence; delete parentComponent._integrity; delete parentComponent.license; + if (!parentComponent["purl"] && parentComponent["bom-ref"]) { + parentComponent["purl"] = decodeURIComponent( + parentComponent["bom-ref"] + ); + } } if (parentComponent && parentComponent.components) { for (const comp of parentComponent.components) { @@ -1788,9 +1800,9 @@ export const createNodejsBom = async (path, options) => { parentComponent.type = "application"; ppurl = new PackageURL( "npm", - parentComponent.group, - parentComponent.name, - parentComponent.version, + options.projectGroup || parentComponent.group, + options.projectName || parentComponent.name, + options.projectVersion || parentComponent.version, null, null ).toString(); @@ -1808,9 +1820,9 @@ export const createNodejsBom = async (path, options) => { }; ppurl = new PackageURL( "npm", - parentComponent.group, - parentComponent.name, - parentComponent.version, + options.projectGroup || parentComponent.group, + options.projectName || parentComponent.name, + options.projectVersion || parentComponent.version, null, null ).toString(); @@ -1839,11 +1851,10 @@ export const createNodejsBom = async (path, options) => { console.log(`Parsing ${f}`); } // Parse package-lock.json if available - const parsedList = await parsePkgLock(f); + const parsedList = await parsePkgLock(f, options); const dlist = parsedList.pkgList; const tmpParentComponent = dlist.splice(0, 1)[0] || {}; tmpParentComponent.type = "application"; - // Create a default parent component based on directory name if (!Object.keys(parentComponent).length) { parentComponent = tmpParentComponent; } else { @@ -1931,9 +1942,9 @@ export const createNodejsBom = async (path, options) => { tmpParentComponent.type = "application"; ppurl = new PackageURL( "npm", - tmpParentComponent.group, - tmpParentComponent.name, - tmpParentComponent.version, + options.projectGroup || tmpParentComponent.group, + options.projectName || tmpParentComponent.name, + options.projectVersion || tmpParentComponent.version, null, null ).toString(); @@ -1950,15 +1961,15 @@ export const createNodejsBom = async (path, options) => { const tmpA = dirName.split(sep); dirName = tmpA[tmpA.length - 1]; const tmpParentComponent = { - group: "", - name: dirName, + group: options.projectGroup || "", + name: options.projectName || dirName, type: "application" }; ppurl = new PackageURL( "npm", tmpParentComponent.group, tmpParentComponent.name, - tmpParentComponent.version, + options.projectVersion || tmpParentComponent.version, null, null ).toString(); @@ -2032,6 +2043,8 @@ export const createNodejsBom = async (path, options) => { if (parentSubComponents.length) { parentComponent.components = parentSubComponents; } + // We need to set this to force our version to be used rather than the directory name based one. + options.parentComponent = parentComponent; return buildBomNSData(options, pkgList, "npm", { allImports, src: path, diff --git a/utils.js b/utils.js index 97962fa0a3..eb5692a2b6 100644 --- a/utils.js +++ b/utils.js @@ -497,12 +497,16 @@ export const parsePkgJson = async (pkgJsonFile) => { * Parse nodejs package lock file * * @param {string} pkgLockFile package-lock.json file + * @param {object} options Command line options */ -export const parsePkgLock = async (pkgLockFile) => { +export const parsePkgLock = async (pkgLockFile, options = {}) => { let pkgList = []; const dependenciesList = []; const depKeys = {}; let rootPkg = {}; + if (!options) { + options = {}; + } if (existsSync(pkgLockFile)) { const lockData = JSON.parse(readFileSync(pkgLockFile, "utf8")); rootPkg.name = lockData.name || ""; @@ -510,16 +514,16 @@ export const parsePkgLock = async (pkgLockFile) => { if (lockData.name && lockData.packages && lockData.packages[""]) { // Build the initial dependency tree for the root package rootPkg = { - group: "", - name: lockData.name, - version: lockData.version, + group: options.projectGroup || "", + name: options.projectName || lockData.name, + version: options.projectVersion || lockData.version, type: "application", "bom-ref": decodeURIComponent( new PackageURL( "npm", - "", - lockData.name, - lockData.version, + options.projectGroup || "", + options.projectName || lockData.name, + options.projectVersion || lockData.version, null, null ).toString() @@ -531,10 +535,10 @@ export const parsePkgLock = async (pkgLockFile) => { dirName = tmpA[tmpA.length - 1]; // v1 lock file rootPkg = { - group: "", - name: lockData.name || dirName, - version: lockData.version || "", - type: "application" + group: options.projectGroup || "", + name: options.projectName || lockData.name || dirName, + version: options.projectVersion || lockData.version || "", + type: "npm" }; } if (rootPkg && rootPkg.name) { diff --git a/utils.test.js b/utils.test.js index 3872d9ddc9..10d4e7f0ee 100644 --- a/utils.test.js +++ b/utils.test.js @@ -1306,16 +1306,19 @@ test("parsePkgLock", async () => { version: "2.0.0" }); expect(deps[deps.length - 1].name).toEqual("zone.js"); - parsedList = await parsePkgLock("./test/data/package-lock-v3.json"); + parsedList = await parsePkgLock("./test/data/package-lock-v3.json", { + projectVersion: "latest", + projectName: "cdxgen" + }); deps = parsedList.pkgList; expect(deps.length).toEqual(879); expect(parsedList.dependenciesList.length).toEqual(879); expect(deps[0]).toEqual({ - "bom-ref": "pkg:npm/@cyclonedx/cdxgen@8.4.3", + "bom-ref": "pkg:npm/cdxgen@latest", group: "", - name: "@cyclonedx/cdxgen", + name: "cdxgen", type: "application", - version: "8.4.3" + version: "latest" }); expect(deps[deps.length - 1].name).toEqual("yocto-queue"); parsedList = await parsePkgLock("./test/data/package-lock4.json");