Skip to content

Commit 6a7172b

Browse files
authored
refactor(configuration): cleanup codegen and make RuleSelector generic (#623)
1 parent b40b276 commit 6a7172b

File tree

18 files changed

+917
-997
lines changed

18 files changed

+917
-997
lines changed

.sqlx/query-02927e584e85871ba6f84c58e8b5e4454b2c36eaf034657d5d2d95633fb85bdb.json

Lines changed: 0 additions & 74 deletions
This file was deleted.

.sqlx/query-425fc6118e76cea42cf256b3b0f11046dc8b77d84c94314a0ed0716e5803df69.json

Lines changed: 0 additions & 74 deletions
This file was deleted.

crates/pgls_cli/src/execute/process_file/check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub(crate) fn check_with_guard<'ctx>(
3131

3232
let pull_diagnostics_result = workspace_file
3333
.guard()
34-
.pull_diagnostics(
34+
.pull_file_diagnostics(
3535
RuleCategoriesBuilder::default().all().build(),
3636
max_diagnostics,
3737
only,

crates/pgls_configuration/src/analyser/splinter/rules.rs

Lines changed: 0 additions & 754 deletions
This file was deleted.

crates/pgls_configuration/src/generated/splinter.rs

Lines changed: 0 additions & 29 deletions
This file was deleted.

crates/pgls_configuration/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub mod linter;
99
pub mod migrations;
1010
pub mod plpgsql_check;
1111
pub mod rules;
12+
pub mod splinter;
1213
pub mod typecheck;
1314
pub mod vcs;
1415

@@ -37,7 +38,7 @@ use plpgsql_check::{
3738
partial_pl_pg_sql_check_configuration,
3839
};
3940
pub use rules::{
40-
RuleConfiguration, RuleFixConfiguration, RulePlainConfiguration, RuleSelector,
41+
AnalyzerGroup, RuleConfiguration, RuleFixConfiguration, RulePlainConfiguration, RuleSelector,
4142
RuleWithFixOptions, RuleWithOptions,
4243
};
4344
use serde::{Deserialize, Serialize};

crates/pgls_configuration/src/linter/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@ pub struct LinterConfiguration {
1818
#[doc = r" List of rules"]
1919
#[partial(bpaf(pure(Default::default()), optional, hide))]
2020
pub rules: Rules,
21-
#[doc = r" A list of Unix shell style patterns. The formatter will ignore files/folders that will"]
22-
#[doc = r" match these patterns."]
21+
#[doc = r" A list of Unix shell style patterns. The linter will ignore files/folders that will match these patterns."]
2322
#[partial(bpaf(hide))]
2423
pub ignore: StringSet,
25-
#[doc = r" A list of Unix shell style patterns. The formatter will include files/folders that will"]
26-
#[doc = r" match these patterns."]
24+
#[doc = r" A list of Unix shell style patterns. The linter will include files/folders that will match these patterns."]
2725
#[partial(bpaf(hide))]
2826
pub include: StringSet,
2927
}

crates/pgls_configuration/src/linter/rules.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ impl Rules {
7272
#[doc = r" The function can return `None` if the rule is not properly configured."]
7373
pub fn get_severity_from_code(&self, category: &Category) -> Option<Severity> {
7474
let mut split_code = category.name().split('/');
75-
let _lint = split_code.next();
76-
debug_assert_eq!(_lint, Some("lint"));
75+
let _category_prefix = split_code.next();
76+
debug_assert_eq!(_category_prefix, Some("lint"));
7777
let group = <RuleGroup as std::str::FromStr>::from_str(split_code.next()?).ok()?;
7878
let rule_name = split_code.next()?;
7979
let rule_name = Self::has_rule(group, rule_name)?;

crates/pgls_configuration/src/rules/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ pub use configuration::{
66
RuleConfiguration, RuleFixConfiguration, RulePlainConfiguration, RuleWithFixOptions,
77
RuleWithOptions,
88
};
9-
pub use selector::RuleSelector;
9+
pub use selector::{AnalyzerGroup, RuleSelector};

crates/pgls_configuration/src/rules/selector.rs

Lines changed: 80 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,33 @@ use pgls_analyse::RuleFilter;
22

33
use std::str::FromStr;
44

5-
use crate::{Rules, linter::RuleGroup};
5+
/// Represents a rule group from any analyzer (linter or splinter)
6+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
7+
pub enum AnalyzerGroup {
8+
Linter(crate::linter::RuleGroup),
9+
Splinter(crate::splinter::RuleGroup),
10+
}
11+
12+
impl AnalyzerGroup {
13+
pub const fn as_str(self) -> &'static str {
14+
match self {
15+
Self::Linter(group) => group.as_str(),
16+
Self::Splinter(group) => group.as_str(),
17+
}
18+
}
19+
20+
pub const fn category_prefix(&self) -> &'static str {
21+
match self {
22+
Self::Linter(_) => "lint",
23+
Self::Splinter(_) => "splinter",
24+
}
25+
}
26+
}
627

728
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
829
pub enum RuleSelector {
9-
Group(RuleGroup),
10-
Rule(RuleGroup, &'static str),
30+
Group(AnalyzerGroup),
31+
Rule(AnalyzerGroup, &'static str),
1132
}
1233

1334
impl From<RuleSelector> for RuleFilter<'static> {
@@ -31,20 +52,56 @@ impl<'a> From<&'a RuleSelector> for RuleFilter<'static> {
3152
impl FromStr for RuleSelector {
3253
type Err = &'static str;
3354
fn from_str(selector: &str) -> Result<Self, Self::Err> {
34-
let selector = selector.strip_prefix("lint/").unwrap_or(selector);
35-
if let Some((group_name, rule_name)) = selector.split_once('/') {
36-
let group = RuleGroup::from_str(group_name)?;
37-
if let Some(rule_name) = Rules::has_rule(group, rule_name) {
38-
Ok(RuleSelector::Rule(group, rule_name))
39-
} else {
40-
Err("This rule doesn't exist.")
55+
// Try to detect the analyzer from the prefix
56+
let (analyzer_type, rest) = if let Some(rest) = selector.strip_prefix("lint/") {
57+
("lint", rest)
58+
} else if let Some(rest) = selector.strip_prefix("splinter/") {
59+
("splinter", rest)
60+
} else {
61+
// Default to lint for backward compatibility
62+
("lint", selector)
63+
};
64+
65+
if let Some((group_name, rule_name)) = rest.split_once('/') {
66+
// Parse as <group>/<rule>
67+
match analyzer_type {
68+
"lint" => {
69+
let group = crate::linter::RuleGroup::from_str(group_name)?;
70+
if let Some(rule_name) = crate::linter::Rules::has_rule(group, rule_name) {
71+
Ok(RuleSelector::Rule(AnalyzerGroup::Linter(group), rule_name))
72+
} else {
73+
Err("This rule doesn't exist.")
74+
}
75+
}
76+
"splinter" => {
77+
let group = crate::splinter::RuleGroup::from_str(group_name)?;
78+
if let Some(rule_name) = crate::splinter::Rules::has_rule(group, rule_name) {
79+
Ok(RuleSelector::Rule(
80+
AnalyzerGroup::Splinter(group),
81+
rule_name,
82+
))
83+
} else {
84+
Err("This rule doesn't exist.")
85+
}
86+
}
87+
_ => Err("Unknown analyzer type."),
4188
}
4289
} else {
43-
match RuleGroup::from_str(selector) {
44-
Ok(group) => Ok(RuleSelector::Group(group)),
45-
Err(_) => Err(
46-
"This group doesn't exist. Use the syntax `<group>/<rule>` to specify a rule.",
47-
),
90+
// Parse as just <group>
91+
match analyzer_type {
92+
"lint" => match crate::linter::RuleGroup::from_str(rest) {
93+
Ok(group) => Ok(RuleSelector::Group(AnalyzerGroup::Linter(group))),
94+
Err(_) => Err(
95+
"This group doesn't exist. Use the syntax `<group>/<rule>` to specify a rule.",
96+
),
97+
},
98+
"splinter" => match crate::splinter::RuleGroup::from_str(rest) {
99+
Ok(group) => Ok(RuleSelector::Group(AnalyzerGroup::Splinter(group))),
100+
Err(_) => Err(
101+
"This group doesn't exist. Use the syntax `<group>/<rule>` to specify a rule.",
102+
),
103+
},
104+
_ => Err("Unknown analyzer type."),
48105
}
49106
}
50107
}
@@ -53,10 +110,15 @@ impl FromStr for RuleSelector {
53110
impl serde::Serialize for RuleSelector {
54111
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
55112
match self {
56-
RuleSelector::Group(group) => serializer.serialize_str(group.as_str()),
113+
RuleSelector::Group(group) => {
114+
let prefix = group.category_prefix();
115+
let group_name = group.as_str();
116+
serializer.serialize_str(&format!("{prefix}/{group_name}"))
117+
}
57118
RuleSelector::Rule(group, rule_name) => {
119+
let prefix = group.category_prefix();
58120
let group_name = group.as_str();
59-
serializer.serialize_str(&format!("{group_name}/{rule_name}"))
121+
serializer.serialize_str(&format!("{prefix}/{group_name}/{rule_name}"))
60122
}
61123
}
62124
}
@@ -68,7 +130,7 @@ impl<'de> serde::Deserialize<'de> for RuleSelector {
68130
impl serde::de::Visitor<'_> for Visitor {
69131
type Value = RuleSelector;
70132
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
71-
formatter.write_str("<group>/<ruyle_name>")
133+
formatter.write_str("<group>/<rule_name>")
72134
}
73135
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
74136
match RuleSelector::from_str(v) {

0 commit comments

Comments
 (0)