Skip to content

athos-ribeiro/cargo-cars

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cargo-cars - Canonical Rust Best Practices Linter

cargo-cars is a cargo extension that enforces code compliance with the Canonical Rust best practices.

It implements all 11 disciplines as modular checkers with auto-fix support, inline suppression via comments, and UK spelling validation via hunspell.

Installation

Requires Rust >= 1.85.0, libclang, and libhunspell-dev at build time.

For UK spelling checks at runtime (optional), you will also need hunspell-en-gb. If not installed, spelling checks fall back to a built-in US/UK word map.

installing dependencies:

sudo apt install libclang-dev libhunspell-dev hunspell-en-gb

Then, install cargo-cars:

cargo install --path .

Usage

cargo cars                                  # analyze current project
cargo cars src/main.rs src/lib.rs           # specific files
cargo cars src/                             # directory

cargo cars --disciplines cosmetic,naming    # select disciplines
cargo cars --exclude-disciplines comment    # exclude disciplines
cargo cars --format json                    # json | sarif | console (default)
cargo cars --fix                            # apply auto-fixes
cargo cars --fixable-only                   # show only fixable violations
cargo cars --config .cars.toml              # custom config file
cargo cars --quiet                          # errors only

Disciplines

# ID Description
1 cosmetic Hex literal case, semantic blank line spacing
2 naming Generic/lifetime naming, UK spelling, pattern match variables
3 import No wildcard imports, import grouping order
4 pattern_matching No ref patterns, no tuple indexing, no param patterns
5 code Empty vec macro, explicit drop, from_iter, Self usage
6 error_panic Unwrap usage, error message format
7 function Single-use generics, unused parameters
8 ordering Derive order, field visibility order, definition order
9 unsafe_code SAFETY comments, unsafe fn docs, block size
10 structural mod.rs structure, Error/Result placement
11 comment Doc comment length, article usage

Auto-fixable rules

These rules provide automatic fixes via --fix:

  • cosmetic::hex_case - lowercase hex literals
  • code::empty_vec - replace vec![] with Vec::new()
  • code::self_usage - replace concrete type with Self in impl blocks
  • error_panic::unwrap_usage - replace .unwrap() with .expect("TODO: add reason")
  • ordering::derive_order - reorder derive attributes (Copy first, alphabetical)

Inline suppression

Suppress violations on the next line with a comment:

// cars:disable cosmetic::hex_case
let x = 0xABCD;  // no violation reported

// cars:disable cosmetic
let y = 0xEF01;  // suppresses all cosmetic rules

// cars:disable
let z = 0xFF;    // suppresses all rules

Configuration

cargo-cars looks for a .cars.toml file starting from the current working directory and searching upward through parent directories until one is found. You can override this with --config <path>.

CLI arguments always take precedence over the config file.

Flat format

The simplest configuration uses top-level keys:

disciplines = ["cosmetic", "naming", "import", "pattern_matching",
    "code", "error_panic", "function", "ordering",
    "unsafe_code", "structural", "comment"]
exclude_disciplines = []

Structured format

The structured format uses a [cars] section and optional [disciplines.<name>] tables for per-discipline key/value options:

[cars]
disciplines = ["cosmetic", "naming", "code", "error_panic"]
exclude_disciplines = ["comment"]

[disciplines.cosmetic]
hex_case = "lower"  # "lower" (default), "upper", or "any"

[disciplines.error_panic]
allow_unwrap_in_tests = "true"  # "true" (default) or "false"

Configuration reference

Key Type Default Description
disciplines array of strings All 11 disciplines Which disciplines to enable
exclude_disciplines array of strings [] Disciplines to skip (applied after disciplines)
[disciplines.<name>] table of key/value strings {} Per-discipline options passed to the checker

Per-discipline options

Discipline Key Values Default Description
cosmetic hex_case lower, upper, any lower Required case for hex literals
error_panic allow_unwrap_in_tests true, false true Whether .unwrap() is allowed in test code

Available discipline IDs

cosmetic, naming, import, pattern_matching, code, error_panic, function, ordering, unsafe_code, structural, comment

Output formats

Console (default):

error[cosmetic::hex_case]: use lowercase for hex literals
  --> src/main.rs:42:13
  = help: use 0xabcd instead

JSON: structured output with violations, locations, and summary.

SARIF: SARIF 2.1.0 for IDE integration.

Exit codes

Code Meaning
0 No violations
1 Violations found
2 Tool error (parse failure, config error)

Testing

cargo test                    # all tests
cargo test --lib              # unit tests only
cargo test --test '*'         # integration tests only
cargo test cosmetic           # single discipline
cargo test -- --nocapture     # with stdout

Each discipline has inline unit tests. Integration tests cover CLI flags, output formats, auto-fix, and configuration loading. Fixtures under tests/fixtures/pass/ and tests/fixtures/fail/ provide per-discipline sample code.

Extending

To add a discipline:

  1. Create src/disciplines/your_discipline.rs implementing Discipline
  2. Register it in src/disciplines/mod.rs
  3. Add pass/fail fixtures in tests/fixtures/
  4. Add inline unit tests with #[cfg(test)]

The Discipline trait:

pub trait Discipline {
    fn id(&self) -> &'static str;
    fn check(&self, file: &ParsedFile) -> Vec<Violation>;
}

License

MIT OR Apache-2.0

About

Canonical Rust Best Practices Linter - https://github.com/canonical/rust-best-practices

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages