Skip to main content

convention_lint/
lib.rs

1//! # convention-lint
2//!
3//! A file-naming convention linter for Rust projects, configurable via `Cargo.toml` metadata.
4//!
5//! It enforces naming conventions (like `snake_case` or `CamelCase`) for any files in your
6//! project, not just Rust source files. It uses parallel directory traversal (same as ripgrep)
7//! and respects `.gitignore`.
8//!
9//! ## Configuration
10//!
11//! Add `[[package.metadata.convention-lint.checks]]` or `[[workspace.metadata.convention-lint.checks]]`
12//! entries to your `Cargo.toml`.
13//!
14//! ### Example
15//!
16//! ```toml
17//! [[workspace.metadata.convention-lint.checks]]
18//! dirs      = ["src/idl", "proto"]
19//! include   = ["*.idl", "*.proto"]
20//! exclude   = ["**/legacy_*.proto"]
21//! format    = "snake_case"
22//! recursive = true
23//! ```
24//!
25//! ### Configuration Fields
26//!
27//! | Field | Required | Default | Description |
28//! |-------|----------|---------|-------------|
29//! | `dirs` | **Yes** | — | Directories to scan. Supports globs like `src/*/tests`. **Cannot be empty.** |
30//! | `include` | No | `["*"]` | Glob patterns for files to check (e.g. `["*.rs"]`). |
31//! | `exclude` | No | `[]` | Glob patterns for files to skip (takes priority over `include`). |
32//! | `format` | **Yes** | — | Convention to enforce: `snake_case`, `CamelCase`, `camelCase`, `SCREAMING_SNAKE_CASE`, `kebab-case`. |
33//! | `recursive` | No | `true` | If `false`, the linter won't enter subdirectories. |
34//!
35//! ### Pattern Matching Rules
36//!
37//! Patterns in `include` and `exclude` are matched against the **full relative path** //! from the project root.
38//!
39//! | Pattern | Match Type | Description |
40//! |---------|------------|-------------|
41//! | `*.rs` | Extension | Any `.rs` file in any directory. |
42//! | `generated.rs` | Exact File | Only `generated.rs` in the project root. |
43//! | `**/generated.rs` | Floating File | Any file named `generated.rs` anywhere in the project. |
44//! | `**/tests/**` | Directory | **Entire directory** and all its contents. |
45//!
46//! **Note:** To exclude an entire directory, always end the pattern with `/**`.
47//!
48//! ## Supported Conventions
49//!
50//! | Identifier | Example |
51//! |------------|---------|
52//! | `snake_case` | `my_service` |
53//! | `CamelCase` | `MyService` (Alias: `PascalCase`) |
54//! | `camelCase` | `myService` |
55//! | `SCREAMING_SNAKE_CASE` | `MY_SERVICE` |
56//! | `kebab-case` | `my-service` |
57//!
58//! ## Usage
59//!
60//! Install the tool:
61//! ```sh
62//! cargo install convention-lint
63//! ```
64//!
65//! Run it in your project root:
66//! ```sh
67//! cargo convention-lint
68//! ```
69//!
70//! ## Library Usage
71//!
72//! ```no_run
73//! use convention_lint::{config::load_config, lint::run};
74//! use std::path::Path;
75//!
76//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
77//! let manifest_path = Path::new("Cargo.toml");
78//! let project_root = Path::new(".");
79//!
80//! let cfg = load_config(manifest_path)?;
81//! let violations = run(&cfg, project_root);
82//!
83//! for v in &violations {
84//!     eprintln!("{v}");
85//! }
86//!
87//! if !violations.is_empty() {
88//!     std::process::exit(1);
89//! }
90//! # Ok(())
91//! # }
92//! ```
93
94pub mod config;
95pub mod core;
96pub mod error;
97pub mod lint;
98
99pub use crate::core::Convention;
100pub use crate::error::Error;
101pub use crate::lint::Violation;