Skip to content

Commit bb1a67a

Browse files
committed
Testing skip hooks option
1 parent 27dba50 commit bb1a67a

File tree

10 files changed

+179
-6
lines changed

10 files changed

+179
-6
lines changed

.lefthook.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# .lefthook.yml
2+
# Fast pre-commit hooks that only check changed files
3+
# Install with: bundle exec lefthook install
4+
5+
pre-commit:
6+
parallel: true
7+
commands:
8+
autofix:
9+
run: bin/lefthook/ruby-autofix staged
10+
11+
rubocop:
12+
run: bin/lefthook/ruby-lint staged
13+
14+
prettier:
15+
run: bin/lefthook/prettier-format staged
16+
17+
trailing-newlines:
18+
run: bin/lefthook/check-trailing-newlines staged
19+
20+
pre-push:
21+
commands:
22+
branch-lint:
23+
run: bin/lefthook/ruby-lint branch

CLAUDE.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
1212

1313
These requirements are non-negotiable. CI will fail if not followed.
1414

15+
**🚀 RECOMMENDED: Install Git hooks to automate these checks:**
16+
17+
```bash
18+
# Install Lefthook hooks (already included in Gemfile)
19+
bundle install
20+
bundle exec lefthook install
21+
```
22+
23+
This will automatically run linting on **only the files you changed** before each commit - making it fast!
24+
25+
**Note:** Git hooks are for React on Rails gem developers only, not for users who install the gem.
26+
1527
## Development Commands
1628

1729
### Essential Commands

CONTRIBUTING.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@
77
## Prerequisites
88

99
- [Yalc](https://github.com/whitecolor/yalc) must be installed globally for most local development.
10+
- **Git hooks setup** (REQUIRED for all contributors):
11+
12+
```sh
13+
cd react_on_rails/
14+
bundle install
15+
bundle exec lefthook install
16+
```
17+
18+
This sets up automatic linting that runs **only on files you changed** - making commits fast while preventing CI failures.
19+
1020
- After updating code via Git, to prepare all examples:
1121

1222
```sh
@@ -457,7 +467,9 @@ This approach:
457467

458468
## Pre-Commit Requirements
459469

460-
**CRITICAL**: Before committing any changes, always run the following commands to ensure code quality:
470+
**AUTOMATED**: If you've set up Lefthook (see Prerequisites), linting runs automatically on changed files before each commit.
471+
472+
**MANUAL OPTION**: If you need to run linting manually:
461473

462474
```bash
463475
# Navigate to the main react_on_rails directory
@@ -476,14 +488,14 @@ rake lint:rubocop
476488
rake lint
477489
```
478490

479-
**Automated checks:**
491+
**Git hooks automatically run:**
480492

481-
- Format all JavaScript/TypeScript files with Prettier
493+
- Format JavaScript/TypeScript files with Prettier (on changed files only)
482494
- Check and fix linting issues with ESLint
483-
- Check and fix Ruby style issues with RuboCop
484-
- Ensure all tests pass before pushing
495+
- Check and fix Ruby style issues with RuboCop (on changed files only)
496+
- Ensure trailing newlines on all files
485497

486-
**Tip**: Set up your IDE to run these automatically on save to catch issues early.
498+
**Setup once**: `bundle exec lefthook install` (see Prerequisites above)
487499

488500
## 🤖 Best Practices for AI Coding Agents
489501

Gemfile.development_dependencies

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ group :development, :test do
3838
gem "rubocop-rspec", "~>2.26", require: false
3939
gem "scss_lint", require: false
4040
gem "spring", "~> 4.0"
41+
gem "lefthook", require: false
4142
end
4243

4344
group :test do

Gemfile.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ GEM
156156
launchy (3.0.1)
157157
addressable (~> 2.8)
158158
childprocess (~> 5.0)
159+
lefthook (1.13.1)
159160
listen (3.9.0)
160161
rb-fsevent (~> 0.10, >= 0.10.3)
161162
rb-inotify (~> 0.9, >= 0.9.10)
@@ -412,6 +413,7 @@ DEPENDENCIES
412413
jbuilder
413414
jquery-rails
414415
launchy
416+
lefthook
415417
listen
416418
package_json
417419
pry
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env bash
2+
# Check for trailing newlines on all changed files
3+
set -euo pipefail
4+
5+
CONTEXT="${1:-staged}"
6+
files="$(bin/lefthook/get-changed-files "$CONTEXT" '.*')"
7+
8+
if [ -z "$files" ]; then
9+
echo "✅ No files to check for trailing newlines"
10+
exit 0
11+
fi
12+
13+
echo "🔍 Checking trailing newlines on $CONTEXT files..."
14+
15+
failed_files=""
16+
for file in $files; do
17+
if [ -f "$file" ] && [ -s "$file" ]; then
18+
if ! tail -c 1 "$file" | grep -q '^$'; then
19+
echo "❌ Missing trailing newline: $file"
20+
failed_files="$failed_files $file"
21+
fi
22+
fi
23+
done
24+
25+
if [ -n "$failed_files" ]; then
26+
echo ""
27+
echo "❌ Trailing newline check failed!"
28+
echo "💡 Add trailing newlines to:$failed_files"
29+
echo "🔧 Quick fix: for file in$failed_files; do echo >> \"\$file\"; done"
30+
echo "🚫 Skip hook: git commit --no-verify"
31+
exit 1
32+
fi
33+
34+
echo "✅ All files have proper trailing newlines"

bin/lefthook/get-changed-files

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
# Get changed files based on context (staged, branch, or all)
3+
set -euo pipefail
4+
5+
CONTEXT="${1:-staged}"
6+
PATTERN="${2:-.*}"
7+
8+
case "$CONTEXT" in
9+
staged)
10+
git diff --cached --name-only --diff-filter=ACM | grep -E "$PATTERN" || true
11+
;;
12+
branch)
13+
# Find base branch (prefer main over master)
14+
base="origin/main"
15+
git rev-parse --verify --quiet "$base" >/dev/null || base="origin/master"
16+
git diff --name-only --diff-filter=ACM "$base"...HEAD | grep -E "$PATTERN" || true
17+
;;
18+
*)
19+
echo "Usage: $0 {staged|branch} [pattern]" >&2
20+
exit 1
21+
;;
22+
esac

bin/lefthook/prettier-format

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
# Format JS/TS/JSON/MD files with Prettier
3+
set -euo pipefail
4+
5+
CONTEXT="${1:-staged}"
6+
files="$(bin/lefthook/get-changed-files "$CONTEXT" '\.(js|jsx|ts|tsx|json|md|yml|yaml)$')"
7+
8+
if [ -z "$files" ]; then
9+
echo "✅ No files to format with Prettier"
10+
exit 0
11+
fi
12+
13+
echo "💅 Prettier on $CONTEXT files:"
14+
printf " %s\n" $files
15+
16+
yarn run prettier --write $files
17+
18+
# Re-stage files if running on staged context
19+
if [ "$CONTEXT" = "staged" ]; then
20+
echo $files | xargs -r git add
21+
echo "✅ Re-staged formatted files"
22+
fi

bin/lefthook/ruby-autofix

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
# Auto-fix Ruby files using rake autofix
3+
set -euo pipefail
4+
5+
CONTEXT="${1:-staged}"
6+
files="$(bin/lefthook/get-changed-files "$CONTEXT" '\.(rb|rake|ru)$')"
7+
8+
if [ -z "$files" ]; then
9+
echo "✅ No Ruby files to autofix"
10+
exit 0
11+
fi
12+
13+
echo "🎨 Autofix on $CONTEXT Ruby files:"
14+
printf " %s\n" $files
15+
16+
bundle exec rake autofix
17+
18+
# Re-stage files if running on staged context
19+
if [ "$CONTEXT" = "staged" ]; then
20+
echo $files | xargs -r git add
21+
echo "✅ Re-staged formatted files"
22+
fi

bin/lefthook/ruby-lint

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
# Lint Ruby files with RuboCop
3+
set -euo pipefail
4+
5+
CONTEXT="${1:-staged}"
6+
files="$(bin/lefthook/get-changed-files "$CONTEXT" '\.(rb|rake|ru)$')"
7+
8+
if [ -z "$files" ]; then
9+
echo "✅ No Ruby files to lint"
10+
exit 0
11+
fi
12+
13+
echo "🔍 RuboCop on $CONTEXT Ruby files:"
14+
printf " %s\n" $files
15+
16+
if ! bundle exec rubocop --force-exclusion --display-cop-names -- $files; then
17+
echo ""
18+
echo "❌ RuboCop check failed!"
19+
echo "💡 Auto-fix: bundle exec rubocop --auto-correct --force-exclusion -- $files"
20+
echo "🚫 Skip hook: git commit --no-verify"
21+
exit 1
22+
fi
23+
echo "✅ RuboCop checks passed for Ruby files"

0 commit comments

Comments
 (0)