Skip to main content

Snapshot linter errors and track only new issues — perfect for incremental linter adoption on large codebases

Project description

snaplint

Snapshot your linter errors and track only new issues in CI — perfect for adopting linters incrementally on large codebases without breaking existing workflows.

snaplint captures a baseline of current linter findings and lets you diff future runs against it. Only new errors cause CI failures, while existing issues are tracked separately.

Quick Start

Install via pip or uv:

pip install snaplint
# or
uv tool install snaplint

Basic Workflow

  1. Create a baseline snapshot of your current linter output:
flake8 src/ | snaplint take-snapshot
# Creates .snaplint/snapshot.flake8.json.gz
  1. Check for new issues in CI or locally:
flake8 src/ | snaplint diff
# Exit code 0: no new issues ✓
# Exit code 1: new issues found ✗

The diff command shows you:

  • New errors (red) — will fail CI
  • Removed errors (green) — improvements!
  • File-level changes — error count and ordering changes per file

Auto-Detection

snaplint automatically detects your linter (flake8, mypy, pylint, or generic format) and creates appropriately named snapshots in .snaplint/:

# Each linter gets its own snapshot
flake8 . | snaplint take-snapshot    # → .snaplint/snapshot.flake8.json.gz
mypy . | snaplint take-snapshot      # → .snaplint/snapshot.mypy.json.gz
pylint src/ | snaplint take-snapshot # → .snaplint/snapshot.pylint.json.gz

Custom Snapshot Paths

Specify a custom path if needed:

flake8 . | snaplint take-snapshot snapshots/baseline.json
flake8 . | snaplint diff snapshots/baseline.json

Exit Codes

  • 0 — No new issues (safe to merge)
  • 1 — New issues detected (CI should fail)
  • 2 — Usage error (missing snapshot, no input, etc.)
  • 3 — Unexpected internal error

How It Works

snaplint creates SHA1 fingerprints of each error by hashing the error type + source code line. This makes error tracking resilient to:

  • Line number changes (refactoring, adding imports)
  • File reorganization
  • Whitespace changes in unrelated code

When comparing snapshots:

  • Per-file tracking shows which files improved or regressed
  • Order changes are detected when errors move within a file
  • Count changes show if the total number of issues changed
  • File-level errors (line 0) are fully supported

Snapshots are stored as gzip-compressed JSON (.json.gz) with version metadata for forward compatibility.

CI Integration

GitHub Actions

- name: Check for new linter issues
  run: |
    flake8 . | snaplint diff || {
      echo "❌ New linting issues detected"
      exit 1
    }

Pre-commit Hook

Add to .pre-commit-config.yaml:

- repo: local
  hooks:
    - id: snaplint
      name: Check linting snapshot
      entry: bash -c 'flake8 . | snaplint diff'
      language: system
      pass_filenames: false

Supported Linters

snaplint automatically recognizes output from:

  • flake8 and compatible tools (flake9, etc.)
  • mypy
  • pylint
  • Generic format — any tool outputting path:line:col: message

Unrecognized lines are skipped with a warning to stderr.

Working with Older Python Versions

If your project needs to support older Python versions (e.g., Python 3.8) but snaplint requires Python 3.10+, you can run the linter with your target Python version and snaplint with a newer interpreter:

# Run linter with Python 3.8
python3.8 -m flake8 src/ > /tmp/lint_output.txt

# Process with snaplint using Python 3.10+
python3.10 -m snaplint take-snapshot < /tmp/lint_output.txt
python3.10 -m snaplint diff < /tmp/lint_output.txt

Or use separate virtual environments:

# Create venv for linting with old Python
python3.8 -m venv .venv-lint
.venv-lint/bin/pip install flake8

# Create venv for snaplint with new Python
python3.10 -m venv .venv-snaplint
.venv-snaplint/bin/pip install snaplint

# Use them together
.venv-lint/bin/flake8 src/ | .venv-snaplint/bin/snaplint diff

This approach lets you maintain compatibility with older Python versions in your codebase while using modern tooling for CI/CD workflows.

Development

Setup

# Clone the repository
git clone https://github.com/GENWAY-AI/snaplint.git
cd snaplint

# Install with uv (recommended)
uv sync

# Or with pip
pip install -e ".[dev]"

Running Tests

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=snaplint --cov-report=html

# Run specific test file
uv run pytest tests/test_e2e.py -v

Local Installation

Install as a global command for testing:

uv tool install -e .
snaplint --version

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

snaplint-0.6.0.tar.gz (54.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

snaplint-0.6.0-py3-none-any.whl (13.7 kB view details)

Uploaded Python 3

File details

Details for the file snaplint-0.6.0.tar.gz.

File metadata

  • Download URL: snaplint-0.6.0.tar.gz
  • Upload date:
  • Size: 54.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for snaplint-0.6.0.tar.gz
Algorithm Hash digest
SHA256 7e333797ecd01f05d2e3730df08b19f5ff70300c647df69aa640fd3c616a6472
MD5 0448a110d83319845917ddb912c423d2
BLAKE2b-256 ce3c41ffe6174ef9ab0b04a96073abfb575238cf328a354eff2a3edfb7d3b874

See more details on using hashes here.

Provenance

The following attestation bundles were made for snaplint-0.6.0.tar.gz:

Publisher: ci.yml on GENWAY-AI/snaplint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file snaplint-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: snaplint-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 13.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for snaplint-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4b4320856803f21d61ea72f43ef38be19493643965dfd6f57500de7d5324a616
MD5 c86738bc986b73ff80ac005e1e75e730
BLAKE2b-256 d22f2dceea131da3a62593485b2c487341876138789f3f5b5716bf097a45594e

See more details on using hashes here.

Provenance

The following attestation bundles were made for snaplint-0.6.0-py3-none-any.whl:

Publisher: ci.yml on GENWAY-AI/snaplint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page