Răsfoiți Sursa

docs: describe the :; label-line wrapper mechanism (#571)

Drew Ritter 1 lună în urmă
părinte
comite
f2bbe9ff92
2 a modificat fișierele cu 15 adăugiri și 9 ștergeri
  1. 4 2
      docs/porting-to-a-new-harness.md
  2. 11 7
      docs/windows/polyglot-hooks.md

+ 4 - 2
docs/porting-to-a-new-harness.md

@@ -745,8 +745,10 @@ single file that's valid as both a Windows batch script and a Unix shell script.
 On Windows, `cmd.exe` runs the batch portion, which locates `bash` (Git for
 Windows, then `bash` on PATH) and runs the named hook script; if no bash is
 found it exits cleanly so the harness still works, just without injection. On
-Unix, the leading `:` makes the batch block a no-op and the shell runs the
-script directly.
+Unix, the shell executes the leading `:;` lines and `exec`s the hook script
+before reaching the batch block (cmd.exe skips those lines as labels).
+Heredocs are banned throughout hooks/ — see issue #571 and the fence test
+`tests/hooks/test-no-heredocs-in-hooks.sh`.
 
 Two rules this enforces, which you must respect:
 

+ 11 - 7
docs/windows/polyglot-hooks.md

@@ -65,9 +65,9 @@ The path is quoted because `${CLAUDE_PLUGIN_ROOT}` may contain spaces.
 
 ## How `run-hook.cmd` Works at a High Level
 
-`run-hook.cmd` is a polyglot script: Windows treats the first block as batch
-commands, while Unix shells treat that block as a no-op heredoc and continue
-after it.
+`run-hook.cmd` is a polyglot script: its first lines start with `:;`, which
+cmd.exe skips as labels and Unix shells execute — the shell execs the hook
+before ever reaching the batch block that Windows runs.
 
 Do not copy an implementation from this document. Read `hooks/run-hook.cmd`
 directly when changing the dispatcher, and run `tests/hooks/test-session-start.sh`
@@ -89,10 +89,14 @@ afterward.
 
 ### How it works on Unix (bash/sh)
 
-1. `: << 'CMDBLOCK'` opens a heredoc on a no-op command.
-2. The entire CMD batch block is consumed by the heredoc and ignored.
-3. After `CMDBLOCK`, bash resolves the script directory and `exec`s the named
-   extensionless script directly.
+1. Each leading `:;` line is a no-op label to cmd.exe but real commands to a
+   POSIX shell.
+2. The shell checks bash exists (silent exit 0 if not), resolves the script
+   directory CDPATH-proof, and `exec`s the named extensionless script — it
+   never reads the batch block at all.
+3. Heredocs are banned in this file and all hooks/ executables (issue #571:
+   bash >= 5.1 pre-fork pipe writes deadlock on macOS under pipe pressure);
+   `tests/hooks/test-no-heredocs-in-hooks.sh` enforces the ban.
 
 ### Key design decisions