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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions