diff --git a/Cargo.lock b/Cargo.lock index 4daeaf4844425..31a7afd76912a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -466,6 +466,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "codegen" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff61280aed771c3070e7dcc9e050c66f1eb1e3b96431ba66f9f74641d02fc41d" +dependencies = [ + "indexmap", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -2054,6 +2063,7 @@ dependencies = [ "chrono", "clap", "clearscreen", + "codegen", "colored", "common-path", "dirs 4.0.0", diff --git a/Cargo.toml b/Cargo.toml index a9a395db6cc90..3ea815d0a1943 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ getrandom = { version = "0.2.7", features = ["js"] } [dev-dependencies] assert_cmd = { version = "2.0.4" } +codegen = { version = "0.2.0" } insta = { version = "1.19.1", features = ["yaml"] } test-case = { version = "2.2.2" } diff --git a/examples/generate_check_code_prefix.rs b/examples/generate_check_code_prefix.rs new file mode 100644 index 0000000000000..547d493d06c0e --- /dev/null +++ b/examples/generate_check_code_prefix.rs @@ -0,0 +1,105 @@ +//! Generate the CheckCodePrefix enum. + +use std::collections::{BTreeMap, BTreeSet}; + +use codegen::{Scope, Type, Variant}; +use itertools::Itertools; +use strum::IntoEnumIterator; + +use ruff::checks::CheckCode; + +fn main() { + // Build up a map from prefix to matching CheckCodes. + let mut prefix_to_codes: BTreeMap> = Default::default(); + for check_code in CheckCode::iter() { + let as_ref = check_code.as_ref().to_string(); + for i in 1..=as_ref.len() { + let prefix = as_ref[..i].to_string(); + let entry = prefix_to_codes + .entry(prefix) + .or_insert_with(|| Default::default()); + entry.insert(check_code.clone()); + } + } + + let mut scope = Scope::new(); + + // Create the `CheckCodePrefix` definition. + let mut gen = scope + .new_enum("CheckCodePrefix") + .vis("pub") + .derive("EnumString") + .derive("Debug") + .derive("PartialEq") + .derive("Eq") + .derive("Clone") + .derive("Serialize") + .derive("Deserialize"); + for (prefix, _) in &prefix_to_codes { + gen = gen.push_variant(Variant::new(prefix.to_string())); + } + + // Create the `PrefixSpecificity` definition. + scope + .new_enum("PrefixSpecificity") + .vis("pub") + .derive("PartialEq") + .derive("Eq") + .derive("PartialOrd") + .derive("Ord") + .push_variant(Variant::new("Category")) + .push_variant(Variant::new("Hundreds")) + .push_variant(Variant::new("Tens")) + .push_variant(Variant::new("Explicit")); + + // Create the `match` statement, to map from definition to relevant codes. + let mut gen = scope + .new_impl("CheckCodePrefix") + .new_fn("codes") + .arg_ref_self() + .ret(Type::new("Vec")) + .vis("pub") + .line("match self {"); + for (prefix, codes) in &prefix_to_codes { + gen = gen.line(format!( + "CheckCodePrefix::{prefix} => vec![{}],", + codes + .iter() + .map(|code| format!("CheckCode::{}", code.as_ref())) + .join(", ") + )); + } + gen.line("}"); + + // Create the `match` statement, to map from definition to specificity. + let mut gen = scope + .new_impl("CheckCodePrefix") + .new_fn("specificity") + .arg_ref_self() + .ret(Type::new("PrefixSpecificity")) + .vis("pub") + .line("match self {"); + for (prefix, _) in &prefix_to_codes { + let specificity = match prefix.len() { + 4 => "Explicit", + 3 => "Tens", + 2 => "Hundreds", + 1 => "Category", + _ => panic!("Invalid prefix: {}", prefix), + }; + gen = gen.line(format!( + "CheckCodePrefix::{prefix} => PrefixSpecificity::{},", + specificity + )); + } + gen.line("}"); + + println!("//! File automatically generated by examples/generate_check_code_prefix.rs."); + println!(); + println!("use serde::{{Deserialize, Serialize}};"); + println!("use strum_macros::EnumString;"); + println!(); + println!("use crate::checks::CheckCode;"); + println!(); + println!("{}", scope.to_string()); +} diff --git a/src/checks_gen.rs b/src/checks_gen.rs new file mode 100644 index 0000000000000..92f855a5ce682 --- /dev/null +++ b/src/checks_gen.rs @@ -0,0 +1,1031 @@ +//! File automatically generated by examples/generate_check_code_prefix.rs. + +use serde::{Deserialize, Serialize}; +use strum_macros::EnumString; + +use crate::checks::CheckCode; + +#[derive(EnumString, Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +pub enum CheckCodePrefix { + A, + A0, + A00, + A001, + A002, + A003, + B, + B0, + B00, + B002, + B007, + B01, + B011, + B014, + B017, + B02, + B025, + C, + C4, + C40, + C400, + C401, + C402, + C403, + C404, + C405, + C406, + C408, + C409, + C41, + C410, + C411, + C413, + C414, + C415, + C416, + C417, + D, + D1, + D10, + D100, + D101, + D102, + D103, + D104, + D105, + D106, + D107, + D2, + D20, + D200, + D201, + D202, + D203, + D204, + D205, + D206, + D207, + D208, + D209, + D21, + D210, + D211, + D212, + D213, + D214, + D215, + D3, + D30, + D300, + D4, + D40, + D400, + D402, + D403, + D404, + D405, + D406, + D407, + D408, + D409, + D41, + D410, + D411, + D412, + D413, + D414, + D415, + D416, + D417, + D418, + D419, + E, + E4, + E40, + E402, + E5, + E50, + E501, + E7, + E71, + E711, + E712, + E713, + E714, + E72, + E721, + E722, + E73, + E731, + E74, + E741, + E742, + E743, + E9, + E90, + E902, + E99, + E999, + F, + F4, + F40, + F401, + F402, + F403, + F404, + F405, + F406, + F407, + F5, + F54, + F541, + F6, + F60, + F601, + F602, + F62, + F621, + F622, + F63, + F631, + F632, + F633, + F634, + F7, + F70, + F701, + F702, + F704, + F706, + F707, + F72, + F722, + F8, + F82, + F821, + F822, + F823, + F83, + F831, + F84, + F841, + F9, + F90, + F901, + M, + M0, + M00, + M001, + N, + N8, + N80, + N801, + N802, + N803, + N804, + N805, + N807, + N81, + N811, + N812, + N813, + N814, + N817, + T, + T2, + T20, + T201, + T203, + U, + U0, + U00, + U001, + U002, + U003, + U004, + U005, + U006, + U007, + U008, + W, + W2, + W29, + W292, + W6, + W60, + W605, +} + +#[derive(PartialEq, Eq, PartialOrd, Ord)] +pub enum PrefixSpecificity { + Category, + Hundreds, + Tens, + Explicit, +} + +impl CheckCodePrefix { + pub fn codes(&self) -> Vec { + match self { + CheckCodePrefix::A => vec![CheckCode::A001, CheckCode::A002, CheckCode::A003], + CheckCodePrefix::A0 => vec![CheckCode::A001, CheckCode::A002, CheckCode::A003], + CheckCodePrefix::A00 => vec![CheckCode::A001, CheckCode::A002, CheckCode::A003], + CheckCodePrefix::A001 => vec![CheckCode::A001], + CheckCodePrefix::A002 => vec![CheckCode::A002], + CheckCodePrefix::A003 => vec![CheckCode::A003], + CheckCodePrefix::B => vec![ + CheckCode::B002, + CheckCode::B007, + CheckCode::B011, + CheckCode::B014, + CheckCode::B017, + CheckCode::B025, + ], + CheckCodePrefix::B0 => vec![ + CheckCode::B002, + CheckCode::B007, + CheckCode::B011, + CheckCode::B014, + CheckCode::B017, + CheckCode::B025, + ], + CheckCodePrefix::B00 => vec![CheckCode::B002, CheckCode::B007], + CheckCodePrefix::B002 => vec![CheckCode::B002], + CheckCodePrefix::B007 => vec![CheckCode::B007], + CheckCodePrefix::B01 => vec![CheckCode::B011, CheckCode::B014, CheckCode::B017], + CheckCodePrefix::B011 => vec![CheckCode::B011], + CheckCodePrefix::B014 => vec![CheckCode::B014], + CheckCodePrefix::B017 => vec![CheckCode::B017], + CheckCodePrefix::B02 => vec![CheckCode::B025], + CheckCodePrefix::B025 => vec![CheckCode::B025], + CheckCodePrefix::C => vec![ + CheckCode::C400, + CheckCode::C401, + CheckCode::C402, + CheckCode::C403, + CheckCode::C404, + CheckCode::C405, + CheckCode::C406, + CheckCode::C408, + CheckCode::C409, + CheckCode::C410, + CheckCode::C411, + CheckCode::C413, + CheckCode::C414, + CheckCode::C415, + CheckCode::C416, + CheckCode::C417, + ], + CheckCodePrefix::C4 => vec![ + CheckCode::C400, + CheckCode::C401, + CheckCode::C402, + CheckCode::C403, + CheckCode::C404, + CheckCode::C405, + CheckCode::C406, + CheckCode::C408, + CheckCode::C409, + CheckCode::C410, + CheckCode::C411, + CheckCode::C413, + CheckCode::C414, + CheckCode::C415, + CheckCode::C416, + CheckCode::C417, + ], + CheckCodePrefix::C40 => vec![ + CheckCode::C400, + CheckCode::C401, + CheckCode::C402, + CheckCode::C403, + CheckCode::C404, + CheckCode::C405, + CheckCode::C406, + CheckCode::C408, + CheckCode::C409, + ], + CheckCodePrefix::C400 => vec![CheckCode::C400], + CheckCodePrefix::C401 => vec![CheckCode::C401], + CheckCodePrefix::C402 => vec![CheckCode::C402], + CheckCodePrefix::C403 => vec![CheckCode::C403], + CheckCodePrefix::C404 => vec![CheckCode::C404], + CheckCodePrefix::C405 => vec![CheckCode::C405], + CheckCodePrefix::C406 => vec![CheckCode::C406], + CheckCodePrefix::C408 => vec![CheckCode::C408], + CheckCodePrefix::C409 => vec![CheckCode::C409], + CheckCodePrefix::C41 => vec![ + CheckCode::C410, + CheckCode::C411, + CheckCode::C413, + CheckCode::C414, + CheckCode::C415, + CheckCode::C416, + CheckCode::C417, + ], + CheckCodePrefix::C410 => vec![CheckCode::C410], + CheckCodePrefix::C411 => vec![CheckCode::C411], + CheckCodePrefix::C413 => vec![CheckCode::C413], + CheckCodePrefix::C414 => vec![CheckCode::C414], + CheckCodePrefix::C415 => vec![CheckCode::C415], + CheckCodePrefix::C416 => vec![CheckCode::C416], + CheckCodePrefix::C417 => vec![CheckCode::C417], + CheckCodePrefix::D => vec![ + CheckCode::D100, + CheckCode::D101, + CheckCode::D102, + CheckCode::D103, + CheckCode::D104, + CheckCode::D105, + CheckCode::D106, + CheckCode::D107, + CheckCode::D200, + CheckCode::D201, + CheckCode::D202, + CheckCode::D203, + CheckCode::D204, + CheckCode::D205, + CheckCode::D206, + CheckCode::D207, + CheckCode::D208, + CheckCode::D209, + CheckCode::D210, + CheckCode::D211, + CheckCode::D212, + CheckCode::D213, + CheckCode::D214, + CheckCode::D215, + CheckCode::D300, + CheckCode::D400, + CheckCode::D402, + CheckCode::D403, + CheckCode::D404, + CheckCode::D405, + CheckCode::D406, + CheckCode::D407, + CheckCode::D408, + CheckCode::D409, + CheckCode::D410, + CheckCode::D411, + CheckCode::D412, + CheckCode::D413, + CheckCode::D414, + CheckCode::D415, + CheckCode::D416, + CheckCode::D417, + CheckCode::D418, + CheckCode::D419, + ], + CheckCodePrefix::D1 => vec![ + CheckCode::D100, + CheckCode::D101, + CheckCode::D102, + CheckCode::D103, + CheckCode::D104, + CheckCode::D105, + CheckCode::D106, + CheckCode::D107, + ], + CheckCodePrefix::D10 => vec![ + CheckCode::D100, + CheckCode::D101, + CheckCode::D102, + CheckCode::D103, + CheckCode::D104, + CheckCode::D105, + CheckCode::D106, + CheckCode::D107, + ], + CheckCodePrefix::D100 => vec![CheckCode::D100], + CheckCodePrefix::D101 => vec![CheckCode::D101], + CheckCodePrefix::D102 => vec![CheckCode::D102], + CheckCodePrefix::D103 => vec![CheckCode::D103], + CheckCodePrefix::D104 => vec![CheckCode::D104], + CheckCodePrefix::D105 => vec![CheckCode::D105], + CheckCodePrefix::D106 => vec![CheckCode::D106], + CheckCodePrefix::D107 => vec![CheckCode::D107], + CheckCodePrefix::D2 => vec![ + CheckCode::D200, + CheckCode::D201, + CheckCode::D202, + CheckCode::D203, + CheckCode::D204, + CheckCode::D205, + CheckCode::D206, + CheckCode::D207, + CheckCode::D208, + CheckCode::D209, + CheckCode::D210, + CheckCode::D211, + CheckCode::D212, + CheckCode::D213, + CheckCode::D214, + CheckCode::D215, + ], + CheckCodePrefix::D20 => vec![ + CheckCode::D200, + CheckCode::D201, + CheckCode::D202, + CheckCode::D203, + CheckCode::D204, + CheckCode::D205, + CheckCode::D206, + CheckCode::D207, + CheckCode::D208, + CheckCode::D209, + ], + CheckCodePrefix::D200 => vec![CheckCode::D200], + CheckCodePrefix::D201 => vec![CheckCode::D201], + CheckCodePrefix::D202 => vec![CheckCode::D202], + CheckCodePrefix::D203 => vec![CheckCode::D203], + CheckCodePrefix::D204 => vec![CheckCode::D204], + CheckCodePrefix::D205 => vec![CheckCode::D205], + CheckCodePrefix::D206 => vec![CheckCode::D206], + CheckCodePrefix::D207 => vec![CheckCode::D207], + CheckCodePrefix::D208 => vec![CheckCode::D208], + CheckCodePrefix::D209 => vec![CheckCode::D209], + CheckCodePrefix::D21 => vec![ + CheckCode::D210, + CheckCode::D211, + CheckCode::D212, + CheckCode::D213, + CheckCode::D214, + CheckCode::D215, + ], + CheckCodePrefix::D210 => vec![CheckCode::D210], + CheckCodePrefix::D211 => vec![CheckCode::D211], + CheckCodePrefix::D212 => vec![CheckCode::D212], + CheckCodePrefix::D213 => vec![CheckCode::D213], + CheckCodePrefix::D214 => vec![CheckCode::D214], + CheckCodePrefix::D215 => vec![CheckCode::D215], + CheckCodePrefix::D3 => vec![CheckCode::D300], + CheckCodePrefix::D30 => vec![CheckCode::D300], + CheckCodePrefix::D300 => vec![CheckCode::D300], + CheckCodePrefix::D4 => vec![ + CheckCode::D400, + CheckCode::D402, + CheckCode::D403, + CheckCode::D404, + CheckCode::D405, + CheckCode::D406, + CheckCode::D407, + CheckCode::D408, + CheckCode::D409, + CheckCode::D410, + CheckCode::D411, + CheckCode::D412, + CheckCode::D413, + CheckCode::D414, + CheckCode::D415, + CheckCode::D416, + CheckCode::D417, + CheckCode::D418, + CheckCode::D419, + ], + CheckCodePrefix::D40 => vec![ + CheckCode::D400, + CheckCode::D402, + CheckCode::D403, + CheckCode::D404, + CheckCode::D405, + CheckCode::D406, + CheckCode::D407, + CheckCode::D408, + CheckCode::D409, + ], + CheckCodePrefix::D400 => vec![CheckCode::D400], + CheckCodePrefix::D402 => vec![CheckCode::D402], + CheckCodePrefix::D403 => vec![CheckCode::D403], + CheckCodePrefix::D404 => vec![CheckCode::D404], + CheckCodePrefix::D405 => vec![CheckCode::D405], + CheckCodePrefix::D406 => vec![CheckCode::D406], + CheckCodePrefix::D407 => vec![CheckCode::D407], + CheckCodePrefix::D408 => vec![CheckCode::D408], + CheckCodePrefix::D409 => vec![CheckCode::D409], + CheckCodePrefix::D41 => vec![ + CheckCode::D410, + CheckCode::D411, + CheckCode::D412, + CheckCode::D413, + CheckCode::D414, + CheckCode::D415, + CheckCode::D416, + CheckCode::D417, + CheckCode::D418, + CheckCode::D419, + ], + CheckCodePrefix::D410 => vec![CheckCode::D410], + CheckCodePrefix::D411 => vec![CheckCode::D411], + CheckCodePrefix::D412 => vec![CheckCode::D412], + CheckCodePrefix::D413 => vec![CheckCode::D413], + CheckCodePrefix::D414 => vec![CheckCode::D414], + CheckCodePrefix::D415 => vec![CheckCode::D415], + CheckCodePrefix::D416 => vec![CheckCode::D416], + CheckCodePrefix::D417 => vec![CheckCode::D417], + CheckCodePrefix::D418 => vec![CheckCode::D418], + CheckCodePrefix::D419 => vec![CheckCode::D419], + CheckCodePrefix::E => vec![ + CheckCode::E402, + CheckCode::E501, + CheckCode::E711, + CheckCode::E712, + CheckCode::E713, + CheckCode::E714, + CheckCode::E721, + CheckCode::E722, + CheckCode::E731, + CheckCode::E741, + CheckCode::E742, + CheckCode::E743, + CheckCode::E902, + CheckCode::E999, + ], + CheckCodePrefix::E4 => vec![CheckCode::E402], + CheckCodePrefix::E40 => vec![CheckCode::E402], + CheckCodePrefix::E402 => vec![CheckCode::E402], + CheckCodePrefix::E5 => vec![CheckCode::E501], + CheckCodePrefix::E50 => vec![CheckCode::E501], + CheckCodePrefix::E501 => vec![CheckCode::E501], + CheckCodePrefix::E7 => vec![ + CheckCode::E711, + CheckCode::E712, + CheckCode::E713, + CheckCode::E714, + CheckCode::E721, + CheckCode::E722, + CheckCode::E731, + CheckCode::E741, + CheckCode::E742, + CheckCode::E743, + ], + CheckCodePrefix::E71 => vec![ + CheckCode::E711, + CheckCode::E712, + CheckCode::E713, + CheckCode::E714, + ], + CheckCodePrefix::E711 => vec![CheckCode::E711], + CheckCodePrefix::E712 => vec![CheckCode::E712], + CheckCodePrefix::E713 => vec![CheckCode::E713], + CheckCodePrefix::E714 => vec![CheckCode::E714], + CheckCodePrefix::E72 => vec![CheckCode::E721, CheckCode::E722], + CheckCodePrefix::E721 => vec![CheckCode::E721], + CheckCodePrefix::E722 => vec![CheckCode::E722], + CheckCodePrefix::E73 => vec![CheckCode::E731], + CheckCodePrefix::E731 => vec![CheckCode::E731], + CheckCodePrefix::E74 => vec![CheckCode::E741, CheckCode::E742, CheckCode::E743], + CheckCodePrefix::E741 => vec![CheckCode::E741], + CheckCodePrefix::E742 => vec![CheckCode::E742], + CheckCodePrefix::E743 => vec![CheckCode::E743], + CheckCodePrefix::E9 => vec![CheckCode::E902, CheckCode::E999], + CheckCodePrefix::E90 => vec![CheckCode::E902], + CheckCodePrefix::E902 => vec![CheckCode::E902], + CheckCodePrefix::E99 => vec![CheckCode::E999], + CheckCodePrefix::E999 => vec![CheckCode::E999], + CheckCodePrefix::F => vec![ + CheckCode::F401, + CheckCode::F402, + CheckCode::F403, + CheckCode::F404, + CheckCode::F405, + CheckCode::F406, + CheckCode::F407, + CheckCode::F541, + CheckCode::F601, + CheckCode::F602, + CheckCode::F621, + CheckCode::F622, + CheckCode::F631, + CheckCode::F632, + CheckCode::F633, + CheckCode::F634, + CheckCode::F701, + CheckCode::F702, + CheckCode::F704, + CheckCode::F706, + CheckCode::F707, + CheckCode::F722, + CheckCode::F821, + CheckCode::F822, + CheckCode::F823, + CheckCode::F831, + CheckCode::F841, + CheckCode::F901, + ], + CheckCodePrefix::F4 => vec![ + CheckCode::F401, + CheckCode::F402, + CheckCode::F403, + CheckCode::F404, + CheckCode::F405, + CheckCode::F406, + CheckCode::F407, + ], + CheckCodePrefix::F40 => vec![ + CheckCode::F401, + CheckCode::F402, + CheckCode::F403, + CheckCode::F404, + CheckCode::F405, + CheckCode::F406, + CheckCode::F407, + ], + CheckCodePrefix::F401 => vec![CheckCode::F401], + CheckCodePrefix::F402 => vec![CheckCode::F402], + CheckCodePrefix::F403 => vec![CheckCode::F403], + CheckCodePrefix::F404 => vec![CheckCode::F404], + CheckCodePrefix::F405 => vec![CheckCode::F405], + CheckCodePrefix::F406 => vec![CheckCode::F406], + CheckCodePrefix::F407 => vec![CheckCode::F407], + CheckCodePrefix::F5 => vec![CheckCode::F541], + CheckCodePrefix::F54 => vec![CheckCode::F541], + CheckCodePrefix::F541 => vec![CheckCode::F541], + CheckCodePrefix::F6 => vec![ + CheckCode::F601, + CheckCode::F602, + CheckCode::F621, + CheckCode::F622, + CheckCode::F631, + CheckCode::F632, + CheckCode::F633, + CheckCode::F634, + ], + CheckCodePrefix::F60 => vec![CheckCode::F601, CheckCode::F602], + CheckCodePrefix::F601 => vec![CheckCode::F601], + CheckCodePrefix::F602 => vec![CheckCode::F602], + CheckCodePrefix::F62 => vec![CheckCode::F621, CheckCode::F622], + CheckCodePrefix::F621 => vec![CheckCode::F621], + CheckCodePrefix::F622 => vec![CheckCode::F622], + CheckCodePrefix::F63 => vec![ + CheckCode::F631, + CheckCode::F632, + CheckCode::F633, + CheckCode::F634, + ], + CheckCodePrefix::F631 => vec![CheckCode::F631], + CheckCodePrefix::F632 => vec![CheckCode::F632], + CheckCodePrefix::F633 => vec![CheckCode::F633], + CheckCodePrefix::F634 => vec![CheckCode::F634], + CheckCodePrefix::F7 => vec![ + CheckCode::F701, + CheckCode::F702, + CheckCode::F704, + CheckCode::F706, + CheckCode::F707, + CheckCode::F722, + ], + CheckCodePrefix::F70 => vec![ + CheckCode::F701, + CheckCode::F702, + CheckCode::F704, + CheckCode::F706, + CheckCode::F707, + ], + CheckCodePrefix::F701 => vec![CheckCode::F701], + CheckCodePrefix::F702 => vec![CheckCode::F702], + CheckCodePrefix::F704 => vec![CheckCode::F704], + CheckCodePrefix::F706 => vec![CheckCode::F706], + CheckCodePrefix::F707 => vec![CheckCode::F707], + CheckCodePrefix::F72 => vec![CheckCode::F722], + CheckCodePrefix::F722 => vec![CheckCode::F722], + CheckCodePrefix::F8 => vec![ + CheckCode::F821, + CheckCode::F822, + CheckCode::F823, + CheckCode::F831, + CheckCode::F841, + ], + CheckCodePrefix::F82 => vec![CheckCode::F821, CheckCode::F822, CheckCode::F823], + CheckCodePrefix::F821 => vec![CheckCode::F821], + CheckCodePrefix::F822 => vec![CheckCode::F822], + CheckCodePrefix::F823 => vec![CheckCode::F823], + CheckCodePrefix::F83 => vec![CheckCode::F831], + CheckCodePrefix::F831 => vec![CheckCode::F831], + CheckCodePrefix::F84 => vec![CheckCode::F841], + CheckCodePrefix::F841 => vec![CheckCode::F841], + CheckCodePrefix::F9 => vec![CheckCode::F901], + CheckCodePrefix::F90 => vec![CheckCode::F901], + CheckCodePrefix::F901 => vec![CheckCode::F901], + CheckCodePrefix::M => vec![CheckCode::M001], + CheckCodePrefix::M0 => vec![CheckCode::M001], + CheckCodePrefix::M00 => vec![CheckCode::M001], + CheckCodePrefix::M001 => vec![CheckCode::M001], + CheckCodePrefix::N => vec![ + CheckCode::N801, + CheckCode::N802, + CheckCode::N803, + CheckCode::N804, + CheckCode::N805, + CheckCode::N807, + CheckCode::N811, + CheckCode::N812, + CheckCode::N813, + CheckCode::N814, + CheckCode::N817, + ], + CheckCodePrefix::N8 => vec![ + CheckCode::N801, + CheckCode::N802, + CheckCode::N803, + CheckCode::N804, + CheckCode::N805, + CheckCode::N807, + CheckCode::N811, + CheckCode::N812, + CheckCode::N813, + CheckCode::N814, + CheckCode::N817, + ], + CheckCodePrefix::N80 => vec![ + CheckCode::N801, + CheckCode::N802, + CheckCode::N803, + CheckCode::N804, + CheckCode::N805, + CheckCode::N807, + ], + CheckCodePrefix::N801 => vec![CheckCode::N801], + CheckCodePrefix::N802 => vec![CheckCode::N802], + CheckCodePrefix::N803 => vec![CheckCode::N803], + CheckCodePrefix::N804 => vec![CheckCode::N804], + CheckCodePrefix::N805 => vec![CheckCode::N805], + CheckCodePrefix::N807 => vec![CheckCode::N807], + CheckCodePrefix::N81 => vec![ + CheckCode::N811, + CheckCode::N812, + CheckCode::N813, + CheckCode::N814, + CheckCode::N817, + ], + CheckCodePrefix::N811 => vec![CheckCode::N811], + CheckCodePrefix::N812 => vec![CheckCode::N812], + CheckCodePrefix::N813 => vec![CheckCode::N813], + CheckCodePrefix::N814 => vec![CheckCode::N814], + CheckCodePrefix::N817 => vec![CheckCode::N817], + CheckCodePrefix::T => vec![CheckCode::T201, CheckCode::T203], + CheckCodePrefix::T2 => vec![CheckCode::T201, CheckCode::T203], + CheckCodePrefix::T20 => vec![CheckCode::T201, CheckCode::T203], + CheckCodePrefix::T201 => vec![CheckCode::T201], + CheckCodePrefix::T203 => vec![CheckCode::T203], + CheckCodePrefix::U => vec![ + CheckCode::U001, + CheckCode::U002, + CheckCode::U003, + CheckCode::U004, + CheckCode::U005, + CheckCode::U006, + CheckCode::U007, + CheckCode::U008, + ], + CheckCodePrefix::U0 => vec![ + CheckCode::U001, + CheckCode::U002, + CheckCode::U003, + CheckCode::U004, + CheckCode::U005, + CheckCode::U006, + CheckCode::U007, + CheckCode::U008, + ], + CheckCodePrefix::U00 => vec![ + CheckCode::U001, + CheckCode::U002, + CheckCode::U003, + CheckCode::U004, + CheckCode::U005, + CheckCode::U006, + CheckCode::U007, + CheckCode::U008, + ], + CheckCodePrefix::U001 => vec![CheckCode::U001], + CheckCodePrefix::U002 => vec![CheckCode::U002], + CheckCodePrefix::U003 => vec![CheckCode::U003], + CheckCodePrefix::U004 => vec![CheckCode::U004], + CheckCodePrefix::U005 => vec![CheckCode::U005], + CheckCodePrefix::U006 => vec![CheckCode::U006], + CheckCodePrefix::U007 => vec![CheckCode::U007], + CheckCodePrefix::U008 => vec![CheckCode::U008], + CheckCodePrefix::W => vec![CheckCode::W292, CheckCode::W605], + CheckCodePrefix::W2 => vec![CheckCode::W292], + CheckCodePrefix::W29 => vec![CheckCode::W292], + CheckCodePrefix::W292 => vec![CheckCode::W292], + CheckCodePrefix::W6 => vec![CheckCode::W605], + CheckCodePrefix::W60 => vec![CheckCode::W605], + CheckCodePrefix::W605 => vec![CheckCode::W605], + } + } +} + +impl CheckCodePrefix { + pub fn specificity(&self) -> PrefixSpecificity { + match self { + CheckCodePrefix::A => PrefixSpecificity::Category, + CheckCodePrefix::A0 => PrefixSpecificity::Hundreds, + CheckCodePrefix::A00 => PrefixSpecificity::Tens, + CheckCodePrefix::A001 => PrefixSpecificity::Explicit, + CheckCodePrefix::A002 => PrefixSpecificity::Explicit, + CheckCodePrefix::A003 => PrefixSpecificity::Explicit, + CheckCodePrefix::B => PrefixSpecificity::Category, + CheckCodePrefix::B0 => PrefixSpecificity::Hundreds, + CheckCodePrefix::B00 => PrefixSpecificity::Tens, + CheckCodePrefix::B002 => PrefixSpecificity::Explicit, + CheckCodePrefix::B007 => PrefixSpecificity::Explicit, + CheckCodePrefix::B01 => PrefixSpecificity::Tens, + CheckCodePrefix::B011 => PrefixSpecificity::Explicit, + CheckCodePrefix::B014 => PrefixSpecificity::Explicit, + CheckCodePrefix::B017 => PrefixSpecificity::Explicit, + CheckCodePrefix::B02 => PrefixSpecificity::Tens, + CheckCodePrefix::B025 => PrefixSpecificity::Explicit, + CheckCodePrefix::C => PrefixSpecificity::Category, + CheckCodePrefix::C4 => PrefixSpecificity::Hundreds, + CheckCodePrefix::C40 => PrefixSpecificity::Tens, + CheckCodePrefix::C400 => PrefixSpecificity::Explicit, + CheckCodePrefix::C401 => PrefixSpecificity::Explicit, + CheckCodePrefix::C402 => PrefixSpecificity::Explicit, + CheckCodePrefix::C403 => PrefixSpecificity::Explicit, + CheckCodePrefix::C404 => PrefixSpecificity::Explicit, + CheckCodePrefix::C405 => PrefixSpecificity::Explicit, + CheckCodePrefix::C406 => PrefixSpecificity::Explicit, + CheckCodePrefix::C408 => PrefixSpecificity::Explicit, + CheckCodePrefix::C409 => PrefixSpecificity::Explicit, + CheckCodePrefix::C41 => PrefixSpecificity::Tens, + CheckCodePrefix::C410 => PrefixSpecificity::Explicit, + CheckCodePrefix::C411 => PrefixSpecificity::Explicit, + CheckCodePrefix::C413 => PrefixSpecificity::Explicit, + CheckCodePrefix::C414 => PrefixSpecificity::Explicit, + CheckCodePrefix::C415 => PrefixSpecificity::Explicit, + CheckCodePrefix::C416 => PrefixSpecificity::Explicit, + CheckCodePrefix::C417 => PrefixSpecificity::Explicit, + CheckCodePrefix::D => PrefixSpecificity::Category, + CheckCodePrefix::D1 => PrefixSpecificity::Hundreds, + CheckCodePrefix::D10 => PrefixSpecificity::Tens, + CheckCodePrefix::D100 => PrefixSpecificity::Explicit, + CheckCodePrefix::D101 => PrefixSpecificity::Explicit, + CheckCodePrefix::D102 => PrefixSpecificity::Explicit, + CheckCodePrefix::D103 => PrefixSpecificity::Explicit, + CheckCodePrefix::D104 => PrefixSpecificity::Explicit, + CheckCodePrefix::D105 => PrefixSpecificity::Explicit, + CheckCodePrefix::D106 => PrefixSpecificity::Explicit, + CheckCodePrefix::D107 => PrefixSpecificity::Explicit, + CheckCodePrefix::D2 => PrefixSpecificity::Hundreds, + CheckCodePrefix::D20 => PrefixSpecificity::Tens, + CheckCodePrefix::D200 => PrefixSpecificity::Explicit, + CheckCodePrefix::D201 => PrefixSpecificity::Explicit, + CheckCodePrefix::D202 => PrefixSpecificity::Explicit, + CheckCodePrefix::D203 => PrefixSpecificity::Explicit, + CheckCodePrefix::D204 => PrefixSpecificity::Explicit, + CheckCodePrefix::D205 => PrefixSpecificity::Explicit, + CheckCodePrefix::D206 => PrefixSpecificity::Explicit, + CheckCodePrefix::D207 => PrefixSpecificity::Explicit, + CheckCodePrefix::D208 => PrefixSpecificity::Explicit, + CheckCodePrefix::D209 => PrefixSpecificity::Explicit, + CheckCodePrefix::D21 => PrefixSpecificity::Tens, + CheckCodePrefix::D210 => PrefixSpecificity::Explicit, + CheckCodePrefix::D211 => PrefixSpecificity::Explicit, + CheckCodePrefix::D212 => PrefixSpecificity::Explicit, + CheckCodePrefix::D213 => PrefixSpecificity::Explicit, + CheckCodePrefix::D214 => PrefixSpecificity::Explicit, + CheckCodePrefix::D215 => PrefixSpecificity::Explicit, + CheckCodePrefix::D3 => PrefixSpecificity::Hundreds, + CheckCodePrefix::D30 => PrefixSpecificity::Tens, + CheckCodePrefix::D300 => PrefixSpecificity::Explicit, + CheckCodePrefix::D4 => PrefixSpecificity::Hundreds, + CheckCodePrefix::D40 => PrefixSpecificity::Tens, + CheckCodePrefix::D400 => PrefixSpecificity::Explicit, + CheckCodePrefix::D402 => PrefixSpecificity::Explicit, + CheckCodePrefix::D403 => PrefixSpecificity::Explicit, + CheckCodePrefix::D404 => PrefixSpecificity::Explicit, + CheckCodePrefix::D405 => PrefixSpecificity::Explicit, + CheckCodePrefix::D406 => PrefixSpecificity::Explicit, + CheckCodePrefix::D407 => PrefixSpecificity::Explicit, + CheckCodePrefix::D408 => PrefixSpecificity::Explicit, + CheckCodePrefix::D409 => PrefixSpecificity::Explicit, + CheckCodePrefix::D41 => PrefixSpecificity::Tens, + CheckCodePrefix::D410 => PrefixSpecificity::Explicit, + CheckCodePrefix::D411 => PrefixSpecificity::Explicit, + CheckCodePrefix::D412 => PrefixSpecificity::Explicit, + CheckCodePrefix::D413 => PrefixSpecificity::Explicit, + CheckCodePrefix::D414 => PrefixSpecificity::Explicit, + CheckCodePrefix::D415 => PrefixSpecificity::Explicit, + CheckCodePrefix::D416 => PrefixSpecificity::Explicit, + CheckCodePrefix::D417 => PrefixSpecificity::Explicit, + CheckCodePrefix::D418 => PrefixSpecificity::Explicit, + CheckCodePrefix::D419 => PrefixSpecificity::Explicit, + CheckCodePrefix::E => PrefixSpecificity::Category, + CheckCodePrefix::E4 => PrefixSpecificity::Hundreds, + CheckCodePrefix::E40 => PrefixSpecificity::Tens, + CheckCodePrefix::E402 => PrefixSpecificity::Explicit, + CheckCodePrefix::E5 => PrefixSpecificity::Hundreds, + CheckCodePrefix::E50 => PrefixSpecificity::Tens, + CheckCodePrefix::E501 => PrefixSpecificity::Explicit, + CheckCodePrefix::E7 => PrefixSpecificity::Hundreds, + CheckCodePrefix::E71 => PrefixSpecificity::Tens, + CheckCodePrefix::E711 => PrefixSpecificity::Explicit, + CheckCodePrefix::E712 => PrefixSpecificity::Explicit, + CheckCodePrefix::E713 => PrefixSpecificity::Explicit, + CheckCodePrefix::E714 => PrefixSpecificity::Explicit, + CheckCodePrefix::E72 => PrefixSpecificity::Tens, + CheckCodePrefix::E721 => PrefixSpecificity::Explicit, + CheckCodePrefix::E722 => PrefixSpecificity::Explicit, + CheckCodePrefix::E73 => PrefixSpecificity::Tens, + CheckCodePrefix::E731 => PrefixSpecificity::Explicit, + CheckCodePrefix::E74 => PrefixSpecificity::Tens, + CheckCodePrefix::E741 => PrefixSpecificity::Explicit, + CheckCodePrefix::E742 => PrefixSpecificity::Explicit, + CheckCodePrefix::E743 => PrefixSpecificity::Explicit, + CheckCodePrefix::E9 => PrefixSpecificity::Hundreds, + CheckCodePrefix::E90 => PrefixSpecificity::Tens, + CheckCodePrefix::E902 => PrefixSpecificity::Explicit, + CheckCodePrefix::E99 => PrefixSpecificity::Tens, + CheckCodePrefix::E999 => PrefixSpecificity::Explicit, + CheckCodePrefix::F => PrefixSpecificity::Category, + CheckCodePrefix::F4 => PrefixSpecificity::Hundreds, + CheckCodePrefix::F40 => PrefixSpecificity::Tens, + CheckCodePrefix::F401 => PrefixSpecificity::Explicit, + CheckCodePrefix::F402 => PrefixSpecificity::Explicit, + CheckCodePrefix::F403 => PrefixSpecificity::Explicit, + CheckCodePrefix::F404 => PrefixSpecificity::Explicit, + CheckCodePrefix::F405 => PrefixSpecificity::Explicit, + CheckCodePrefix::F406 => PrefixSpecificity::Explicit, + CheckCodePrefix::F407 => PrefixSpecificity::Explicit, + CheckCodePrefix::F5 => PrefixSpecificity::Hundreds, + CheckCodePrefix::F54 => PrefixSpecificity::Tens, + CheckCodePrefix::F541 => PrefixSpecificity::Explicit, + CheckCodePrefix::F6 => PrefixSpecificity::Hundreds, + CheckCodePrefix::F60 => PrefixSpecificity::Tens, + CheckCodePrefix::F601 => PrefixSpecificity::Explicit, + CheckCodePrefix::F602 => PrefixSpecificity::Explicit, + CheckCodePrefix::F62 => PrefixSpecificity::Tens, + CheckCodePrefix::F621 => PrefixSpecificity::Explicit, + CheckCodePrefix::F622 => PrefixSpecificity::Explicit, + CheckCodePrefix::F63 => PrefixSpecificity::Tens, + CheckCodePrefix::F631 => PrefixSpecificity::Explicit, + CheckCodePrefix::F632 => PrefixSpecificity::Explicit, + CheckCodePrefix::F633 => PrefixSpecificity::Explicit, + CheckCodePrefix::F634 => PrefixSpecificity::Explicit, + CheckCodePrefix::F7 => PrefixSpecificity::Hundreds, + CheckCodePrefix::F70 => PrefixSpecificity::Tens, + CheckCodePrefix::F701 => PrefixSpecificity::Explicit, + CheckCodePrefix::F702 => PrefixSpecificity::Explicit, + CheckCodePrefix::F704 => PrefixSpecificity::Explicit, + CheckCodePrefix::F706 => PrefixSpecificity::Explicit, + CheckCodePrefix::F707 => PrefixSpecificity::Explicit, + CheckCodePrefix::F72 => PrefixSpecificity::Tens, + CheckCodePrefix::F722 => PrefixSpecificity::Explicit, + CheckCodePrefix::F8 => PrefixSpecificity::Hundreds, + CheckCodePrefix::F82 => PrefixSpecificity::Tens, + CheckCodePrefix::F821 => PrefixSpecificity::Explicit, + CheckCodePrefix::F822 => PrefixSpecificity::Explicit, + CheckCodePrefix::F823 => PrefixSpecificity::Explicit, + CheckCodePrefix::F83 => PrefixSpecificity::Tens, + CheckCodePrefix::F831 => PrefixSpecificity::Explicit, + CheckCodePrefix::F84 => PrefixSpecificity::Tens, + CheckCodePrefix::F841 => PrefixSpecificity::Explicit, + CheckCodePrefix::F9 => PrefixSpecificity::Hundreds, + CheckCodePrefix::F90 => PrefixSpecificity::Tens, + CheckCodePrefix::F901 => PrefixSpecificity::Explicit, + CheckCodePrefix::M => PrefixSpecificity::Category, + CheckCodePrefix::M0 => PrefixSpecificity::Hundreds, + CheckCodePrefix::M00 => PrefixSpecificity::Tens, + CheckCodePrefix::M001 => PrefixSpecificity::Explicit, + CheckCodePrefix::N => PrefixSpecificity::Category, + CheckCodePrefix::N8 => PrefixSpecificity::Hundreds, + CheckCodePrefix::N80 => PrefixSpecificity::Tens, + CheckCodePrefix::N801 => PrefixSpecificity::Explicit, + CheckCodePrefix::N802 => PrefixSpecificity::Explicit, + CheckCodePrefix::N803 => PrefixSpecificity::Explicit, + CheckCodePrefix::N804 => PrefixSpecificity::Explicit, + CheckCodePrefix::N805 => PrefixSpecificity::Explicit, + CheckCodePrefix::N807 => PrefixSpecificity::Explicit, + CheckCodePrefix::N81 => PrefixSpecificity::Tens, + CheckCodePrefix::N811 => PrefixSpecificity::Explicit, + CheckCodePrefix::N812 => PrefixSpecificity::Explicit, + CheckCodePrefix::N813 => PrefixSpecificity::Explicit, + CheckCodePrefix::N814 => PrefixSpecificity::Explicit, + CheckCodePrefix::N817 => PrefixSpecificity::Explicit, + CheckCodePrefix::T => PrefixSpecificity::Category, + CheckCodePrefix::T2 => PrefixSpecificity::Hundreds, + CheckCodePrefix::T20 => PrefixSpecificity::Tens, + CheckCodePrefix::T201 => PrefixSpecificity::Explicit, + CheckCodePrefix::T203 => PrefixSpecificity::Explicit, + CheckCodePrefix::U => PrefixSpecificity::Category, + CheckCodePrefix::U0 => PrefixSpecificity::Hundreds, + CheckCodePrefix::U00 => PrefixSpecificity::Tens, + CheckCodePrefix::U001 => PrefixSpecificity::Explicit, + CheckCodePrefix::U002 => PrefixSpecificity::Explicit, + CheckCodePrefix::U003 => PrefixSpecificity::Explicit, + CheckCodePrefix::U004 => PrefixSpecificity::Explicit, + CheckCodePrefix::U005 => PrefixSpecificity::Explicit, + CheckCodePrefix::U006 => PrefixSpecificity::Explicit, + CheckCodePrefix::U007 => PrefixSpecificity::Explicit, + CheckCodePrefix::U008 => PrefixSpecificity::Explicit, + CheckCodePrefix::W => PrefixSpecificity::Category, + CheckCodePrefix::W2 => PrefixSpecificity::Hundreds, + CheckCodePrefix::W29 => PrefixSpecificity::Tens, + CheckCodePrefix::W292 => PrefixSpecificity::Explicit, + CheckCodePrefix::W6 => PrefixSpecificity::Hundreds, + CheckCodePrefix::W60 => PrefixSpecificity::Tens, + CheckCodePrefix::W605 => PrefixSpecificity::Explicit, + } + } +} diff --git a/src/cli.rs b/src/cli.rs index 991008fcb08d4..a1365a7f298f0 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -5,7 +5,7 @@ use clap::{command, Parser}; use log::warn; use regex::Regex; -use crate::checks::CheckCode; +use crate::checks_gen::CheckCodePrefix; use crate::printer::SerializationFormat; use crate::pyproject::StrCheckCodePair; use crate::settings::PythonVersion; @@ -43,16 +43,16 @@ pub struct Cli { pub no_cache: bool, /// List of error codes to enable. #[arg(long, value_delimiter = ',')] - pub select: Vec, + pub select: Vec, /// Like --select, but adds additional error codes on top of the selected ones. #[arg(long, value_delimiter = ',')] - pub extend_select: Vec, + pub extend_select: Vec, /// List of error codes to ignore. #[arg(long, value_delimiter = ',')] - pub ignore: Vec, + pub ignore: Vec, /// Like --ignore, but adds additional error codes on top of the ignored ones. #[arg(long, value_delimiter = ',')] - pub extend_ignore: Vec, + pub extend_ignore: Vec, /// List of paths, used to exclude files and/or directories from checks. #[arg(long, value_delimiter = ',')] pub exclude: Vec, @@ -106,9 +106,9 @@ impl fmt::Display for Warnable { /// Warn the user if they attempt to enable a code that won't be respected. pub fn warn_on( flag: Warnable, - codes: &[CheckCode], - cli_ignore: &[CheckCode], - cli_extend_ignore: &[CheckCode], + codes: &[CheckCodePrefix], + cli_ignore: &[CheckCodePrefix], + cli_extend_ignore: &[CheckCodePrefix], pyproject_settings: &RawSettings, pyproject_path: &Option, ) { diff --git a/src/fs.rs b/src/fs.rs index 5cf565f649640..77f792ad416c1 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -133,7 +133,7 @@ pub fn ignores_from_path<'a>( [&pattern_code_pair.pattern].into_iter(), ) }) - .map(|pattern_code_pair| &pattern_code_pair.code) + .flat_map(|pattern_code_pair| &pattern_code_pair.codes) .collect()) } diff --git a/src/lib.rs b/src/lib.rs index 2e3cf1d274769..0702cef80252b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,7 @@ pub mod check_ast; mod check_lines; mod check_tokens; pub mod checks; +mod checks_gen; pub mod cli; pub mod code_gen; mod cst; diff --git a/src/pyproject.rs b/src/pyproject.rs index 9946dd7c12f8a..bc5214a2b1c66 100644 --- a/src/pyproject.rs +++ b/src/pyproject.rs @@ -7,7 +7,7 @@ use path_absolutize::Absolutize; use serde::de; use serde::{Deserialize, Deserializer}; -use crate::checks::CheckCode; +use crate::checks_gen::CheckCodePrefix; use crate::settings::PythonVersion; use crate::{flake8_quotes, fs}; @@ -34,13 +34,13 @@ pub struct Config { pub exclude: Option>, #[serde(default)] pub extend_exclude: Vec, - pub select: Option>, + pub select: Option>, #[serde(default)] - pub extend_select: Vec, + pub extend_select: Vec, #[serde(default)] - pub ignore: Vec, + pub ignore: Vec, #[serde(default)] - pub extend_ignore: Vec, + pub extend_ignore: Vec, #[serde(default)] pub per_file_ignores: Vec, pub dummy_variable_rgx: Option, @@ -51,7 +51,7 @@ pub struct Config { #[derive(Clone, Debug, PartialEq, Eq)] pub struct StrCheckCodePair { pub pattern: String, - pub code: CheckCode, + pub code: CheckCodePrefix, } impl StrCheckCodePair { @@ -84,7 +84,7 @@ impl FromStr for StrCheckCodePair { } (tokens[0].trim(), tokens[1].trim()) }; - let code = CheckCode::from_str(code_string)?; + let code = CheckCodePrefix::from_str(code_string)?; let pattern = pattern_str.into(); Ok(Self { pattern, code }) } @@ -157,7 +157,7 @@ mod tests { use anyhow::Result; - use crate::checks::CheckCode; + use crate::checks_gen::CheckCodePrefix; use crate::flake8_quotes; use crate::flake8_quotes::settings::Quote; use crate::pyproject::{ @@ -269,7 +269,7 @@ select = ["E501"] line_length: None, exclude: None, extend_exclude: vec![], - select: Some(vec![CheckCode::E501]), + select: Some(vec![CheckCodePrefix::E501]), extend_select: vec![], ignore: vec![], extend_ignore: vec![], @@ -297,8 +297,8 @@ ignore = ["E501"] exclude: None, extend_exclude: vec![], select: None, - extend_select: vec![CheckCode::M001], - ignore: vec![CheckCode::E501], + extend_select: vec![CheckCodePrefix::M001], + ignore: vec![CheckCodePrefix::E501], extend_ignore: vec![], per_file_ignores: vec![], dummy_variable_rgx: None, @@ -372,7 +372,7 @@ other-attribute = 1 extend_ignore: vec![], per_file_ignores: vec![StrCheckCodePair { pattern: "__init__.py".to_string(), - code: CheckCode::F401 + code: CheckCodePrefix::F401 }], dummy_variable_rgx: None, target_version: None, diff --git a/src/settings.rs b/src/settings.rs index cc49c839c52df..824ea7cba22a4 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -8,9 +8,9 @@ use glob::Pattern; use once_cell::sync::Lazy; use regex::Regex; use serde::{Deserialize, Serialize}; -use strum::IntoEnumIterator; -use crate::checks::{CheckCategory, CheckCode}; +use crate::checks::CheckCode; +use crate::checks_gen::{CheckCodePrefix, PrefixSpecificity}; use crate::pyproject::{load_config, StrCheckCodePair}; use crate::{flake8_quotes, fs}; @@ -74,14 +74,14 @@ impl FilePattern { #[derive(Debug, Clone, Hash)] pub struct PerFileIgnore { pub pattern: FilePattern, - pub code: CheckCode, + pub codes: BTreeSet, } impl PerFileIgnore { pub fn new(user_in: StrCheckCodePair, project_root: &Option) -> Self { let pattern = FilePattern::from_user(user_in.pattern.as_str(), project_root); - let code = user_in.code; - Self { pattern, code } + let codes = BTreeSet::from_iter(user_in.code.codes()); + Self { pattern, codes } } } @@ -90,12 +90,12 @@ pub struct RawSettings { pub dummy_variable_rgx: Regex, pub exclude: Vec, pub extend_exclude: Vec, - pub extend_ignore: Vec, - pub extend_select: Vec, - pub ignore: Vec, + pub extend_ignore: Vec, + pub extend_select: Vec, + pub ignore: Vec, pub line_length: usize, pub per_file_ignores: Vec, - pub select: Vec, + pub select: Vec, pub target_version: PythonVersion, // Plugins pub flake8_quotes: flake8_quotes::settings::Settings, @@ -157,16 +157,9 @@ impl RawSettings { .map(|path| FilePattern::from_user(path, project_root)) .collect(), extend_ignore: config.extend_ignore, - select: config.select.unwrap_or_else(|| { - CheckCode::iter() - .filter(|code| { - matches!( - code.category(), - CheckCategory::PycodestyleError | CheckCategory::Pyflakes - ) - }) - .collect() - }), + select: config + .select + .unwrap_or_else(|| vec![CheckCodePrefix::E, CheckCodePrefix::F]), extend_select: config.extend_select, ignore: config.ignore, line_length: config.line_length.unwrap_or(88), @@ -197,21 +190,58 @@ pub struct Settings { pub flake8_quotes: flake8_quotes::settings::Settings, } -impl Settings { - pub fn from_raw(settings: RawSettings) -> Self { - // Materialize the set of enabled CheckCodes. - let mut enabled: BTreeSet = BTreeSet::new(); - enabled.extend(settings.select); - enabled.extend(settings.extend_select); - for code in &settings.ignore { - enabled.remove(code); +/// Given a set of selected and ignored prefixes, resolve the set of enabled error codes. +fn resolve_codes( + select: &[CheckCodePrefix], + extend_select: &[CheckCodePrefix], + ignore: &[CheckCodePrefix], + extend_ignore: &[CheckCodePrefix], +) -> BTreeSet { + let mut codes: BTreeSet = BTreeSet::new(); + for specificity in [ + PrefixSpecificity::Category, + PrefixSpecificity::Hundreds, + PrefixSpecificity::Tens, + PrefixSpecificity::Explicit, + ] { + for prefix in select { + if prefix.specificity() == specificity { + codes.extend(prefix.codes()); + } + } + for prefix in extend_select { + if prefix.specificity() == specificity { + codes.extend(prefix.codes()); + } } - for code in &settings.extend_ignore { - enabled.remove(code); + for prefix in ignore { + if prefix.specificity() == specificity { + for code in prefix.codes() { + codes.remove(&code); + } + } } + for prefix in extend_ignore { + if prefix.specificity() == specificity { + for code in prefix.codes() { + codes.remove(&code); + } + } + } + } + codes +} + +impl Settings { + pub fn from_raw(settings: RawSettings) -> Self { Self { dummy_variable_rgx: settings.dummy_variable_rgx, - enabled, + enabled: resolve_codes( + &settings.select, + &settings.extend_select, + &settings.ignore, + &settings.extend_ignore, + ), exclude: settings.exclude, extend_exclude: settings.extend_exclude, flake8_quotes: settings.flake8_quotes, @@ -290,12 +320,12 @@ pub struct CurrentSettings { pub dummy_variable_rgx: Regex, pub exclude: Vec, pub extend_exclude: Vec, - pub extend_ignore: Vec, - pub extend_select: Vec, - pub ignore: Vec, + pub extend_ignore: Vec, + pub extend_select: Vec, + pub ignore: Vec, pub line_length: usize, pub per_file_ignores: Vec, - pub select: Vec, + pub select: Vec, pub target_version: PythonVersion, // Plugins pub flake8_quotes: flake8_quotes::settings::Settings,