Diagnose & document Go-template args split by unquoted spaces (#172)#173
Conversation
Adding .gitkeep for PR creation (default mode). This file will be removed when the task is complete. Issue: #172
A literal template token like `--format {{json .Config.Env}}` contains an
unquoted space, so command-stream splits it into separate argv words exactly
as a POSIX shell does. Quoting or interpolating the token passes it through
untouched. To make the failing case easy to spot:
- Emit a one-line stderr warning when a built command contains an unquoted
{{ }} token with an internal space (once per token; silence via
COMMAND_STREAM_NO_TEMPLATE_WARNING=1).
- Add a README "Go templates & {{ }} arguments" section with the
works/breaks/workaround patterns.
- Add examples/go-template-arguments.mjs and a test suite covering the
splitting behavior and the diagnostic.
Add find_split_template_token + warn_on_split_template to rust/src/quote.rs and emit the one-line warning from build_shell_command and the cmd! macro, matching the JavaScript implementation. Silenced via the same COMMAND_STREAM_NO_TEMPLATE_WARNING env var; once per unique token.
Working session summaryEverything is complete and green. Here's the final state of PR #173: SummaryThe failing Rust changelog fragment check is now resolved — that was the last blocker. I added All three CI checks now pass on the latest commit (
The working tree is clean and the PR is mergeable (not draft). What the PR delivers (all three issue asks)
PR: #173 The root-cause finding stands: this is shell-faithful behavior, not corruption — making full template passthrough would deviate from POSIX shell semantics, so the right fix is diagnosis + documentation, which is what's shipped. This summary was automatically extracted from the AI working session output. |
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost estimation:
📊 Context and tokens usage:Claude Opus 4.8: (2 sub-sessions)
Total: (22.8K new + 132.7K cache writes + 7.3M cache reads) input tokens, 52.4K output tokens, $6.393531 cost 🤖 Models used:
📎 Log file uploaded as Gist (2825KB)Now working session is ended, feel free to review and add any feedback on the solution draft. |
✅ Ready to mergeThis pull request is now ready to be merged:
Monitored by hive-mind with --auto-restart-until-mergeable flag |
This reverts commit 7332d23.
Summary
Fixes #172.
A literal Go/Docker template token typed in a
$template — e.g.--format {{json .Config.Env}}— contains an unquoted space, socommand-streamsplits it into separate argv words. That is exactly what a POSIX shell (bash) does, but it surprised users because a space-free{{.Id}}survives while the spaced token reaches Docker broken (template parsing error: ... unclosed action).Root-cause finding
This is shell-faithful behavior, not corruption. I verified command-stream matches
bashargv-for-argv:--format {{json .Config.Env}}(unquoted)--format,{{json,.Config.Env}}--format {{.Id}}(no space)--format,{{.Id}}--format '{{json .Config.Env}}'--format,{{json .Config.Env}}--format "{{json .Config.Env}}"--format,{{json .Config.Env}}--format ${format}(interpolated)--format,{{json .Config.Env}}So the fix is to make the failing case diagnosable and documented, while keeping shell parity (full verbatim passthrough would deviate from shell semantics).
Changes
{{ … }}token with an internal space,command-streamprints a one-line warning to stderr pointing at the gotcha. Fires once per unique token; silence withCOMMAND_STREAM_NO_TEMPLATE_WARNING=1. (src/$.quote.mjs, newfindSplitTemplateToken.){{ }}arguments" showing the works/breaks/workaround patterns.examples/go-template-arguments.mjsdemonstrating each pattern.tests/go-template-quoting.test.mjs(13 tests) asserting splitting/quoting behavior and the warning (emit, dedup, env silence, quoted/space-free no-warn).Reproduction / verification
All new tests pass; the full suite has no new failures (pre-existing
jq-not-installed failures are environmental).Rust parity
The diagnostic is mirrored in the Rust implementation to satisfy the JS/Rust source-parity CI check:
find_split_template_token/warn_on_split_templateinrust/src/quote.rs, wired intobuild_shell_commandand thecmd!macro inrust/src/macros.rs, with unit tests + a doctest and arust/changelog.d/fragment.