From c88870ac931df047e742e9e2d9f440a2dd63e63f Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 6 Apr 2026 16:51:18 +0100 Subject: [PATCH] refactor: dedupe windows cmd runner helpers --- scripts/npm-runner.mjs | 22 +--------------------- scripts/pnpm-runner.mjs | 18 +----------------- scripts/windows-cmd-helpers.mjs | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 38 deletions(-) create mode 100644 scripts/windows-cmd-helpers.mjs diff --git a/scripts/npm-runner.mjs b/scripts/npm-runner.mjs index 9e1324e0ff1..aa86c3a6b30 100644 --- a/scripts/npm-runner.mjs +++ b/scripts/npm-runner.mjs @@ -1,26 +1,6 @@ import fs from "node:fs"; import path from "node:path"; - -const WINDOWS_UNSAFE_CMD_CHARS_RE = /[&|<>%\r\n]/; - -function resolvePathEnvKey(env) { - return Object.keys(env).find((key) => key.toLowerCase() === "path") ?? "PATH"; -} - -function escapeForCmdExe(arg) { - if (WINDOWS_UNSAFE_CMD_CHARS_RE.test(arg)) { - throw new Error(`unsafe Windows cmd.exe argument detected: ${JSON.stringify(arg)}`); - } - const escaped = arg.replace(/\^/g, "^^"); - if (!escaped.includes(" ") && !escaped.includes('"')) { - return escaped; - } - return `"${escaped.replace(/"/g, '""')}"`; -} - -function buildCmdExeCommandLine(command, args) { - return [escapeForCmdExe(command), ...args.map(escapeForCmdExe)].join(" "); -} +import { buildCmdExeCommandLine, resolvePathEnvKey } from "./windows-cmd-helpers.mjs"; function resolveToolchainNpmRunner(params) { const npmCliCandidates = [ diff --git a/scripts/pnpm-runner.mjs b/scripts/pnpm-runner.mjs index 4d97ba86af5..de4a69d0c23 100644 --- a/scripts/pnpm-runner.mjs +++ b/scripts/pnpm-runner.mjs @@ -1,27 +1,11 @@ import { spawn } from "node:child_process"; import path from "node:path"; - -const WINDOWS_UNSAFE_CMD_CHARS_RE = /[&|<>%\r\n]/; +import { buildCmdExeCommandLine } from "./windows-cmd-helpers.mjs"; function isPnpmExecPath(value) { return /^pnpm(?:-cli)?(?:\.(?:c?js|cmd|exe))?$/.test(path.basename(value).toLowerCase()); } -function escapeForCmdExe(arg) { - if (WINDOWS_UNSAFE_CMD_CHARS_RE.test(arg)) { - throw new Error(`unsafe Windows cmd.exe argument detected: ${JSON.stringify(arg)}`); - } - const escaped = arg.replace(/\^/g, "^^"); - if (!escaped.includes(" ") && !escaped.includes('"')) { - return escaped; - } - return `"${escaped.replace(/"/g, '""')}"`; -} - -function buildCmdExeCommandLine(command, args) { - return [escapeForCmdExe(command), ...args.map(escapeForCmdExe)].join(" "); -} - export function resolvePnpmRunner(params = {}) { const pnpmArgs = params.pnpmArgs ?? []; const nodeArgs = params.nodeArgs ?? []; diff --git a/scripts/windows-cmd-helpers.mjs b/scripts/windows-cmd-helpers.mjs new file mode 100644 index 00000000000..021c2c61cab --- /dev/null +++ b/scripts/windows-cmd-helpers.mjs @@ -0,0 +1,20 @@ +const WINDOWS_UNSAFE_CMD_CHARS_RE = /[&|<>%\r\n]/; + +export function resolvePathEnvKey(env) { + return Object.keys(env).find((key) => key.toLowerCase() === "path") ?? "PATH"; +} + +export function escapeForCmdExe(arg) { + if (WINDOWS_UNSAFE_CMD_CHARS_RE.test(arg)) { + throw new Error(`unsafe Windows cmd.exe argument detected: ${JSON.stringify(arg)}`); + } + const escaped = arg.replace(/\^/g, "^^"); + if (!escaped.includes(" ") && !escaped.includes('"')) { + return escaped; + } + return `"${escaped.replace(/"/g, '""')}"`; +} + +export function buildCmdExeCommandLine(command, args) { + return [escapeForCmdExe(command), ...args.map(escapeForCmdExe)].join(" "); +}