Keyboard shortcuts

Press โ† or โ†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Pre-commit Setup and Optimization

"Quality is not an act, it's a habit." โ€” Aristotle

This document describes Speakr's pre-commit hook configuration, optimization strategies, and future improvement opportunities.

๐Ÿ“‹ Table of Contents

Overview

Pre-commit hooks ensure code quality by running automated checks before each commit. This prevents broken code from entering the repository and maintains consistent coding standards across the team.

Why Pre-commit?

  • Early Detection: Catch issues before they reach CI/CD
  • Consistent Quality: Enforce formatting and linting standards
  • Fast Feedback: Immediate results during development
  • Team Alignment: Same standards for all contributors

Current Setup

Our optimized pre-commit configuration targets affected packages only, reducing execution time by ~70% for typical changes.

Configuration Files

Hook Categories

1. Package-Specific Rust Hooks

speakr-core (triggered by ^speakr-core/.*\.rs$):

  • cargo-fmt-core: Code formatting check
  • cargo-clippy-core: Linting with all warnings as errors
  • cargo-test-core: Unit and integration tests

speakr-tauri (triggered by ^speakr-tauri/.*\.rs$):

  • cargo-fmt-tauri: Code formatting check
  • cargo-clippy-tauri: Linting with all warnings as errors
  • cargo-test-tauri: Unit and integration tests

speakr-ui (triggered by ^speakr-ui/.*\.rs$):

  • cargo-fmt-ui: Code formatting check
  • cargo-clippy-ui: Linting with all warnings as errors
  • cargo-test-ui: Unit and integration tests

2. Workspace-Level Hooks

Workspace Changes (triggered by ^(Cargo\.(toml|lock)|\.cargo/.*)$):

  • cargo-fmt-workspace: Format all packages
  • cargo-clippy-workspace: Lint entire workspace

3. Smart Integration Hooks

Dependency Awareness:

  • cargo-test-integration: When speakr-core changes, also test speakr-tauri (dependency relationship)

4. General Quality Hooks

  • Trailing whitespace: Remove unnecessary whitespace
  • YAML/JSON/TOML validation: Syntax checking
  • Large file detection: Prevent accidental commits of large files
  • Merge conflict detection: Catch unresolved conflicts
  • Markdown linting: Documentation quality

Optimizations

๐ŸŽฏ Selective Package Testing

Problem: Previous setup ran all checks on all packages for any Rust file change.

Solution: File pattern matching to target only affected packages.

# Before: Always runs on ANY .rs file
files: \.rs$
entry: cargo test --all

# After: Only runs on speakr-core files
files: ^speakr-core/.*\.rs$
entry: cargo test --package speakr-core

๐Ÿง  Dependency-Aware Testing

Problem: Changes to speakr-core could break speakr-tauri without running its tests.

Solution: Smart integration testing when dependencies change.

# Integration test: core changes affect tauri
- id: cargo-test-integration
  name: Cargo Test (integration - core affects tauri)
  entry: cargo test --package speakr-tauri
  files: ^speakr-core/.*\.rs$  # Triggered by core changes

โšก Performance Optimizations

  1. Parallel Execution: Each package's hooks can run in parallel
  2. Targeted Scoping: Only affected code gets checked
  3. Smart Caching: Cargo's incremental compilation benefits
  4. Early Exit: Hooks fail fast on first error

Usage Guide

Installation

# Install pre-commit (if not already installed)
pip install pre-commit

# Install hooks in repository
pre-commit install

# Optional: Install for push events too
pre-commit install -t pre-push

Daily Workflow

Automatic (Recommended):

git add .
git commit -m "feat: add new feature"
# Hooks run automatically, commit proceeds if all pass

Manual Testing:

# Run all hooks on all files
pre-commit run --all-files

# Run specific hook
pre-commit run cargo-fmt-core

# Run on specific files
pre-commit run --files speakr-core/src/lib.rs

Advanced Selective Testing

For maximum control, use our custom script:

# Test only packages affected by changes since last commit
./scripts/selective-tests.sh

# Compare against specific commit/branch
./scripts/selective-tests.sh main
./scripts/selective-tests.sh abc123def

# Get help
./scripts/selective-tests.sh --help

Bypassing Hooks (Emergency Only)

# Skip all hooks (use sparingly!)
git commit -m "hotfix: urgent fix" --no-verify

# Skip specific hook
SKIP=cargo-test-core git commit -m "fix: skip tests temporarily"

Performance Metrics

Before Optimization

  • Total packages checked: 3/3 (100%)
  • Average execution time: ~45 seconds
  • Parallel efficiency: Low (redundant work)

After Optimization

  • Typical single-package change: 1/3 packages (33%)
  • Average execution time: ~15 seconds (70% improvement)
  • Parallel efficiency: High (targeted work)
  • Smart dependencies: Core changes โ†’ Core + Tauri tests

Real-world Example

Scenario: Modify speakr-ui/src/app.rs

Before: โœ— Tests all 3 packages (~45s) After: โœ“ Tests only speakr-ui package (~12s) Speedup: 3.75x faster ๐Ÿš€

Future Improvements

๐Ÿš€ Performance Enhancements

1. Incremental Testing with Coverage

Goal: Only run tests affected by specific code changes, not entire packages.

Implementation:

# Future: Ultra-granular testing
cargo test --package speakr-core -- --test-affected-by src/audio.rs

Tools to explore:

  • cargo-difftests: Selective re-testing framework
  • LLVM coverage analysis for affected test discovery
  • determinator: Facebook's affected package detection

2. Caching and Memoization

Goal: Skip checks if code hasn't changed since last successful run.

Implementation:

# Cache test results based on content hash
- id: cargo-test-cached
  entry: cache-wrapper cargo test --package speakr-core
  cache_key: "hash:speakr-core/**/*.rs"

Benefits:

  • Near-instant results for unchanged code
  • Perfect for repeated CI runs on same commit

3. Parallel Package Testing

Goal: Run different package tests truly in parallel.

Current: Sequential package testing Future: Matrix-style parallel execution

# Run in parallel using job control
cargo test --package speakr-core &
cargo test --package speakr-tauri &
cargo test --package speakr-ui &
wait  # Wait for all to complete

๐Ÿ” Enhanced Feedback

1. Rich Diff Display

Goal: Show exactly what code caused failures.

Implementation:

# Future: Rich failure reporting
cargo clippy --message-format json | jq -r '.spans[] | .file_name + ":" + .line_start'

Features:

  • Syntax-highlighted diffs
  • Click-to-fix suggestions
  • Context-aware error messages

2. Performance Profiling

Goal: Track and optimize hook execution time.

Metrics to collect:

  • Per-hook execution time
  • Cache hit/miss ratios
  • Package-level timing breakdown
  • Historical performance trends

3. Smart Notifications

Goal: Contextual feedback based on change type.

Examples:

# API changes detected
โš ๏ธ  Public API modified in speakr-core - consider semver impact

# Performance impact detected
๐ŸŒ Tests are 20% slower - check for performance regressions

# Security sensitive changes
๐Ÿ”’ Cryptographic code modified - extra security review recommended

๐Ÿงช Test Quality Improvements

1. Mutation Testing Integration

Goal: Ensure tests actually catch bugs.

Implementation:

# Run mutation tests on changed code
cargo mutants --package speakr-core --in-diff HEAD~1..HEAD

2. Dependency Impact Analysis

Goal: Understand full impact of changes across the dependency graph.

Visualization:

speakr-core change impact:
โ”œโ”€โ”€ speakr-core (direct) โœ“
โ”œโ”€โ”€ speakr-tauri (depends on core) โœ“
โ””โ”€โ”€ speakr-ui (independent) โญ๏ธ skipped

3. Flaky Test Detection

Goal: Identify and fix unreliable tests.

Implementation:

  • Run tests multiple times in CI
  • Track test success/failure rates
  • Auto-quarantine flaky tests
  • Generate flakiness reports

๐Ÿ”ง Developer Experience

1. IDE Integration

Goal: Show pre-commit status in development environment.

Features:

  • Real-time hook status in VS Code/Cursor
  • Inline error highlighting
  • One-click fix suggestions

2. Hook Customization

Goal: Allow per-developer customization.

Implementation:

# .pre-commit-config.local.yaml (git-ignored)
hooks:
  - id: cargo-clippy-core
    args: ["--", "-A", "clippy::pedantic"]  # Less strict for local dev

3. Quick Fix Tools

Goal: Automated fixing of common issues.

Examples:

# Auto-fix formatting
pre-commit run cargo-fmt-core --hook-stage manual

# Auto-fix common clippy warnings
cargo clippy --fix --allow-dirty

# Auto-update dependencies
cargo update && pre-commit run cargo-test-all

Troubleshooting

Common Issues

Hook Fails with "Package not found"

Cause: Package name mismatch in hook configuration. Solution: Verify package names match Cargo.toml files:

cargo metadata --format-version 1 | jq '.packages[].name'

Tests Pass Locally but Fail in CI

Cause: Different dependency versions or environment. Solution: Use Cargo.lock and consistent Rust versions:

# CI configuration
rust-toolchain: "1.88.0"  # Pin exact version

Hooks Run on Wrong Files

Cause: Incorrect regex patterns in files: configuration. Solution: Test patterns with realistic file paths:

# Test regex pattern
echo "speakr-core/src/lib.rs" | grep -E "^speakr-core/.*\.rs$"

Performance Issues

Slow Hook Execution

  1. Check package scoping: Ensure hooks target specific packages
  2. Review test suite: Look for slow integration tests
  3. Enable caching: Use --cache-dir for cargo operations

Memory Issues

  1. Limit parallel jobs: Set CARGO_BUILD_JOBS=2
  2. Increase memory limits: Configure system swap
  3. Use release mode for tests: cargo test --release (if appropriate)

Getting Help

  1. Check configuration: Validate with pre-commit validate-config
  2. Debug mode: Run with pre-commit run --verbose
  3. Clean cache: Use pre-commit clean to reset
  4. Manual testing: Test individual hooks in isolation

References