angler

Crates.ioangler
lib.rsangler
version0.1.0
created_at2025-05-17 13:06:43.627747+00
updated_at2025-05-17 13:06:43.627747+00
descriptionEfficient git hooks management
homepage
repository
max_upload_size
id1677852
size206,687
Romain Girard (romaingd)

documentation

README

(WIP) Angler: Manage git hooks and run them fast

Plan

  • Order steps below
  • Simple pre-commit hook
  • Shell script hook
  • xargs on staged files
  • Multiple hooks (sequential)
  • Rust-based hook (system version)
  • From repository
  • YAML config
  • install and run commands
  • Store
  • uninstall
  • Python-based hook (system version)
  • Python-based hook (dedicated venv)
  • Multithread xargs
  • Display
  • More hook types
  • Multithread hooks (non-modifying)
  • Lock config
  • More languages

Key features

  • Fast
    • Rust binary, no intermediate VM
    • Concurrency across and within hooks
    • Pre-computed exact commands to run
  • Simple
    • Human-readable expansion of each hook
    • Local / global install
    • No need for a repo-side manifest
    • Display only failing hooks
    • Monorepo support (?) - Check pre-commit issues
    • Sourceable multi-part config (?) - Check pre-commit issues on the matter
    • CLI add/remove/stats + autocompletion (?)

Parallel execution

First round: full parallelism

Snapshot Stage

  • Take a snapshot of all files to be modified before any hooks run
  • This serves as the "base state" that can be restored if needed

Isolated Execution Environment

  • Each hook operates on a temporary copy of the files
  • Modifications are made to these copies, not the original files
  • This prevents partial modifications from being visible to other hooks

Change Recording

  • Track all modifications made by each hook
  • Store these as "proposed changes" rather than applying them directly

Validation Phase

  • After a hook completes, validate that its changes are compatible with changes from other hooks
  • Detect potential conflicts (same line modified differently by multiple hooks)

Second round: Sequential Fallback

When conflicts are detected in parallel execution, rather than simply failing or discarding all changes, fall back to sequential. This preserves the automatic fixing behavior users expect.

Smart Ordering

  • Learn from conflict patterns to optimize future runs
  • Store information about which hooks conflict with each other
  • Automatically adjust execution strategy on subsequent runs

Similar tools

Husky

package.json    # Modified on running `husky init` to auto-install `husky`
.husky/
    .gitignore      # Initialized with `*`
    pre-commit      # Human-writable shell script, initialized with `npm test`
    _/              # Configured git.config.core.hooksPath
        h               # Runs `.husky/<script>` if it exists
        pre-commit      # Only runs `./husky/_/h`, auto-created
        pre-push        # Only runs `./husky/_/h`, auto-created
  • Configures core hooks path to .husky/_/
  • Writes dummy files for all possible hooks
  • Redirects all git hooks to a single dispatcher h, that runs the appropriate human-written script
  • Purely shell-based
  • Can be disabled using the HUSKY environment variable

Overcommit

TODO

Pre-commit

# project-level
pre-commit-config.yaml
.git/hooks/
    pre-commit      # Templated, runs `<python> -m pre-commit hook-impl <config> type=pre-commit`
    pre-push        # Templated, runs `<python> -m pre-commit hook-impl <config> type=pre-push`
# global
~/.cache/pre-commit/
    db.db                       # Store, sqlite DB, tables `repos` [repo, ref, path] and `configs`
    repo-<cloned_repo_id>/      # Cached across configs, referenced in the Store
        <repo_content>              # Cloned from source
        .pre-commit-hooks.yaml      # Manifest describing how to run the hook, part of the source
        <venv>                      # Contains hook dependencies, created during install
  • Structure
    • Git hook-level templated block that invokes a dispatcher
    • Project-level YAML config
    • Global-level cached repo hooks + venv
    • Global-level config -> repos -> path store for cleanup
    • Repo-level manifest (for hook-defining repos)
  • Support
    • Many languages
    • Hooks can require additional dependencies
    • Extensible
    • Hook-defining repos must expose a manifest
    • Local hooks possible
  • Install
    • Global cache is populated
    • Adds templated redirects to a shared dispatcher
    • Auto-install possible with template-dir
  • Run
    • Dispatcher <python> -m pre-commit hook-impl <config> type=<hook-type> runs
      • Python process
      • Loads config, finds hooks
      • Installs missing hooks
      • Builds hook commands
      • Runs hooks within subprocesses (Python xargs)
    • Concurrency
      • xargs runs in multithreading
      • Serial execution can be explicitly required
    • Directly invokable with pre-commit run
    • Targeted skips possible with SKIP= environment variable
Commit count: 0

cargo fmt