Skip to content

fix(gold-traces): quote record-command arguments for cmd.exe on Windows - #14

Open
kgilpin wants to merge 2 commits into
mainfrom
fix/windows-quoting
Open

kgilpin wants to merge 2 commits into
mainfrom
fix/windows-quoting

Conversation

@kgilpin

@kgilpin kgilpin commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Fixes #7.

shellQuote quoted arguments with single quotes, which cmd.exe does not understand. On Windows a test name with spaces split into several arguments, and a jest, vitest, mocha, minitest or rails-test run with two or more tests put a | in the name filter, which cmd.exe read as a pipe.

How it quotes now on Windows

cmd.exe gets the whole command line as one string, and the program splits it itself using C runtime rules (double quotes group, \" is a literal quote). So the argument is wrapped in double quotes for the program, and every character cmd.exe acts on, the quotes included, is escaped with ^. cmd.exe then never enters quote mode and hands the string over untouched. This is the scheme cross-spawn uses.

Argument POSIX Windows
tests/test_a.py::test_x as is as is
creates an order 'creates an order' ^"creates an order^"
(adds|removes) '(adds|removes)' ^"^(adds^|removes^)^"
100% as is ^"100^%^" (a bare % can name a variable to cmd.exe)

Nothing changes on macOS or Linux. shellQuote takes a platform (default process.platform), and buildCommand passes it through, so the Windows cases are tested on any machine.

Evidence

One test writes a Node script that prints its argv, runs it through the real shell with every kind of argument (spaces, a regex union, escaped parentheses, quotes, & < > ^, %, a trailing backslash), and checks that each one arrives as written. On the Windows runner that shell is cmd.exe.

🤖 Generated with Claude Code

kgilpin and others added 2 commits September 22, 2026 18:40
shellQuote used single quotes, which cmd.exe does not understand. A test name
with spaces split into several arguments, and a jest, vitest, mocha, minitest or
rails-test run with two or more tests put a | in the name filter, which cmd.exe
read as a pipe.

On Windows the argument is now double-quoted for the program and every
character cmd.exe acts on, the quotes included, is escaped with ^, so cmd.exe
passes the string through untouched (the cross-spawn scheme). A bare % is not
left unquoted there, since it can name a variable.

A test runs every quoted argument through the real shell and checks that it
reaches the program as written; the Windows CI runner runs it through cmd.exe.

Closes #7

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@kgilpin
kgilpin requested a review from dividedmind September 23, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows: record commands are quoted for sh, but run through cmd.exe

2 participants