Skip to content

feat: add Lefthook for Git hooks management #209

@justin808

Description

@justin808

Add Lefthook for Git Hooks Management

Summary

Propose migrating to Lefthook for managing Git hooks to provide fast, parallel pre-commit checks that prevent simple test and lint failures.

Motivation

Currently, the project uses [Husky/lint-staged OR custom scripts]. Lefthook offers several advantages:

  • Parallel execution: Run multiple checks simultaneously for faster feedback
  • Language agnostic: Works across Ruby, JS, and other languages
  • Minimal dependencies: Single binary, no Node.js required for Ruby projects
  • Maintained by Evil Martians: Well-maintained, widely adopted in Ruby/Rails ecosystem
  • Smart file filtering: Built-in glob patterns for targeting specific file types

Proposed Implementation

Based on successful implementation in shakacode/package_json#32:

Pre-commit Hooks (Fast - runs in seconds)

Run in parallel on staged files only:

  • Linting: RuboCop on staged Ruby files, ESLint/Prettier on JS files
  • Tests: Run affected spec files based on changed lib files
  • Trailing newlines: Ensure all files end with newlines

Pre-push Hooks (Comprehensive)

Before pushing to remote:

  • Full linting: Entire codebase
  • Full test suite: All tests

Configuration Example

# lefthook.yml
pre-commit:
  parallel: true
  commands:
    rubocop:
      glob: '**/*.rb'
      run: bin/lefthook/rubocop-lint {staged_files}
    
    prettier:
      glob: '**/*.{js,jsx,ts,tsx,json,md,yml}'
      run: bin/lefthook/prettier-format {staged_files}
    
    trailing-newlines:
      run: bin/lefthook/check-trailing-newlines {staged_files}

pre-push:
  commands:
    full-lint:
      run: bundle exec rubocop && yarn lint
    
    full-test:
      run: bundle exec rspec && yarn test

Helper Scripts

Modular scripts in bin/lefthook/:

  • rubocop-lint - Lint staged Ruby files with helpful error messages
  • prettier-format - Format JS/TS/JSON/YAML files
  • check-trailing-newlines - Ensure proper file endings
  • Shell-safe: Handles filenames with spaces and special characters

Benefits

  1. Developer Experience

    • ⚡ Fast pre-commit checks (<5 seconds vs minutes)
    • 🎯 Only check changed files on commit
    • 🛡️ Full validation before push
    • 📊 Clear, helpful error messages
  2. Code Quality

    • Catch simple issues before CI
    • Reduce CI failures and iteration time
    • Consistent standards across team
  3. Maintenance

    • Automatic installation via bin/setup
    • Easy to extend with new hooks
    • Well-documented in README

Implementation Plan

  1. Add lefthook gem to Gemfile
  2. Create lefthook.yml configuration
  3. Create helper scripts in bin/lefthook/
  4. Update bin/setup to run lefthook install
  5. Update README with Git hooks documentation
  6. Test with files containing spaces and special characters

Example PR

See complete implementation: shakacode/package_json#32

Questions for Discussion

  1. Should we migrate existing hooks or run Lefthook alongside them initially?
  2. What checks should run on pre-commit vs pre-push?
  3. Should we include database-dependent tests in pre-push or leave to CI?
  4. Any project-specific hooks needed (e.g., database migrations check)?

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions