diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b3219bd..0997e264 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased](https://github.com/Kampfkarren/selene/compare/0.21.0...HEAD) +### Added +- Added exclude option to selene.toml for excluding files from lints + ## [0.21.1](https://github.com/Kampfkarren/selene/releases/tag/0.21.0) - 2022-09-19 ### Fixed - Fixed not being able to use projects without selene.toml. diff --git a/Cargo.lock b/Cargo.lock index 72e0568e..b6fb2acb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -88,6 +88,15 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "memchr", +] + [[package]] name = "bumpalo" version = "3.10.0" @@ -283,6 +292,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.0.1" @@ -357,6 +372,19 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "globset" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + [[package]] name = "hashbrown" version = "0.9.1" @@ -828,6 +856,7 @@ dependencies = [ "dirs", "full_moon", "glob", + "globset", "lazy_static", "num_cpus", "profiling", diff --git a/docs/src/usage/configuration.md b/docs/src/usage/configuration.md index f4c11ca8..20085a01 100644 --- a/docs/src/usage/configuration.md +++ b/docs/src/usage/configuration.md @@ -62,3 +62,10 @@ For example, if we had `game.toml` and `engine.toml` standard libraries, we coul ```toml std = "game+engine" ``` + +### Excluding files from being linted +It is possible to exclude files from being linted using the exclude option: + +```toml +exclude = ["external/*", "*.spec.lua"] +``` diff --git a/selene-lib/src/lib.rs b/selene-lib/src/lib.rs index b10dc9ce..478afeb9 100644 --- a/selene-lib/src/lib.rs +++ b/selene-lib/src/lib.rs @@ -65,6 +65,7 @@ pub struct CheckerConfig { pub config: HashMap, pub rules: HashMap, pub std: Option, + pub exclude: Vec, // Not locked behind Roblox feature so that selene.toml for Roblox will // run even without it. @@ -83,6 +84,8 @@ impl Default for CheckerConfig { config: HashMap::new(), rules: HashMap::new(), std: None, + exclude: Vec::new(), + roblox_std_source: RobloxStdSource::default(), } } diff --git a/selene/Cargo.toml b/selene/Cargo.toml index a22b407f..a090da90 100644 --- a/selene/Cargo.toml +++ b/selene/Cargo.toml @@ -20,6 +20,7 @@ color-eyre = "0.6.1" dirs = "4.0.0" full_moon = "0.15.1" glob = "0.3" +globset = "0.4.9" lazy_static = "1.4" num_cpus = "1.10" profiling = { version = "1.0.6" } diff --git a/selene/src/main.rs b/selene/src/main.rs index fa118a4d..9baf645d 100644 --- a/selene/src/main.rs +++ b/selene/src/main.rs @@ -469,6 +469,25 @@ fn start(mut matches: opts::Options) { } }; + let mut builder = globset::GlobSetBuilder::new(); + for pattern in &config.exclude { + builder.add(match globset::Glob::new(pattern) { + Ok(glob) => glob, + Err(error) => { + error!("Invalid glob pattern: {error}"); + return; + } + }); + } + + let exclude_set = match builder.build() { + Ok(globset) => globset, + Err(error) => { + error!("{error}"); + return; + } + }; + let checker = Arc::new(match Checker::new(config, standard_library) { Ok(checker) => checker, Err(error) => { @@ -510,6 +529,10 @@ fn start(mut matches: opts::Options) { for entry in glob { match entry { Ok(path) => { + if exclude_set.is_match(&path) { + continue; + } + let checker = Arc::clone(&checker); pool.execute(move || read_file(&checker, &path));