Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
"generate:api": "npm run generate:api:intelligence-service && npm run generate:api:application-server",
"format:java": "node --import tsx scripts/run-quiet.ts prettier --write \"server/application-server/src/**/*.java\" --config-precedence prefer-file --config server/application-server/.prettierrc.yaml --ignore-path server/application-server/.prettierignore",
"format:java:check": "node --import tsx scripts/run-quiet.ts prettier --check \"server/application-server/src/**/*.java\" --config-precedence prefer-file --config server/application-server/.prettierrc.yaml --ignore-path server/application-server/.prettierignore",
"lint:java": "cd server/application-server && ./mvnw pmd:check -q",
"lint:java:report": "cd server/application-server && ./mvnw pmd:pmd && echo 'Report: server/application-server/target/site/pmd.html'",
"lint:java": "node --import tsx scripts/run-mvnw.ts pmd:check -q",
"lint:java:report": "node --import tsx scripts/run-mvnw.ts pmd:pmd && echo 'Report: server/application-server/target/site/pmd.html'",
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

echo 'Report: ...' is Bash-friendly, but on Windows cmd.exe it prints the single quotes literally. Since this script is being made Windows-compatible, consider switching to echo Report: ... (no quotes) or printing via Node so the output is consistent across shells.

Suggested change
"lint:java:report": "node --import tsx scripts/run-mvnw.ts pmd:pmd && echo 'Report: server/application-server/target/site/pmd.html'",
"lint:java:report": "node --import tsx scripts/run-mvnw.ts pmd:pmd && echo Report: server/application-server/target/site/pmd.html",

Copilot uses AI. Check for mistakes.
"format:intelligence-service": "npm -w server/intelligence-service run format",
"format:intelligence-service:check": "npm -w server/intelligence-service run format:check",
"lint:intelligence-service": "npm -w server/intelligence-service run lint",
Expand Down
53 changes: 53 additions & 0 deletions scripts/run-mvnw.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env node
/**
* Cross-platform Maven wrapper runner.
* Resolves ./mvnw (Unix) or mvnw.cmd (Windows) automatically.
*
* Usage: node --import tsx scripts/run-mvnw.ts [maven-args...]
* Example: node --import tsx scripts/run-mvnw.ts pmd:check -q
*/

import { spawnSync } from "node:child_process";
import path from "node:path";
import process from "node:process";
import { fileURLToPath } from "node:url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const mvnwDir = path.resolve(__dirname, "..", "server", "application-server");
const isWindows = process.platform === "win32";

function main(): void {
// shell: true is required on Windows for .cmd files (CVE-2024-27980).
// Safe here because args come from hardcoded npm scripts, not user input.
const result = spawnSync(
isWindows ? "mvnw.cmd" : "./mvnw",
process.argv.slice(2),
{
stdio: "inherit",
cwd: mvnwDir,
shell: isWindows,
Comment on lines +18 to +28
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using shell: true on Windows while forwarding process.argv.slice(2) allows shell metacharacters (e.g. &, |, >) to be interpreted by cmd.exe when someone runs npm run lint:java -- <args...> or invokes this script directly. To avoid this, consider spawning cmd.exe explicitly with a safely-quoted command line (or using a library like cross-spawn), and/or validating/escaping args so they’re never interpreted by the shell.

Suggested change
function main(): void {
// shell: true is required on Windows for .cmd files (CVE-2024-27980).
// Safe here because args come from hardcoded npm scripts, not user input.
const result = spawnSync(
isWindows ? "mvnw.cmd" : "./mvnw",
process.argv.slice(2),
{
stdio: "inherit",
cwd: mvnwDir,
shell: isWindows,
const mvnwPath = path.join(mvnwDir, isWindows ? "mvnw.cmd" : "mvnw");
function main(): void {
// Run the Maven wrapper directly to avoid shell interpretation of arguments.
const result = spawnSync(
mvnwPath,
process.argv.slice(2),
{
stdio: "inherit",
cwd: mvnwDir,

Copilot uses AI. Check for mistakes.
},
);
Comment on lines +22 to +30
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Windows shell: true means the spawned process is cmd.exe, so a missing mvnw.cmd typically won’t surface as result.error/ENOENT; instead you’ll get a non-zero status (often 9009) and a generic shell message. If you want the actionable “wrapper not found” error cross-platform, check for the wrapper file’s existence before spawning (or explicitly detect the Windows command-not-found exit code and print the same message).

Copilot uses AI. Check for mistakes.

if (result.error) {
const errCode = (result.error as NodeJS.ErrnoException).code;
if (errCode === "ENOENT") {
console.error(
`Maven wrapper not found in ${mvnwDir}. Is the Maven wrapper installed?`,
);
} else {
console.error(`Failed to run Maven wrapper: ${result.error.message}`);
}
process.exitCode = 1;
return;
}

if (result.signal) {
process.kill(process.pid, result.signal);
return;
}

process.exitCode = result.status ?? 1;
}

main();
Loading