From 027ccce5365276236dd89fd43796a1bafeb8e11a Mon Sep 17 00:00:00 2001 From: Roland Asmann Date: Sun, 2 Feb 2025 07:19:42 +0100 Subject: [PATCH 1/5] We need to let spawnSync know if we are on Windows or not Signed-off-by: Roland Asmann --- lib/cli/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/cli/index.js b/lib/cli/index.js index af2de430c..5e3146c32 100644 --- a/lib/cli/index.js +++ b/lib/cli/index.js @@ -1863,6 +1863,7 @@ export async function createJavaBom(path, options) { const sresult = spawnSync(gradleCmd, gradleArguments, { cwd: gradleRootPath, encoding: "utf-8", + shell: isWin, timeout: TIMEOUT_MS, maxBuffer: MAX_BUFFER, }); From 0f7525e44609a83e2e2e2bd230da937656cb4bd6 Mon Sep 17 00:00:00 2001 From: Roland Asmann Date: Sun, 2 Feb 2025 08:12:34 +0100 Subject: [PATCH 2/5] Coommands on Windows can't be longer than 8191 characters! Signed-off-by: Roland Asmann --- lib/cli/index.js | 45 +++++++++++---------- lib/helpers/utils.js | 95 +++++++++++++++++++++++++++++--------------- 2 files changed, 87 insertions(+), 53 deletions(-) diff --git a/lib/cli/index.js b/lib/cli/index.js index 5e3146c32..cbc0cf0c6 100644 --- a/lib/cli/index.js +++ b/lib/cli/index.js @@ -1852,29 +1852,34 @@ export async function createJavaBom(path, options) { process.env.GRADLE_ARGS_DEPENDENCIES ? process.env.GRADLE_ARGS_DEPENDENCIES.split(" ") : [], + gradleCmd.length, ); - console.log( - "Executing", - gradleCmd, - gradleArguments.join(" "), - "in", - gradleRootPath, - ); - const sresult = spawnSync(gradleCmd, gradleArguments, { - cwd: gradleRootPath, - encoding: "utf-8", - shell: isWin, - timeout: TIMEOUT_MS, - maxBuffer: MAX_BUFFER, - }); - - if (sresult.status !== 0 || sresult.error) { - if (options.failOnError || DEBUG_MODE) { - console.error(sresult.stdout, sresult.stderr); + const allOutputs = []; + for (const gradleArg of gradleArguments) { + console.log( + "Executing", + gradleCmd, + gradleArg.join(" "), + "in", + gradleRootPath, + ); + const sresult = spawnSync(gradleCmd, gradleArg, { + cwd: gradleRootPath, + encoding: "utf-8", + shell: isWin, + timeout: TIMEOUT_MS, + maxBuffer: MAX_BUFFER, + }); + if (sresult.status !== 0 || sresult.error) { + if (options.failOnError || DEBUG_MODE) { + console.error(sresult.stdout, sresult.stderr); + } + options.failOnError && process.exit(1); } - options.failOnError && process.exit(1); + allOutputs.push(sresult.stdout); } - const sstdout = sresult.stdout; + + const sstdout = allOutputs.join("\n"); if (sstdout) { const cmdOutput = Buffer.from(sstdout).toString(); const perProjectOutput = splitOutputByGradleProjects(cmdOutput, [ diff --git a/lib/helpers/utils.js b/lib/helpers/utils.js index 97b9115d0..3747d0b65 100644 --- a/lib/helpers/utils.js +++ b/lib/helpers/utils.js @@ -3782,43 +3782,56 @@ export function executeParallelGradleProperties(dir, allProjectsStr) { process.env.GRADLE_ARGS_PROPERTIES ? process.env.GRADLE_ARGS_PROPERTIES.split(" ") : [], + gradleCmd.length, ); - const result = spawnSync(gradleCmd, gradleArgs, { - cwd: dir, - encoding: "utf-8", - shell: isWin, - maxBuffer: MAX_BUFFER, - }); - if (result.status !== 0 || result.error) { - if (result.stderr) { - console.error(result.stdout, result.stderr); - console.log( - "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 23 with gradle 8 which might be incompatible.", - ); - console.log( - "2. Try running cdxgen with the custom JDK11-based image `ghcr.io/cyclonedx/cdxgen-java11:v11`.", - ); - if (result.stderr?.includes("not get unknown property")) { + const allOutputs = []; + for (const gradleArg of gradleArgs) { + console.log( + "Executing", + gradleCmd, + gradleArg.join(" "), + "in", + dir, + ); + const result = spawnSync(gradleCmd, gradleArg, { + cwd: dir, + encoding: "utf-8", + shell: isWin, + maxBuffer: MAX_BUFFER, + }); + if (result.status !== 0 || result.error) { + if (result.stderr) { + console.error(result.stdout, result.stderr); console.log( - "3. Check if the SBOM is generated for the correct root project for your application.", + "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 23 with gradle 8 which might be incompatible.", ); - } else if ( - result.stderr?.includes( - "In version catalog libs, import of external catalog file failed", - ) - ) { console.log( - "3. Catalog file is required for gradle dependency resolution to succeed.", + "2. Try running cdxgen with the custom JDK11-based image `ghcr.io/cyclonedx/cdxgen-java11:v11`.", ); - } - if (result.stderr.includes("does not exist")) { - return ""; + if (result.stderr?.includes("not get unknown property")) { + console.log( + "3. Check if the SBOM is generated for the correct root project for your application.", + ); + } else if ( + result.stderr?.includes( + "In version catalog libs, import of external catalog file failed", + ) + ) { + console.log( + "3. Catalog file is required for gradle dependency resolution to succeed.", + ); + } + if (result.stderr.includes("does not exist")) { + return ""; + } } } + allOutputs.push(result.stdout); } - const stdout = result.stdout; - if (stdout) { - return Buffer.from(stdout).toString(); + + const sstdout = allOutputs.join("\n"); + if (sstdout) { + return Buffer.from(sstdout).toString(); } return ""; } @@ -11803,25 +11816,41 @@ export function getGradleCommand(srcPath, rootPath) { * @param {string[]} gradleArguments The general gradle arguments, which must only be added once * @param {string[]} gradleSubCommands The sub-commands that are to be executed by gradle * @param {string[]} gradleSubCommandArguments The arguments specific to the sub-command(s), which much be added PER sub-command + * @param {int} gradleCommandLength The length of the full gradle-command * - * @returns {string[]} Array of arguments to be added to the gradle command + * @returns {string[]} Array of arrays of arguments to be added to the gradle command */ export function buildGradleCommandArguments( gradleArguments, gradleSubCommands, gradleSubCommandArguments, + gradleCommandLength, ) { - let allGradleArguments = [ + const mainGradleArguments = [ "--build-cache", "--console", "plain", "--no-parallel", ].concat(gradleArguments); + const maxCliArgsLength = isWin ? 8191 - gradleCommandLength - mainGradleArguments.join(" ").length - 2 : -1; + const splitArgs = []; + let allGradleArguments = [].concat(mainGradleArguments); + let remainingLength = maxCliArgsLength; for (const gradleSubCommand of gradleSubCommands) { - allGradleArguments.push(gradleSubCommand); + const subCommandLength = [gradleSubCommand, ...gradleSubCommandArguments].join(" ").length + 1; + if (maxCliArgsLength !== -1 && remainingLength - subCommandLength < 0) { + splitArgs.push(allGradleArguments); + allGradleArguments = [].concat(mainGradleArguments); + remainingLength = maxCliArgsLength; + } + allGradleArguments.push(gradleSubCommand) allGradleArguments = allGradleArguments.concat(gradleSubCommandArguments); + remainingLength -= subCommandLength; + } + if (allGradleArguments.length !== mainGradleArguments.length) { + splitArgs.push(allGradleArguments); } - return allGradleArguments; + return splitArgs; } /** From 7d9b93e3338e432fd402066e367ea38bb371880f Mon Sep 17 00:00:00 2001 From: Roland Asmann Date: Sun, 2 Feb 2025 21:27:41 +0100 Subject: [PATCH 3/5] Windows sucks... Use a bit of a margin to get this to work... Signed-off-by: Roland Asmann --- lib/helpers/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/helpers/utils.js b/lib/helpers/utils.js index 3747d0b65..dedc67138 100644 --- a/lib/helpers/utils.js +++ b/lib/helpers/utils.js @@ -11832,7 +11832,7 @@ export function buildGradleCommandArguments( "plain", "--no-parallel", ].concat(gradleArguments); - const maxCliArgsLength = isWin ? 8191 - gradleCommandLength - mainGradleArguments.join(" ").length - 2 : -1; + const maxCliArgsLength = isWin ? 8000 - gradleCommandLength - mainGradleArguments.join(" ").length - 2 : -1; const splitArgs = []; let allGradleArguments = [].concat(mainGradleArguments); let remainingLength = maxCliArgsLength; From 3448dc580a4e85d56933dd00d11d4f79d40cd648 Mon Sep 17 00:00:00 2001 From: Roland Asmann Date: Sun, 2 Feb 2025 23:17:25 +0100 Subject: [PATCH 4/5] We need even more margin! Signed-off-by: Roland Asmann --- lib/helpers/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/helpers/utils.js b/lib/helpers/utils.js index dedc67138..11a9fc69a 100644 --- a/lib/helpers/utils.js +++ b/lib/helpers/utils.js @@ -11832,7 +11832,7 @@ export function buildGradleCommandArguments( "plain", "--no-parallel", ].concat(gradleArguments); - const maxCliArgsLength = isWin ? 8000 - gradleCommandLength - mainGradleArguments.join(" ").length - 2 : -1; + const maxCliArgsLength = isWin ? 7500 - gradleCommandLength - mainGradleArguments.join(" ").length - 2 : -1; const splitArgs = []; let allGradleArguments = [].concat(mainGradleArguments); let remainingLength = maxCliArgsLength; From 64b497df19dfe38377e21cd72c86ddf7bff8a199 Mon Sep 17 00:00:00 2001 From: Roland Asmann Date: Mon, 3 Feb 2025 02:28:05 +0100 Subject: [PATCH 5/5] Linting Signed-off-by: Roland Asmann --- lib/helpers/utils.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/lib/helpers/utils.js b/lib/helpers/utils.js index 11a9fc69a..fea17333d 100644 --- a/lib/helpers/utils.js +++ b/lib/helpers/utils.js @@ -3786,13 +3786,7 @@ export function executeParallelGradleProperties(dir, allProjectsStr) { ); const allOutputs = []; for (const gradleArg of gradleArgs) { - console.log( - "Executing", - gradleCmd, - gradleArg.join(" "), - "in", - dir, - ); + console.log("Executing", gradleCmd, gradleArg.join(" "), "in", dir); const result = spawnSync(gradleCmd, gradleArg, { cwd: dir, encoding: "utf-8", @@ -11832,18 +11826,21 @@ export function buildGradleCommandArguments( "plain", "--no-parallel", ].concat(gradleArguments); - const maxCliArgsLength = isWin ? 7500 - gradleCommandLength - mainGradleArguments.join(" ").length - 2 : -1; + const maxCliArgsLength = isWin + ? 7500 - gradleCommandLength - mainGradleArguments.join(" ").length - 2 + : -1; const splitArgs = []; let allGradleArguments = [].concat(mainGradleArguments); let remainingLength = maxCliArgsLength; for (const gradleSubCommand of gradleSubCommands) { - const subCommandLength = [gradleSubCommand, ...gradleSubCommandArguments].join(" ").length + 1; + const subCommandLength = + [gradleSubCommand, ...gradleSubCommandArguments].join(" ").length + 1; if (maxCliArgsLength !== -1 && remainingLength - subCommandLength < 0) { splitArgs.push(allGradleArguments); allGradleArguments = [].concat(mainGradleArguments); remainingLength = maxCliArgsLength; } - allGradleArguments.push(gradleSubCommand) + allGradleArguments.push(gradleSubCommand); allGradleArguments = allGradleArguments.concat(gradleSubCommandArguments); remainingLength -= subCommandLength; }