diff --git a/bin/cdxgen.js b/bin/cdxgen.js index 2b062be2f..bfcb2d667 100755 --- a/bin/cdxgen.js +++ b/bin/cdxgen.js @@ -278,7 +278,7 @@ const args = yargs(hideBin(process.argv)) .option("feature-flags", { description: "Experimental feature flags to enable. Advanced users only.", hidden: true, - choices: ["safe-pip-install"], + choices: ["safe-pip-install", "suggest-build-tools"], }) .completion("completion", "Generate bash/zsh completion") .array("type") diff --git a/ci/Dockerfile b/ci/Dockerfile index deda6c158..b6676d775 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -133,6 +133,9 @@ RUN set -e; \ && curl -L -O https://github.com/clojure/brew-install/releases/latest/download/linux-install.sh \ && chmod +x linux-install.sh \ && sudo ./linux-install.sh \ + && curl -L --output /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-${GOBIN_VERSION} \ + && chmod +x /usr/local/bin/bazel \ + && bazel --version \ && useradd -ms /bin/bash cyclonedx \ && npm install --unsafe-perm -g node-gyp @microsoft/rush --omit=dev \ && npx node-gyp install \ diff --git a/ci/Dockerfile-deno b/ci/Dockerfile-deno index 7b7dcec61..9d3d12fa8 100644 --- a/ci/Dockerfile-deno +++ b/ci/Dockerfile-deno @@ -131,6 +131,9 @@ RUN set -e; \ && curl -L -O https://github.com/clojure/brew-install/releases/latest/download/linux-install.sh \ && chmod +x linux-install.sh \ && sudo ./linux-install.sh \ + && curl -L --output /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-${GOBIN_VERSION} \ + && chmod +x /usr/local/bin/bazel \ + && bazel --version \ && useradd -ms /bin/bash cyclonedx \ && pecl channel-update pecl.php.net \ && pecl install timezonedb \ diff --git a/deno.json b/deno.json index b99cb13e1..5463e9a31 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "@cyclonedx/cdxgen", - "version": "10.9.0", + "version": "10.9.1", "exports": "./index.js", "compilerOptions": { "allowJs": true, diff --git a/docs/ENV.md b/docs/ENV.md index 96b080a11..0ab81f453 100644 --- a/docs/ENV.md +++ b/docs/ENV.md @@ -12,6 +12,7 @@ The following environment variables are available to configure the bom generatio | PREFER_MAVEN_DEPS_TREE | Use maven `dependency:tree` command instead of the cyclonedx maven plugin | | MAVEN_CENTRAL_URL | Specify URL of Maven Central for metadata fetching (e.g. when private repo is used) | | ANDROID_MAVEN_URL | Specify URL of Android Maven Repository for metadata fetching (e.g. when private repo is used) | +| BAZEL_ARGS | Additional arguments for Bazel command. Eg: --bazelrc=bazelrc.remote | | BAZEL_TARGET | Bazel target to build. Default :all (Eg: //java-maven) | | BAZEL_STRIP_MAVEN_PREFIX | Strip Maven group prefix (e.g. useful when private repo is used, defaults to `/maven2/`) | | BAZEL_USE_ACTION_GRAPH | SBOM for specific Bazel target, uses `bazel aquery 'outputs(".*.jar", deps())'` (defaults to `false`) | diff --git a/index.js b/index.js index 934fda893..88883e1d3 100644 --- a/index.js +++ b/index.js @@ -1529,7 +1529,6 @@ export async function createJavaBom(path, options) { ) { parentComponent = bomJsonObj.metadata.component; options.parentComponent = parentComponent; - pkgList = []; } if (bomJsonObj.components) { // Inject evidence into the components. #994 @@ -1944,7 +1943,11 @@ export async function createJavaBom(path, options) { // Bazel // Look for the BUILD file only in the root directory - const bazelFiles = getAllFiles(path, "BUILD", options); + const bazelFiles = getAllFiles( + path, + `${options.multiProject ? "**/" : ""}BUILD*`, + options, + ); if ( bazelFiles?.length && !options.projectType?.includes("maven") && @@ -1959,9 +1962,18 @@ export async function createJavaBom(path, options) { for (const f of bazelFiles) { const basePath = dirname(f); // Invoke bazel build first - const bazelTarget = process.env.BAZEL_TARGET || ":all"; - console.log("Executing", BAZEL_CMD, "build", bazelTarget, "in", basePath); - let result = spawnSync(BAZEL_CMD, ["build", bazelTarget], { + const bazelTarget = process.env.BAZEL_TARGET || "//..."; + let bArgs = [ + ...(process.env?.BAZEL_ARGS?.split(" ") || []), + "build", + bazelTarget, + ]; + // Automatically load any bazelrc file + if (!process.env.BAZEL_ARGS && existsSync(join(basePath, ".bazelrc"))) { + bArgs = ["--bazelrc=.bazelrc", "build", bazelTarget]; + } + console.log("Executing", BAZEL_CMD, bArgs.join(" "), "in", basePath); + let result = spawnSync(BAZEL_CMD, bArgs, { cwd: basePath, shell: true, encoding: "utf-8", @@ -1978,16 +1990,23 @@ export async function createJavaBom(path, options) { options.failOnError && process.exit(1); } else { const target = process.env.BAZEL_TARGET || "//..."; - let query; + let query = [...(process.env?.BAZEL_ARGS?.split(" ") || [])]; let bazelParser; + // Automatically load any bazelrc file + if (!process.env.BAZEL_ARGS && existsSync(join(basePath, ".bazelrc"))) { + query = ["--bazelrc=.bazelrc"]; + } if (["true", "1"].includes(process.env.BAZEL_USE_ACTION_GRAPH)) { - query = ["aquery", `outputs('.*.jar',deps(${target}))`]; + query = query.concat(["aquery", `outputs('.*.jar',deps(${target}))`]); bazelParser = parseBazelActionGraph; } else { - query = ["aquery", "--output=textproto", "--skyframe_state"]; + query = query.concat([ + "aquery", + "--output=textproto", + "--skyframe_state", + ]); bazelParser = parseBazelSkyframe; } - console.log("Executing", BAZEL_CMD, `${query.join(" ")} in`, basePath); result = spawnSync(BAZEL_CMD, query, { cwd: basePath, @@ -2067,8 +2086,12 @@ export async function createJavaBom(path, options) { options, ); - if (sbtProjects?.length) { - let pkgList = []; + if ( + sbtProjects?.length && + !options.projectType?.includes("bazel") && + !options.projectType?.includes("gradle") && + !options.projectType?.includes("maven") + ) { // If the project use sbt lock files if (sbtLockFiles?.length) { for (const f of sbtLockFiles) { @@ -4920,6 +4943,32 @@ export async function createCsharpBom(path, options) { `${options.multiProject ? "**/" : ""}*.nupkg`, options, ); + // Support for detecting and suggesting build tools for this project + // We parse all the .csproj files to collect the target framework strings + if (isFeatureEnabled(options, "suggest-build-tools")) { + const targetFrameworks = new Set(); + for (const f of csProjFiles) { + const csProjData = readFileSync(f, { encoding: "utf-8" }); + const retMap = parseCsProjData(csProjData, f, {}); + if (retMap?.parentComponent?.properties) { + const parentProperties = retMap.parentComponent.properties; + retMap.parentComponent.properties + .filter( + (p) => + p.name === "cdx:dotnet:target_framework" && p.value.trim().length, + ) + .forEach((p) => { + const frameworkValues = p.value + .split(";") + .filter((v) => v.trim().length && !v.startsWith("$(")) + .forEach((v) => { + targetFrameworks.add(v); + }); + }); + } + } + console.log("Target frameworks found:", Array.from(targetFrameworks)); + } // Support for automatic restore for .Net projects if ( options.installDeps && @@ -4969,9 +5018,11 @@ export async function createCsharpBom(path, options) { console.log( "Authenticate with any private registries such as Azure Artifacts feed before running cdxgen.", ); - console.log( - "Alternatively, try using the unofficial `ghcr.io/appthreat/cdxgen-dotnet6:v10` container image, which bundles nuget (mono) and a range of dotnet SDKs.", - ); + if (process.env?.CDXGEN_IN_CONTAINER !== "true") { + console.log( + "Alternatively, try using the unofficial `ghcr.io/appthreat/cdxgen-dotnet6:v10` container image, which bundles nuget (mono) and a range of dotnet SDKs.", + ); + } } console.log(result.stdout, result.stderr); options.failOnError && process.exit(1); @@ -5097,10 +5148,6 @@ export async function createCsharpBom(path, options) { console.log(`Parsing ${f}`); } pkgData = readFileSync(f, { encoding: "utf-8" }); - // Remove byte order mark - if (pkgData.charCodeAt(0) === 0xfeff) { - pkgData = pkgData.slice(1); - } const dlist = parseCsPkgData(pkgData, f); if (dlist?.length) { pkgList = pkgList.concat(dlist); @@ -5147,13 +5194,9 @@ export async function createCsharpBom(path, options) { if (DEBUG_MODE) { console.log(`Parsing ${f}`); } - let csProjData = readFileSync(f, { encoding: "utf-8" }); - // Remove byte order mark - if (csProjData.charCodeAt(0) === 0xfeff) { - csProjData = csProjData.slice(1); - } + const csProjData = readFileSync(f, { encoding: "utf-8" }); const retMap = parseCsProjData(csProjData, f, pkgNameVersions); - if (retMap?.parentComponent) { + if (retMap?.parentComponent?.purl) { // If there are multiple project files, track the parent components using nested components if (csProjFiles.length > 1) { if (!parentComponent.components) { diff --git a/jsr.json b/jsr.json index 659202225..4fbfa9d04 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@cyclonedx/cdxgen", - "version": "10.9.0", + "version": "10.9.1", "exports": "./index.js", "include": ["*.js", "bin/**", "data/**", "types/**"], "exclude": ["test/", "docs/", "contrib/", "ci/", "tools_config/"] diff --git a/package.json b/package.json index 757012df5..4387f48d2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cyclonedx/cdxgen", - "version": "10.9.0", + "version": "10.9.1", "description": "Creates CycloneDX Software Bill of Materials (SBOM) from source or container image", "homepage": "http://github.com/cyclonedx/cdxgen", "author": "Prabhu Subramanian ", diff --git a/test/data/Logging.csproj b/test/data/Logging.csproj new file mode 100644 index 000000000..3be7b746e --- /dev/null +++ b/test/data/Logging.csproj @@ -0,0 +1,38 @@ + + + + $(TargetFrameworks); + Sample OData extensions for OData v8 + Sample.OData + enable + + + + README.md + Includes latest versions of Seedwork packages and versions of packages used by Seedwork. Includes project validation's checks. Includes mechanism to attach Seedwork locally + MSBuild Tasks Seedwork + true + false + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/types/evinser.d.ts b/types/evinser.d.ts index 6b875455b..10f3fecad 100644 --- a/types/evinser.d.ts +++ b/types/evinser.d.ts @@ -30,7 +30,7 @@ export function prepareDB(options: any): Promise<{ changed(key: K, dirty: boolean): void; changed(): false | string[]; previous(): Partial; - previous(key: K): any | undefined; + previous(key: K): any; save(options?: import("sequelize").SaveOptions): Promise; reload(options?: import("sequelize").FindOptions): Promise; validate(options?: import("sequelize/types/instance-validator.js").ValidationOptions): Promise; @@ -213,7 +213,7 @@ export function prepareDB(options: any): Promise<{ changed(key: K, dirty: boolean): void; changed(): false | string[]; previous(): Partial; - previous(key: K): any | undefined; + previous(key: K): any; save(options?: import("sequelize").SaveOptions): Promise; reload(options?: import("sequelize").FindOptions): Promise; validate(options?: import("sequelize/types/instance-validator.js").ValidationOptions): Promise; @@ -396,7 +396,7 @@ export function prepareDB(options: any): Promise<{ changed(key: K, dirty: boolean): void; changed(): false | string[]; previous(): Partial; - previous(key: K): any | undefined; + previous(key: K): any; save(options?: import("sequelize").SaveOptions): Promise; reload(options?: import("sequelize").FindOptions): Promise; validate(options?: import("sequelize/types/instance-validator.js").ValidationOptions): Promise; diff --git a/types/index.d.ts.map b/types/index.d.ts.map index b821e3cf0..bdda2604d 100644 --- a/types/index.d.ts.map +++ b/types/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.js"],"names":[],"mappings":"AAyvBA;;;;;;;;GAQG;AACH,gFAFW,MAAM,SAchB;AAyUD;;;;;;;GAOG;AACH,mCALW,MAAM,qBAiEhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM;;;;EAKhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM;;;;EAkBhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAi/BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA2chB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BAkahB;AAED;;;;;GAKG;AACH,kCAHW,MAAM,8BAkUhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAqIhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAiDhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBA+KhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBAsHhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,0CAHW,MAAM,qBAuBhB;AAED;;;;;GAKG;AACH,kCAHW,MAAM,8BAqDhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,8BA4ChB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,qCAHW,MAAM,8BAwFhB;AAED;;;;;GAKG;AACH,iDAHW,MAAM,qBAiUhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBAwJhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAmFhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BAyWhB;AAED;;;;;GAKG;AACH,2CAHW,MAAM;;;;;;;;;;;;;;;;;;;;GAoChB;AAED;;;;;;;;KA+DC;AAED;;;;;;GAMG;AACH,yDA2CC;AAED;;;;;;;;;GASG;AACH,2GA6BC;AAED;;;;;GAKG;AACH,0CAHW,MAAM,EAAE,8BAmclB;AAED;;;;;GAKG;AACH,iCAHW,MAAM,8BAiUhB;AAED;;;;;GAKG;AACH,gCAHW,MAAM,qBAsOhB;AAED;;;;;;GAMG;AACH,wDAFY,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CAAC,CA2FxE"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.js"],"names":[],"mappings":"AAyvBA;;;;;;;;GAQG;AACH,gFAFW,MAAM,SAchB;AAyUD;;;;;;;GAOG;AACH,mCALW,MAAM,qBAiEhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM;;;;EAKhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM;;;;EAkBhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAwgChB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA2chB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BAkahB;AAED;;;;;GAKG;AACH,kCAHW,MAAM,8BAkUhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAqIhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAiDhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBA+KhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBAsHhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,0CAHW,MAAM,qBAuBhB;AAED;;;;;GAKG;AACH,kCAHW,MAAM,8BAqDhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,8BA4ChB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,qCAHW,MAAM,8BAwFhB;AAED;;;;;GAKG;AACH,iDAHW,MAAM,qBAiUhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBAwJhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAmFhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA6XhB;AAED;;;;;GAKG;AACH,2CAHW,MAAM;;;;;;;;;;;;;;;;;;;;GAoChB;AAED;;;;;;;;KA+DC;AAED;;;;;;GAMG;AACH,yDA2CC;AAED;;;;;;;;;GASG;AACH,2GA6BC;AAED;;;;;GAKG;AACH,0CAHW,MAAM,EAAE,8BAmclB;AAED;;;;;GAKG;AACH,iCAHW,MAAM,8BAiUhB;AAED;;;;;GAKG;AACH,gCAHW,MAAM,qBAsOhB;AAED;;;;;;GAMG;AACH,wDAFY,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CAAC,CA2FxE"} \ No newline at end of file diff --git a/types/utils.d.ts.map b/types/utils.d.ts.map index 48d25ae97..390760819 100644 --- a/types/utils.d.ts.map +++ b/types/utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../utils.js"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../utils.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/utils.js b/utils.js index d6eacc885..4bb8ebe91 100644 --- a/utils.js +++ b/utils.js @@ -239,6 +239,7 @@ export const PROJECT_TYPE_ALIASES = { "mvn", "maven", "sbt", + "bazel", ], android: ["android", "apk", "aab"], jar: ["jar", "war", "ear"], @@ -6954,6 +6955,10 @@ export function parseCsPkgData(pkgData, pkgFile) { if (!pkgData) { return pkgList; } + // Remove byte order mark + if (pkgData.charCodeAt(0) === 0xfeff) { + pkgData = pkgData.slice(1); + } let packages = xml2js(pkgData, { compact: true, alwaysArray: true, @@ -7010,10 +7015,14 @@ export function parseCsPkgData(pkgData, pkgFile) { */ export function parseCsProjData(csProjData, projFile, pkgNameVersions = {}) { const pkgList = []; - let parentComponent = { type: "application", properties: [] }; + const parentComponent = { type: "application", properties: [] }; if (!csProjData) { return pkgList; } + // Remove byte order mark + if (csProjData.charCodeAt(0) === 0xfeff) { + csProjData = csProjData.slice(1); + } let projects = undefined; try { projects = xml2js(csProjData, { @@ -7079,6 +7088,27 @@ export function parseCsProjData(csProjData, projFile, pkgNameVersions = {}) { }); } if ( + apg?.RootNamespace && + Array.isArray(apg.RootNamespace) && + apg.RootNamespace[0]._ && + Array.isArray(apg.RootNamespace[0]._) + ) { + parentComponent.properties.push({ + name: "Namespaces", + value: apg.RootNamespace[0]._[0], + }); + } + if ( + apg?.TargetFramework && + Array.isArray(apg.TargetFramework) && + apg.TargetFramework[0]._ && + Array.isArray(apg.TargetFramework[0]._) + ) { + parentComponent.properties.push({ + name: "cdx:dotnet:target_framework", + value: apg.TargetFramework[0]._[0], + }); + } else if ( apg?.TargetFrameworkVersion && Array.isArray(apg.TargetFrameworkVersion) && apg.TargetFrameworkVersion[0]._ && @@ -7088,13 +7118,34 @@ export function parseCsProjData(csProjData, projFile, pkgNameVersions = {}) { name: "cdx:dotnet:target_framework", value: apg.TargetFrameworkVersion[0]._[0], }); + } else if ( + apg?.TargetFrameworks && + Array.isArray(apg.TargetFrameworks) && + apg.TargetFrameworks[0]._ && + Array.isArray(apg.TargetFrameworks[0]._) + ) { + parentComponent.properties.push({ + name: "cdx:dotnet:target_framework", + value: apg.TargetFrameworks[0]._[0], + }); + } + if ( + apg?.Description && + Array.isArray(apg.Description) && + apg.Description[0]._ && + Array.isArray(apg.Description[0]._) + ) { + parentComponent.description = apg.Description[0]._[0]; + } else if ( + apg?.PackageDescription && + Array.isArray(apg.PackageDescription) && + apg.PackageDescription[0]._ && + Array.isArray(apg.PackageDescription[0]._) + ) { + parentComponent.description = apg.PackageDescription[0]._[0]; } } } - // If we are unable to determine the name of the parent component, clear the object - if (!parentComponent.purl) { - parentComponent = undefined; - } if (project.ItemGroup?.length) { for (const i in project.ItemGroup) { const item = project.ItemGroup[i]; diff --git a/utils.test.js b/utils.test.js index d24e2aae0..4fcde2369 100644 --- a/utils.test.js +++ b/utils.test.js @@ -1855,7 +1855,7 @@ test("parse cs proj", () => { let retMap = parseCsProjData( readFileSync("./test/sample.csproj", { encoding: "utf-8" }), ); - expect(retMap.parentComponent).toBeUndefined(); + expect(retMap?.parentComponent["bom-ref"]).toBeUndefined(); expect(retMap.pkgList.length).toEqual(5); expect(retMap.pkgList[0]).toEqual({ "bom-ref": "pkg:nuget/Microsoft.AspNetCore.Mvc.NewtonsoftJson@3.1.1", @@ -1864,6 +1864,9 @@ test("parse cs proj", () => { version: "3.1.1", purl: "pkg:nuget/Microsoft.AspNetCore.Mvc.NewtonsoftJson@3.1.1", }); + expect(retMap?.parentComponent.properties).toEqual([ + { name: "cdx:dotnet:target_framework", value: "netcoreapp3.1" }, + ]); retMap = parseCsProjData( readFileSync("./test/data/WindowsFormsApplication1.csproj", { encoding: "utf-8", @@ -1876,6 +1879,10 @@ test("parse cs proj", () => { name: "cdx:dotnet:project_guid", value: "{3336A23A-6F2C-46D4-89FA-93C726CEB23D}", }, + { + name: "Namespaces", + value: "WindowsFormsApplication1", + }, { name: "cdx:dotnet:target_framework", value: "v4.8" }, ], name: "WindowsFormsApplication1", @@ -1957,6 +1964,20 @@ test("parse cs proj", () => { ], }, ]); + expect(retMap?.parentComponent.properties).toEqual([ + { + name: "cdx:dotnet:project_guid", + value: "{3336A23A-6F2C-46D4-89FA-93C726CEB23D}", + }, + { + name: "Namespaces", + value: "WindowsFormsApplication1", + }, + { + name: "cdx:dotnet:target_framework", + value: "v4.8", + }, + ]); retMap = parseCsProjData( readFileSync("./test/data/Server.csproj", { encoding: "utf-8", @@ -1969,6 +1990,7 @@ test("parse cs proj", () => { name: "cdx:dotnet:project_guid", value: "{6BA9F9E1-E43C-489D-A3B4-8916CA2D4C5F}", }, + { name: "Namespaces", value: "OutputMgr.Server" }, { name: "cdx:dotnet:target_framework", value: "v4.8" }, ], name: "Server", @@ -1977,6 +1999,30 @@ test("parse cs proj", () => { "bom-ref": "pkg:nuget/Server@9.0.21022", }); expect(retMap.pkgList.length).toEqual(34); + expect(retMap?.parentComponent.properties).toEqual([ + { + name: "cdx:dotnet:project_guid", + value: "{6BA9F9E1-E43C-489D-A3B4-8916CA2D4C5F}", + }, + { + name: "Namespaces", + value: "OutputMgr.Server", + }, + { + name: "cdx:dotnet:target_framework", + value: "v4.8", + }, + ]); + retMap = parseCsProjData( + readFileSync("./test/data/Logging.csproj", { + encoding: "utf-8", + }), + ); + expect(retMap?.parentComponent["bom-ref"]).toBeUndefined(); + expect(retMap?.parentComponent.properties).toEqual([ + { name: "Namespaces", value: "Sample.OData" }, + { name: "cdx:dotnet:target_framework", value: "$(TargetFrameworks);" }, + ]); }); test("parse project.assets.json", () => { @@ -2194,7 +2240,10 @@ test("parse .net cs proj", () => { ); expect(retMap.parentComponent).toEqual({ type: "library", - properties: [{ name: "cdx:dotnet:target_framework", value: "v4.6.2" }], + properties: [ + { name: "Namespaces", value: "Calculator" }, + { name: "cdx:dotnet:target_framework", value: "v4.6.2" }, + ], name: "Calculator", purl: "pkg:nuget/Calculator@latest", "bom-ref": "pkg:nuget/Calculator@latest",