fix(migrate): reject nested command substitutions

This commit is contained in:
Mohamed Boudra
2026-07-19 06:30:11 +02:00
parent 0c3c61be94
commit 2505075beb
2 changed files with 21 additions and 0 deletions
@@ -163,6 +163,7 @@ test("preserves literal or escaped Conductor names and rewrites active variables
arithmeticOffset: { command: "serve --port $(( CONDUCTOR_PORT + 1 ))" },
prefixExpansion: { command: "serve --length ${#CONDUCTOR_PORT}" },
unicodePrefix: { command: 'printf 😀 "$CONDUCTOR_PORT"' },
commandSubstitution: { command: "printf \"$(printf '$CONDUCTOR_PORT')\"" },
},
},
});
@@ -196,6 +197,11 @@ test("preserves literal or escaped Conductor names and rewrites active variables
message:
"scripts.prefixExpansion: Unsupported Conductor variables: CONDUCTOR_PORT. Command was not imported.",
});
expect(inspected.notices).toContainEqual({
code: "conductor-setting-unsupported",
level: "warning",
message: "scripts.commandSubstitution: Command substitutions are not imported.",
});
});
test("skips cwd scripts on Windows instead of emitting POSIX shell syntax", () => {
@@ -369,6 +369,10 @@ function rewriteExactCommand(
notices: MigrationNotice[],
platform: NodeJS.Platform,
): string | null {
if (containsActiveCommandSubstitution(command)) {
notices.push(unsupportedSetting(key, "Command substitutions are not imported."));
return null;
}
if (containsActiveHereDocument(command)) {
notices.push(unsupportedSetting(key, "Here-document commands are not imported."));
return null;
@@ -727,6 +731,17 @@ function containsActiveHereDocument(command: string): boolean {
return false;
}
function containsActiveCommandSubstitution(command: string): boolean {
const mask = activeShellMask(command);
for (const match of command.matchAll(/\$\((?!\()/g)) {
if (mask.slice(match.index, match.index + 2) === "$(") return true;
}
for (const match of command.matchAll(/`/g)) {
if (mask[match.index] === "`") return true;
}
return false;
}
function appendArgs(command: string, args: string[]): string {
return args.length === 0 ? command : `${command} ${args.map(shellQuoteArgument).join(" ")}`;
}