Skip to content

Commit d04cbc9

Browse files
authored
feat(splinter): allow ignoring db objects (#634)
adds an `ignores` config option to all `splinter` rules. the filter is applied in rust and not part of the query for more flexibility. also: moved `matcher` into its own crate to allow `splinter` to reuse it
1 parent 763c9af commit d04cbc9

File tree

20 files changed

+670
-274
lines changed

20 files changed

+670
-274
lines changed

Cargo.lock

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ pgls_lexer = { path = "./crates/pgls_lexer", version = "0.0.0"
7777
pgls_lexer_codegen = { path = "./crates/pgls_lexer_codegen", version = "0.0.0" }
7878
pgls_lsp = { path = "./crates/pgls_lsp", version = "0.0.0" }
7979
pgls_markup = { path = "./crates/pgls_markup", version = "0.0.0" }
80+
pgls_matcher = { path = "./crates/pgls_matcher", version = "0.0.0" }
8081
pgls_plpgsql_check = { path = "./crates/pgls_plpgsql_check", version = "0.0.0" }
8182
pgls_query = { path = "./crates/pgls_query", version = "0.0.0" }
8283
pgls_query_ext = { path = "./crates/pgls_query_ext", version = "0.0.0" }

crates/pgls_configuration/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pgls_analyser = { workspace = true }
2222
pgls_console = { workspace = true }
2323
pgls_diagnostics = { workspace = true }
2424
pgls_env = { workspace = true }
25+
pgls_matcher = { workspace = true }
2526
pgls_text_size = { workspace = true }
2627
rustc-hash = { workspace = true }
2728
schemars = { workspace = true, features = ["indexmap1"], optional = true }

crates/pgls_configuration/src/rules/configuration.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ impl<T: Clone + Default + 'static> RuleConfiguration<T> {
5858
}
5959
}
6060
}
61+
impl<T: Default> RuleConfiguration<T> {
62+
/// Get a reference to the typed options if present
63+
pub fn get_options_ref(&self) -> Option<&T> {
64+
match self {
65+
Self::Plain(_) => None,
66+
Self::WithOptions(options) => Some(&options.options),
67+
}
68+
}
69+
}
6170
impl<T: Default> Default for RuleConfiguration<T> {
6271
fn default() -> Self {
6372
Self::Plain(RulePlainConfiguration::Error)

crates/pgls_configuration/src/splinter/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Generated file, do not edit by hand, see `xtask/codegen`
22
33
#![doc = r" Generated file, do not edit by hand, see `xtask/codegen`"]
4+
mod options;
5+
pub use options::SplinterRuleOptions;
46
mod rules;
57
use biome_deserialize::StringSet;
68
use biome_deserialize_macros::{Merge, Partial};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use biome_deserialize_macros::Deserializable;
2+
#[cfg(feature = "schema")]
3+
use schemars::JsonSchema;
4+
use serde::{Deserialize, Serialize};
5+
6+
/// Shared options for all splinter rules.
7+
///
8+
/// These options allow configuring per-rule filtering of database objects.
9+
#[derive(Clone, Debug, Default, Deserialize, Deserializable, Eq, PartialEq, Serialize)]
10+
#[cfg_attr(feature = "schema", derive(JsonSchema))]
11+
#[serde(rename_all = "camelCase", deny_unknown_fields)]
12+
pub struct SplinterRuleOptions {
13+
/// A list of glob patterns for database objects to ignore.
14+
///
15+
/// Patterns use Unix-style globs where:
16+
/// - `*` matches any sequence of characters
17+
/// - `?` matches any single character
18+
///
19+
/// Each pattern should be in the format `schema.object_name`, for example:
20+
/// - `"public.my_table"` - ignores a specific table
21+
/// - `"audit.*"` - ignores all objects in the audit schema
22+
/// - `"*.audit_*"` - ignores objects with audit_ prefix in any schema
23+
#[serde(default)]
24+
pub ignore: Vec<String>,
25+
}

crates/pgls_configuration/src/splinter/rules.rs

Lines changed: 285 additions & 21 deletions
Large diffs are not rendered by default.

crates/pgls_matcher/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
authors.workspace = true
3+
categories.workspace = true
4+
description = "Unix shell style pattern matching for Postgres Language Server"
5+
edition.workspace = true
6+
homepage.workspace = true
7+
keywords.workspace = true
8+
license.workspace = true
9+
name = "pgls_matcher"
10+
repository.workspace = true
11+
version = "0.0.0"
12+
13+
[dependencies]
14+
pgls_console = { workspace = true }
15+
pgls_diagnostics = { workspace = true }
16+
rustc-hash = { workspace = true }
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ impl Diagnostic for PatternError {
135135

136136
#[cfg(test)]
137137
mod test {
138-
use crate::matcher::Matcher;
139-
use crate::matcher::pattern::MatchOptions;
138+
use crate::Matcher;
139+
use crate::pattern::MatchOptions;
140140
use std::env;
141141

142142
#[test]
@@ -145,7 +145,7 @@ mod test {
145145
let dir = format!("{}/**/*.rs", current.display());
146146
let mut ignore = Matcher::new(MatchOptions::default());
147147
ignore.add_pattern(&dir).unwrap();
148-
let path = env::current_dir().unwrap().join("src/workspace.rs");
148+
let path = env::current_dir().unwrap().join("src/lib.rs");
149149
let result = ignore.matches(path.to_str().unwrap());
150150

151151
assert!(result);
@@ -157,7 +157,7 @@ mod test {
157157
let dir = format!("{}/**/*.rs", current.display());
158158
let mut ignore = Matcher::new(MatchOptions::default());
159159
ignore.add_pattern(&dir).unwrap();
160-
let path = env::current_dir().unwrap().join("src/workspace.rs");
160+
let path = env::current_dir().unwrap().join("src/lib.rs");
161161
let result = ignore.matches_path(path.as_path());
162162

163163
assert!(result);
@@ -184,14 +184,14 @@ mod test {
184184

185185
#[test]
186186
fn matches_single_path() {
187-
let dir = "workspace.rs";
187+
let dir = "lib.rs";
188188
let mut ignore = Matcher::new(MatchOptions {
189189
require_literal_separator: true,
190190
case_sensitive: true,
191191
require_literal_leading_dot: true,
192192
});
193193
ignore.add_pattern(dir).unwrap();
194-
let path = env::current_dir().unwrap().join("src/workspace.rs");
194+
let path = env::current_dir().unwrap().join("src/lib.rs");
195195
let result = ignore.matches(path.to_str().unwrap());
196196

197197
assert!(result);

crates/pgls_workspace/src/matcher/pattern.rs renamed to crates/pgls_matcher/src/pattern.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use crate::matcher::pattern::CharSpecifier::{CharRange, SingleChar};
2-
use crate::matcher::pattern::MatchResult::{
3-
EntirePatternDoesntMatch, Match, SubPatternDoesntMatch,
4-
};
5-
use crate::matcher::pattern::PatternToken::{
1+
use crate::pattern::CharSpecifier::{CharRange, SingleChar};
2+
use crate::pattern::MatchResult::{EntirePatternDoesntMatch, Match, SubPatternDoesntMatch};
3+
use crate::pattern::PatternToken::{
64
AnyChar, AnyExcept, AnyPattern, AnyRecursiveSequence, AnySequence, AnyWithin, Char,
75
};
86
use std::error::Error;

0 commit comments

Comments
 (0)