Skip to main content

A fast, cross-platform multi-language linter and formatter

Project description

linthis

Crates.io PyPI License: MIT

A fast, cross-platform multi-language linter and formatter written in Rust.

Features

  • 🚀 Single Command: Run both linting and formatting simultaneously
  • 🌍 Multi-Language Support: Rust, Python, TypeScript, JavaScript, Go, Java, C++, Swift, Kotlin, Lua, and more
  • 🎯 Auto-Detection: Automatically detect programming languages used in your project
  • ⚙️ Flexible Configuration: Support for project config, global config, and CLI parameters
  • 📦 Plugin System: Share and reuse configurations via Git repositories
  • 🎨 Format Presets: Support for popular code styles like Google, Airbnb, Standard
  • Parallel Processing: Leverage multi-core CPU for faster file processing

Installation

Method 1: Install via PyPI (Recommended for Python users)

# Using pip
pip install linthis

# Using uv (recommended)
# pip install uv
uv pip install linthis

Method 2: Install via Cargo (Recommended for Rust users)

cargo install linthis

Method 3: Build from Source

git clone https://github.com/zhlinh/linthis.git
cd linthis
cargo build --release

Quick Start

Initialize Configuration (Optional)

# Create project configuration file
linthis init

# Create global configuration file
linthis init -g

# Create global git hook template (for all new repos)
linthis init -g --hook-type git

# Initialize with pre-commit hooks (project-level)
linthis init --hook-type prek
linthis init --hook-type pre-commit
linthis init --hook-type git

# Force overwrite existing files
linthis init --force
linthis init --hook-type prek -f

Basic Usage

# Check and format current directory (default behavior)
linthis

# Check and format specific directories
linthis -i src/
linthis --include src/ --include lib/

# Check only, no formatting
linthis -c
linthis --check-only

# Format only, no checking
linthis -f
linthis --format-only

# Check Git staged files (suitable for pre-commit hook)
linthis -s
linthis --staged

Specify Languages

# Check specific language
linthis -l python
linthis --lang rust

# Check multiple languages
linthis -l python,rust,cpp
linthis --lang "python,javascript,go"

Exclude Files

# Exclude specific patterns
linthis -e "*.test.js" -e "dist/**"
linthis --exclude "target/**" --exclude "node_modules/**"

Plugin System

linthis supports Git-based configuration plugins for easy sharing of code standards across projects and teams.

Add Plugin

# Add plugin to project config (.linthis.toml)
linthis plugin add <alias> <git-url>

# Example: Add a custom plugin
linthis plugin add myplugin https://github.com/zhlinh/linthis-plugin.git

# Add to global config (~/.linthis/config.toml)
linthis plugin add -g <alias> <git-url>
linthis plugin add --global <alias> <git-url>

Use Plugin

# Use plugin configuration for linting and formatting
linthis -p myplugin
linthis --plugin myplugin

# Combine with other options
linthis -p myplugin -l python -i src/
linthis --plugin myplugin --check-only
linthis --plugin myplugin --staged

Remove Plugin

# Remove plugin from project config
linthis plugin remove <alias>
linthis plugin remove myplugin

# Remove plugin from global config
linthis plugin remove -g <alias>
linthis plugin remove --global myplugin

# Supports flexible parameter ordering
linthis plugin remove --global myplugin

View and Manage Plugins

# View project config plugins
linthis plugin list

# View global config plugins
linthis plugin list -g
linthis plugin list --global

# Update plugin cache
linthis --plugin-update

# Initialize new plugin
linthis plugin init my-config

# Validate plugin structure
linthis plugin validate /path/to/plugin

# Clean plugin cache
linthis plugin clean          # Interactive cleanup
linthis plugin clean --all    # Clean all caches

Configuration Files

Project Configuration

Create .linthis.toml in your project root:

# Specify languages to check (omit for auto-detection)
languages = ["rust", "python", "javascript"]

# Exclude files and directories
excludes = [
    "target/**",
    "node_modules/**",
    "*.generated.rs",
    "dist/**"
]

# Maximum cyclomatic complexity
max_complexity = 20

# Format preset
preset = "google"  # Options: google, airbnb, standard

# Configure plugins
[plugins]
sources = [
    { name = "official" },
    { name = "myplugin", url = "https://github.com/zhlinh/linthis-plugin.git", ref = "main" }
]

# Language-specific configuration
# [rust]
# max_complexity = 15

# [python]
# excludes = ["*_test.py"]

Global Configuration

Global configuration file is located at ~/.linthis/config.toml, with the same format as project config.

Configuration Priority

Configuration merge priority (from high to low):

  1. CLI Parameters: --option value
  2. Project Config: .linthis.toml
  3. Global Config: ~/.linthis/config.toml
  4. Plugin Config: Plugins in sources array (later ones override earlier ones)
  5. Built-in Defaults

Configuration Management

linthis provides a config subcommand for convenient command-line configuration management without manual TOML editing.

Array Field Operations

Supported array fields: includes, excludes, languages

Add Values (add)

# Add to project config
linthis config add includes "src/**"
linthis config add excludes "*.log"
linthis config add languages "rust"

# Add to global config (-g or --global)
linthis config add -g includes "lib/**"
linthis config add --global excludes "node_modules/**"

# Add multiple values (automatically deduped)
linthis config add includes "src/**"
linthis config add includes "lib/**"

Remove Values (remove)

# Remove from project config
linthis config remove excludes "*.log"
linthis config remove languages "python"

# Remove from global config
linthis config remove -g includes "lib/**"
linthis config remove --global excludes "target/**"

Clear Field (clear)

# Clear project config field
linthis config clear languages
linthis config clear includes

# Clear global config field
linthis config clear -g excludes
linthis config clear --global languages

Scalar Field Operations

Supported scalar fields: max_complexity, preset, verbose

Set Value (set)

# Set complexity limit
linthis config set max_complexity 15
linthis config set max_complexity 30 -g

# Set format preset (google, standard, airbnb)
linthis config set preset google
linthis config set preset airbnb --global

# Set verbose output
linthis config set verbose true
linthis config set verbose false -g

Unset Value (unset)

# Remove field from project config
linthis config unset max_complexity
linthis config unset preset

# Remove field from global config
linthis config unset -g verbose
linthis config unset --global max_complexity

Query Operations

Get Single Field Value (get)

# View project config field
linthis config get includes
linthis config get max_complexity
linthis config get preset

# View global config field
linthis config get -g excludes
linthis config get --global languages

List All Configuration (list)

# List project config
linthis config list

# List global config
linthis config list -g
linthis config list --global

# Verbose mode (show all fields including empty values)
linthis config list -v
linthis config list --verbose
linthis config list --global --verbose

Configuration Management Examples

# Initialize project config
linthis config add includes "src/**"
linthis config add includes "lib/**"
linthis config add excludes "target/**"
linthis config add excludes "*.log"
linthis config add languages "rust"
linthis config add languages "python"
linthis config set max_complexity 20
linthis config set preset google

# View config
linthis config list

# Adjust config
linthis config set max_complexity 15
linthis config remove excludes "*.log"
linthis config add excludes "*.tmp"

# Set global defaults
linthis config set -g max_complexity 20
linthis config add -g excludes "node_modules/**"
linthis config add -g excludes ".git/**"

Initialize Configuration File

Use the init subcommand to explicitly create configuration files:

# Create project config (.linthis.toml)
linthis init

# Create global config (~/.linthis/config.toml)
linthis init -g
linthis init --global

# Backward compatible: can also use --init flag
linthis --init

Auto-Create Configuration Files

When using the config command, configuration files are automatically created if they don't exist:

  • Project Config: Creates .linthis.toml in current directory
  • Global Config: Creates config.toml in ~/.linthis/ directory

All modifications preserve TOML file format and comments.

Command Line Options

Main Command Options

Short Long Description Example
-i --include Specify files or directories to check -i src -i lib
-e --exclude Exclude patterns (can be used multiple times) -e "*.test.js"
-p --plugin Use plugin (alias or Git URL) -p myplugin
-c --check-only Check only, no formatting -c
-f --format-only Format only, no checking -f
-s --staged Check only Git staged files -s
-l --lang Specify languages (comma-separated) -l python,rust
-o --output Output format: human, json, github-actions -o json
-v --verbose Verbose output -v
-q --quiet Quiet mode (errors only) -q
--config Specify config file path --config custom.toml
--init Initialize .linthis.toml config file --init
--preset Format preset --preset google
--plugin-update Force update plugin cache --plugin-update
--no-default-excludes Disable default exclude rules --no-default-excludes
--no-gitignore Disable .gitignore rules --no-gitignore

Plugin Management Subcommands

Command Short Long Description
plugin add <alias> <url> -g --global Add to global config
--ref Specify Git reference
plugin remove <alias> -g --global Remove from global config
plugin list -g --global Show global config plugins
-v --verbose Show detailed info
plugin clean --all Clean all caches
plugin init <name> Initialize new plugin
plugin validate <path> Validate plugin structure

Configuration Management Subcommands

Command Short Long Description
config add <field> <value> -g --global Add value to array field
config remove <field> <value> -g --global Remove value from array field
config clear <field> -g --global Clear array field
config set <field> <value> -g --global Set scalar field value
config unset <field> -g --global Remove scalar field
config get <field> -g --global Get field value
config list -g --global List all configuration
-v --verbose Show detailed info (including empty values)

Supported array fields: includes, excludes, languages Supported scalar fields: max_complexity, preset, verbose

Init Subcommand

Command Short Long Description
init -g --global Create global config file
--hook Initialize pre-commit hooks
-i --interactive Interactive mode for hooks setup
-f --force Force overwrite existing files

Created configuration files:

  • Without -g: Creates .linthis.toml (current directory)
  • With -g: Creates ~/.linthis/config.toml (global config)

Hook options:

  • prek: Rust-based pre-commit tool (faster)
  • pre-commit: Python-based standard tool
  • git: Traditional git hook

Supported Languages

Language Linter Formatter
Rust clippy rustfmt
Python pylint, flake8, ruff black, ruff
TypeScript eslint prettier
JavaScript eslint prettier
Go golangci-lint gofmt
Java checkstyle google-java-format
C++ cpplint, cppcheck clang-format
Swift swiftlint swift-format
Kotlin detekt ktlint
Lua luacheck stylua
Dart dart analyze dart format

Usage Scenarios

Pre-commit Hook

Method 1: Global Hook Template (One-time Setup)

Set up a global Git hook template that applies to all new repositories:

# Create global hook template
linthis init -g --hook-type git

# All new repos will automatically include the hook
git init new-project
cd new-project
# .git/hooks/pre-commit is already set up!

For existing repositories:

cd existing-project
git init  # Re-apply template

Features:

  • 🎯 Smart Detection: Only runs if project has linthis config
  • 🔗 Hook Chaining: Supports .git/hooks/pre-commit.local for project-specific hooks
  • 🚫 Zero Interference: Projects without linthis config are not affected
  • One-time Setup: Works for all your new repositories

Pros:

  • One-time setup for all your projects
  • No need to configure hooks per project
  • Perfect for personal development
  • Won't interfere with other projects or hook tools

Cons:

  • Not shared with team members
  • Requires manual setup on each machine

See Global Hooks Guide for details.

Method 2: Using prek (Recommended for Teams)

prek is a high-performance Git hooks manager written in Rust, fully compatible with pre-commit config format but much faster.

Install prek:

# Using cargo
cargo install prek

# Or using pip
pip install prek

Create .pre-commit-config.yaml in your project:

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: linthis
        name: linthis
        entry: linthis --staged --check-only
        language: system
        pass_filenames: false

Install hook:

prek install

Method 3: Traditional Git Hook (Project-level)

Add to .git/hooks/pre-commit:

#!/bin/sh
linthis --staged --check-only

Or use linthis to create it automatically:

linthis init --hook-type git

Method 4: Using pre-commit Framework

Using the pre-commit framework:

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: linthis
        name: linthis
        entry: linthis --staged --check-only
        language: system
        pass_filenames: false

CI/CD Integration

GitHub Actions

name: Lint

on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install linthis
        run: pip install linthis
      - name: Run linthis
        run: linthis --check-only --output github-actions

GitLab CI

lint:
  image: rust:latest
  script:
    - cargo install linthis
    - linthis --check-only

Creating Custom Plugins

1. Initialize Plugin

linthis plugin init my-company-standards
cd my-company-standards

2. Edit Plugin Configuration

Edit linthis-plugin.toml:

[plugin]
name = "my-company-standards"
version = "1.0.0"
description = "My company's coding standards"

["language.python"]
config_count = 2

["language.python".tools.flake8]
priority = "P0"
files = [".flake8"]

["language.python".tools.black]
priority = "P1"
files = ["pyproject.toml"]

3. Add Configuration Files

mkdir -p python
# Add your config files to corresponding language directories
cp /path/to/.flake8 python/
cp /path/to/pyproject.toml python/

4. Publish to Git

git init
git add .
git commit -m "feat: Initial commit of my company coding standards"
git remote add origin git@github.com:mycompany/linthis-standards.git
git push -u origin main

5. Use Your Plugin

linthis plugin add company https://github.com/mycompany/linthis-standards.git
linthis --plugin company

FAQ

Q: How to specify multiple paths?

linthis -i src -i lib -i tests

Q: How to check only specific file types?

linthis -l python  # Only check Python files

Q: Where is the plugin cache?

  • macOS: ~/Library/Caches/linthis/plugins
  • Linux: ~/.cache/linthis/plugins
  • Windows: %LOCALAPPDATA%\linthis\plugins

Q: How to update plugins?

linthis --plugin-update

Q: What is the plugin Git reference (ref) used for?

The ref can specify:

  • Branch name: --ref main
  • Tag: --ref v1.0.0
  • Commit hash: --ref abc1234

This allows you to lock plugin versions or use development versions.

Documentation

Development

Build

cargo build

Test

cargo test

Release

cargo build --release

Contributing

Issues and Pull Requests are welcome!

License

MIT License - See LICENSE file for details

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

linthis-0.0.7.tar.gz (157.8 kB view details)

Uploaded Source

Built Distributions

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

linthis-0.0.7-py3-none-win_amd64.whl (2.1 MB view details)

Uploaded Python 3Windows x86-64

linthis-0.0.7-py3-none-manylinux_2_28_x86_64.whl (2.1 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

linthis-0.0.7-py3-none-manylinux_2_28_aarch64.whl (1.9 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

linthis-0.0.7-py3-none-macosx_11_0_arm64.whl (1.9 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

linthis-0.0.7-py3-none-macosx_10_12_x86_64.whl (2.0 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file linthis-0.0.7.tar.gz.

File metadata

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

File hashes

Hashes for linthis-0.0.7.tar.gz
Algorithm Hash digest
SHA256 005e971bfe28ec1a33e0abb3977973e8f7ddb66e1d34addd4ef4a088747d6570
MD5 20af41d57e49c2e58fc10fde64a12a47
BLAKE2b-256 d095c4491ef50bf9dc14bf4416dda3b5025771263e46cf2594a8d952fe4d88e6

See more details on using hashes here.

Provenance

The following attestation bundles were made for linthis-0.0.7.tar.gz:

Publisher: release.yml on zhlinh/linthis

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

File details

Details for the file linthis-0.0.7-py3-none-win_amd64.whl.

File metadata

  • Download URL: linthis-0.0.7-py3-none-win_amd64.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for linthis-0.0.7-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 f3f8bd92e6f51dcc7983b4f31e24dd590e3377cf1f102be48ff787fc6078a14b
MD5 2b30d8e8e8ba1c56964cd4e35cfeab20
BLAKE2b-256 5380d9215b149923739d46767c23e495ff8e11d575ab9b73808c764c4df48b8b

See more details on using hashes here.

Provenance

The following attestation bundles were made for linthis-0.0.7-py3-none-win_amd64.whl:

Publisher: release.yml on zhlinh/linthis

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

File details

Details for the file linthis-0.0.7-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for linthis-0.0.7-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e52be67247705bcafa7e9cb054403392eb7f918d3fefc885dce998714e89ad25
MD5 afe362f7a7f0ee870ed21ccebe144103
BLAKE2b-256 180e3374407e39bc1fafcb539a35880800e0e268161ba869a1dc978dbbf865cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for linthis-0.0.7-py3-none-manylinux_2_28_x86_64.whl:

Publisher: release.yml on zhlinh/linthis

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

File details

Details for the file linthis-0.0.7-py3-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for linthis-0.0.7-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 246239318615091259ede01e945fbed3d160620effe560ec6f3ca39c0f9a79cb
MD5 7e31976f0d20c026005fe215d0d25362
BLAKE2b-256 21d3677e41f0c719e2f2ee58630153b8f5c4e3098dcb45ac19c8977115b2b71b

See more details on using hashes here.

Provenance

The following attestation bundles were made for linthis-0.0.7-py3-none-manylinux_2_28_aarch64.whl:

Publisher: release.yml on zhlinh/linthis

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

File details

Details for the file linthis-0.0.7-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for linthis-0.0.7-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 97c199f00d6e1a74ab1f7969bf43846a3a832dc73bca94386133d730d635950c
MD5 8eaa3e0d58ff8284aef581b66cca916a
BLAKE2b-256 bc85b7414565b019581aff06e8cf85675b48344235884671af805d2647197b5b

See more details on using hashes here.

Provenance

The following attestation bundles were made for linthis-0.0.7-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on zhlinh/linthis

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

File details

Details for the file linthis-0.0.7-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for linthis-0.0.7-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 56a4ee5057125528e2d167feef9d00e61d61123ddd997115f453a8f25964f9fe
MD5 c56f1a8b8f7859278ec1cbddc268c043
BLAKE2b-256 c5f30a636799a5eef8bf8f843d11873f477508fc17dbd664b60def4892f5aad5

See more details on using hashes here.

Provenance

The following attestation bundles were made for linthis-0.0.7-py3-none-macosx_10_12_x86_64.whl:

Publisher: release.yml on zhlinh/linthis

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