Skip to content

Getting started

Install the CLI, declare your policy, and run your first read-only check.

Install

Install the published multilingual release or build the CLI from source.

With uv, install the native wheel:

uv tool install lint-my-headers==0.7.0
lmh --version

PyPI tooling requires Python 3.11+. Wheels contain native lmh and lint-my-headers executables. Building a source distribution also requires Rust and a C compiler. Version 0.7.0 supports all nine languages and every configuration container.

Use the pinned Rust 1.93 toolchain and a native linker:

git clone https://github.com/frgfm/lint-my-headers.git
cd lint-my-headers
cargo install --path . --locked
lmh --version

Ensure Cargo's binary directory is on your PATH. Python is optional when using the native CLI directly.

Declare the policy

Use your project's established ownership and license. These example values are placeholders; the tool never infers them. Set paths to directories that exist and keep the corresponding LICENSE at the project root.

Add this section to pyproject.toml:

[tool.lint-my-headers]
owner = "Example Organization"
starting-year = 2024
license = "Apache-2.0"
paths = ["src", "tests"]
ignore-files = ["version.py"]
ignore-folders = ["src/generated"]

Create .lmh.toml in your project root:

owner = "Example Organization"
starting-year = 2024
license = "Apache-2.0"
languages = ["python", "javascript", "typescript", "rust", "go", "swift", "bash", "c", "cpp"]
paths = ["src", "tests"]
ignore-files = ["version.py"]
ignore-folders = ["src/generated"]

Select only the languages used by your project. The default is Python. Both configuration examples work with the published release and source checkout.

Check existing headers

Run from the project directory:

lmh check
lmh check src/package tests/test_api.py
lmh check --help

The first command uses configured paths; positional paths replace that list. Checks are read-only. A valid Python header in 2026 looks like this:

# Copyright (C) 2024-2026, Example Organization.

# This program is licensed under the Apache License 2.0.
# See LICENSE or go to <https://www.apache.org/licenses/LICENSE-2.0> for full license details.

Bash uses the same # marker. Other supported languages use //, with the same text and blank lines. See header layouts for language-specific details. Published 0.7.0 leaves missing headers for manual review. The additional layouts support common copyright lines, ordinary blocks, and SPDX pairs in the unreleased source checkout; they are not available in published 0.7.0.

Refresh a stale year

For a recognized header ending in 2025, lmh check reports LMH004. When the diagnostic is marked fixable and source changes are authorized:

lmh fix
lmh check
git diff

In 2026, a creation year of 2024 with an end year of 2025 becomes 2024-2026. The tool retains the creation year and every other byte. It leaves ineligible findings for manual review.

Insert a missing header (unreleased)

The source checkout can insert a header when the policy supplies its owner and notice and you declare the file's first copyright year. The existing starting-year is a validation floor; it is not used as the file's year.

lmh check --creation-year 2024 src/new_file.py
lmh fix --creation-year 2024 src/new_file.py
lmh check src/new_file.py
git diff

The new header uses 2024 through the current year. Declare the actual year for the selected files; creation-year = 2024 in project configuration has the same effect. Without this declaration, fix keeps LMH001 unresolved. Select files with the same actual creation year and run separately for different years.

Insertion keeps the original bytes, encoding, line endings, preambles, and mode. Existing legal declarations, ambiguous layouts, and notices that cannot be encoded in the file remain unfixable. Python files that start with parentheses, joined or escaped strings, or byte, formatted, or template strings also require review. Existing headers still use the limited end-year repair. This feature is not in published 0.7.0.

Insertion refuses any file that contains copyright, ©, SPDX, license, licence, or all rights reserved, regardless of case or position. A leading comment such as (c) 2024 Other Owner also needs review. Examples and variable names can trigger these guards; LMH001 explains the refusal. Review those files and add the header manually.

Exit code Meaning
0 No unresolved findings; any eligible repairs completed.
1 Unresolved findings remain.
2 Invocation, configuration, or I/O failure.

For CI, use Integrations. For programmatic output, see Diagnostics & agents.