Skip to content

Add shell metacharacter tests and fix error message quoting in exec runner#34

Open
JoshuaOliphant wants to merge 1 commit into
simonw:mainfrom
JoshuaOliphant:fix/shell-metacharacters-in-exec
Open

Add shell metacharacter tests and fix error message quoting in exec runner#34
JoshuaOliphant wants to merge 1 commit into
simonw:mainfrom
JoshuaOliphant:fix/shell-metacharacters-in-exec

Conversation

@JoshuaOliphant
Copy link
Copy Markdown

I was using showboat to build a demo document that needed piped commands — echo hello | wc -l, ls | head -3, that kind of thing. Nothing special. While reading through the runner code I noticed two things: the existing behaviour for shell metacharacters was already correct (bash/sh/zsh get -c, which naturally interprets |, >, &&), but there were no tests proving it. I also spotted the error message using %s to format the interpreter name, which produces ambiguous output when the binary name runs up against punctuation.

This PR adds explicit test coverage for the metacharacter cases and tightens the error formatting. No behaviour change to the runner itself.

Changes

exec/runner_test.go — three new tests:

  • TestRunWithPipe: runs echo hello | wc -l via bash, asserts exit 0 and output 1
  • TestRunWithRedirect: runs echo redirected > file, asserts the file was created with the right content
  • TestRunShellMetacharacters: runs echo one && echo two via sh, asserts both lines appear and exit code is 0

All three check exit codes explicitly, not just output content.

exec/runner.go — one-character change: %s%q in the startup-failure error path. Before: executing python3: exec: "python3": executable file not found. After: executing "python3": exec: .... The quotes make it unambiguous where the binary name ends and the error begins.

Evidence of testing

Built the binary locally and ran a full demo document exercising every metacharacter case:

$ showboat init /tmp/demo.md "Shell Metacharacter Demo"
$ showboat exec /tmp/demo.md bash "echo 'the quick brown fox' | wc -w"
       4
$ showboat exec /tmp/demo.md bash "echo step1 && echo step2 && echo step3"
step1
step2
step3
$ showboat exec /tmp/demo.md bash "echo 'hello from redirect' > /tmp/out.txt && cat /tmp/out.txt"
hello from redirect
$ showboat exec /tmp/demo.md python3 "print(2 + 2)"
4
$ showboat exec /tmp/demo.md sh "printf 'a\nb\nc\n' | grep b"
b
$ showboat verify /tmp/demo.md
(exit 0 — no diffs)

verify passing confirms the round-trip: python3 blocks still execute as Python, not bash. lang stays as the actual interpreter.

Full test suite:

$ go test ./...
ok  	github.com/simonw/showboat	4.140s
ok  	github.com/simonw/showboat/cmd	0.858s
ok  	github.com/simonw/showboat/exec	0.705s
ok  	github.com/simonw/showboat/markdown	(cached)

… tests

Shell interpreters (bash, sh, zsh) already handle metacharacters correctly
via the existing `exec.Command(lang, "-c", code)` dispatch. This commit
adds explicit test coverage for pipes, redirects, and `&&` chaining to
document and protect that behaviour.

Also improves the error message when an interpreter cannot be found: the
binary name is now quoted with %q, making "executing \"python3\": ..."
unambiguous in output.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant