fix: normalize generated hook line endings#175
Conversation
PR Summary
|
3c7f634 to
f615626
Compare
There was a problem hiding this comment.
Pull request overview
This PR addresses cross-platform shell hook execution issues by ensuring Husky-generated hook scripts use LF line endings, preventing CRLF shebangs from breaking on Linux/WSL.
Changes:
- Added
ShellScriptLineEndings.Normalizeutility to convert CRLF/CR to LF. - Applied normalization when generating
.husky/_/husky.shand hooks created viaset, and added.husky/.gitattributesto enforce LF checkouts. - Added regression tests covering CRLF and standalone CR normalization, plus install behavior for
.gitattributes.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/Husky/Utils/ShellScriptLineEndings.cs |
Introduces LF normalization helper for shell script content. |
src/Husky/Cli/SetCommand.cs |
Normalizes generated hook file content before writing. |
src/Husky/Cli/InstallCommand.cs |
Normalizes husky.sh template and creates .husky/.gitattributes to enforce LF. |
tests/HuskyTest/Utils/LineEndingTests.cs |
Adds unit tests for CRLF and CR-to-LF normalization. |
tests/HuskyTest/Cli/InstallCommandTests.cs |
Adds coverage for .gitattributes creation/non-overwrite during install. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var content = ShellScriptLineEndings.Normalize(await sr.ReadToEndAsync()); | ||
| var hookContent = ShellScriptLineEndings.Normalize($"{content}\n{Command}\n"); | ||
| await _fileSystem.File.WriteAllTextAsync(hookPath, hookContent); |
There was a problem hiding this comment.
set now normalizes the initially generated hook content, but add can still append Command containing \r/CRLF (see AddCommand.AppendAllTextAsync(...)), reintroducing CR characters into an existing hook script and breaking execution on Linux. Normalize the appended content (or read/normalize/rewrite the whole file) in the add flow as well so hooks remain LF-only after subsequent add operations.
| // Keep Husky hook scripts LF-only even when users have core.autocrlf enabled. | ||
| var gitAttributesPath = Path.Combine(path, GIT_ATTRIBUTES_FILE_NAME); | ||
| if (!_fileSystem.File.Exists(gitAttributesPath)) | ||
| _fileSystem.File.WriteAllText(gitAttributesPath, GIT_ATTRIBUTES_CONTENT); | ||
|
|
There was a problem hiding this comment.
Line-ending normalization + .gitattributes creation is duplicated between CreateResources and CreateResourcesAsync, and CreateResources appears unused in this file (only CreateResourcesAsync is called). This increases the risk of these two paths diverging over time; consider removing the dead sync method or extracting shared logic into a single helper used by the actual execution path.
f615626 to
d21a311
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
Test Plan
Context
This prevents CRLF shebangs in generated hook scripts from breaking execution on Linux/WSL with errors like: fatal: cannot exec '.husky/pre-commit': No such file or directory