From 7e8726bf060856de97c6bc12aebbe5e07b9eee33 Mon Sep 17 00:00:00 2001 From: xumian520 <126989134+xumian520@users.noreply.github.com> Date: Sun, 26 Jul 2026 15:08:44 +0800 Subject: [PATCH 1/3] fix(build): preserve LF for shell entrypoints Signed-off-by: xumian520 <126989134+xumian520@users.noreply.github.com> --- .gitattributes | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitattributes b/.gitattributes index 365ab6abd..95c02ea49 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,8 @@ # Vendored tree-sitter grammars — machine-generated, hide from stats and diffs internal/cbm/vendored/grammars/**/parser.c linguist-generated=true diff=false internal/cbm/vendored/grammars/**/scanner.c linguist-generated=true diff=false + +# Shell entrypoints must stay executable from Windows checkouts mounted in WSL. +*.sh text eol=lf +scripts/git-hooks/commit-msg text eol=lf +scripts/hooks/pre-commit text eol=lf From 1d611bd737408642a908504a401e85c444802052 Mon Sep 17 00:00:00 2001 From: xumian520 <126989134+xumian520@users.noreply.github.com> Date: Sun, 26 Jul 2026 15:09:31 +0800 Subject: [PATCH 2/3] test: run shell line-ending contract Signed-off-by: xumian520 <126989134+xumian520@users.noreply.github.com> --- scripts/test.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/test.sh b/scripts/test.sh index 5155e4e20..b13f5b8da 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -85,6 +85,9 @@ bash "$ROOT/tests/test_makefile_ts_runtime_dependencies.sh" echo "=== Step 0g: security fuzz harness self-test ===" bash "$ROOT/tests/test_security_fuzz_harness.sh" +echo "=== Step 0h: shell line-ending contract ===" +bash "$ROOT/tests/test_shell_line_endings.sh" + # Verify compiler supports target arch verify_compiler "$CC" From 2c4803a47a37d74eca3a3246f1db33e6670b96a8 Mon Sep 17 00:00:00 2001 From: xumian520 <126989134+xumian520@users.noreply.github.com> Date: Sun, 26 Jul 2026 15:10:13 +0800 Subject: [PATCH 3/3] test: enforce LF for shell entrypoints Signed-off-by: xumian520 <126989134+xumian520@users.noreply.github.com> --- tests/test_shell_line_endings.sh | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests/test_shell_line_endings.sh diff --git a/tests/test_shell_line_endings.sh b/tests/test_shell_line_endings.sh new file mode 100644 index 000000000..043b5291b --- /dev/null +++ b/tests/test_shell_line_endings.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Regression guard: shell entrypoints must remain LF in Windows checkouts so +# they can run directly from WSL and MSYS without a `bash\r` shebang failure. + +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$ROOT" + +failures=0 +checked=0 +while IFS= read -r -d '' path && + IFS= read -r -d '' attribute && + IFS= read -r -d '' eol; do + checked=$((checked + 1)) + if [[ "$eol" != "lf" ]]; then + echo "FAIL: $path must declare eol=lf (got ${eol:-unset})" >&2 + failures=$((failures + 1)) + fi +done < <( + git ls-files -z '*.sh' 'scripts/git-hooks/*' 'scripts/hooks/*' | + git check-attr -z --stdin eol +) + +if (( failures > 0 )); then + echo "FAIL: $failures shell entrypoint(s) lack an LF checkout contract" >&2 + exit 1 +fi + +echo "Shell line-ending contract passed ($checked files)"