Skip to content

Commit 50bf83d

Browse files
feat: add RuleOverwrite to override rule severity from CLI
fix ast-grep#1061
1 parent 8ad0182 commit 50bf83d

File tree

7 files changed

+62
-36
lines changed

7 files changed

+62
-36
lines changed

crates/cli/src/config.rs

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
use crate::lang::{CustomLang, LanguageGlobs, SerializableInjection, SgLang};
2-
use crate::utils::{ErrorContext as EC, RuleTrace};
2+
use crate::utils::{ErrorContext as EC, RuleOverwrite, RuleTrace};
33

44
use anyhow::{Context, Result};
55
use ast_grep_config::{
66
from_str, from_yaml_string, DeserializeEnv, GlobalRules, RuleCollection, RuleConfig,
77
};
88
use ast_grep_language::config_file_type;
99
use ignore::WalkBuilder;
10-
use regex::Regex;
1110
use serde::{Deserialize, Serialize};
1211

1312
use std::collections::HashMap;
@@ -84,11 +83,11 @@ impl ProjectConfig {
8483

8584
pub fn find_rules(
8685
config_path: Option<PathBuf>,
87-
rule_filter: Option<&Regex>,
86+
rule_overwrite: RuleOverwrite,
8887
) -> Result<(RuleCollection<SgLang>, RuleTrace)> {
8988
let project_config = ProjectConfig::by_config_path(config_path)?;
9089
let global_rules = find_util_rules(&project_config)?;
91-
read_directory_yaml(&project_config, global_rules, rule_filter)
90+
read_directory_yaml(&project_config, global_rules, rule_overwrite)
9291
}
9392

9493
pub fn register_custom_language(config_path: Option<PathBuf>) -> Result<()> {
@@ -153,7 +152,7 @@ fn find_util_rules(config: &ProjectConfig) -> Result<GlobalRules<SgLang>> {
153152
fn read_directory_yaml(
154153
config: &ProjectConfig,
155154
global_rules: GlobalRules<SgLang>,
156-
rule_filter: Option<&Regex>,
155+
rule_overwrite: RuleOverwrite,
157156
) -> Result<(RuleCollection<SgLang>, RuleTrace)> {
158157
let mut configs = vec![];
159158
let ProjectConfig {
@@ -182,11 +181,7 @@ fn read_directory_yaml(
182181
}
183182
let total_rule_count = configs.len();
184183

185-
let configs = if let Some(filter) = rule_filter {
186-
filter_rule_by_regex(configs, filter)?
187-
} else {
188-
configs
189-
};
184+
let configs = rule_overwrite.process_configs(configs)?;
190185
let collection = RuleCollection::try_new(configs).context(EC::GlobPattern)?;
191186
let effective_rule_count = collection.total_rule_count();
192187
let trace = RuleTrace {
@@ -196,22 +191,6 @@ fn read_directory_yaml(
196191
Ok((collection, trace))
197192
}
198193

199-
fn filter_rule_by_regex(
200-
configs: Vec<RuleConfig<SgLang>>,
201-
filter: &Regex,
202-
) -> Result<Vec<RuleConfig<SgLang>>> {
203-
let selected: Vec<_> = configs
204-
.into_iter()
205-
.filter(|c| filter.is_match(&c.id))
206-
.collect();
207-
208-
if selected.is_empty() {
209-
Err(anyhow::anyhow!(EC::RuleNotFound(filter.to_string())))
210-
} else {
211-
Ok(selected)
212-
}
213-
}
214-
215194
pub fn read_rule_file(
216195
path: &Path,
217196
global_rules: Option<&GlobalRules<SgLang>>,

crates/cli/src/lsp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ async fn run_language_server_impl(arg: LspArg) -> Result<()> {
2424
let stdin = tokio::io::stdin();
2525
let stdout = tokio::io::stdout();
2626
let config_base = find_config_base(arg.config.clone())?;
27-
let config_result = find_rules(arg.config, None);
27+
let config_result = find_rules(arg.config, Default::default());
2828
let config_result_std: std::result::Result<_, String> = config_result
2929
.map_err(|e| {
3030
// convert anyhow::Error to String with chain of causes

crates/cli/src/scan.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::print::{
1717
ReportStyle, SimpleFile,
1818
};
1919
use crate::utils::ErrorContext as EC;
20+
use crate::utils::RuleOverwrite;
2021
use crate::utils::{filter_file_interactive, InputArgs, OutputArgs, SeverityArg};
2122
use crate::utils::{FileTrace, RuleTrace, ScanTrace};
2223
use crate::utils::{Items, PathWorker, StdInWorker, Worker};
@@ -120,7 +121,8 @@ impl<P: Printer> ScanWithConfig<P> {
120121
.with_context(|| EC::ParseRule("INLINE_RULES".into()))?;
121122
RuleCollection::try_new(rules).context(EC::GlobPattern)?
122123
} else {
123-
let (configs, r_stats) = find_rules(arg.config.take(), arg.filter.as_ref())?;
124+
let overwrite = RuleOverwrite::new(&arg.severity, &arg.filter)?;
125+
let (configs, r_stats) = find_rules(arg.config.take(), overwrite)?;
124126
rule_trace = r_stats;
125127
configs
126128
};

crates/cli/src/utils/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod worker;
88
pub use args::{InputArgs, OutputArgs, SeverityArg};
99
pub use debug_query::DebugFormat;
1010
pub use error_context::{exit_with_error, ErrorContext};
11+
pub use rule_overwrite::RuleOverwrite;
1112
pub use tracing::{FileTrace, RuleTrace, RunTrace, ScanTrace, Tracing};
1213
pub use worker::{Items, PathWorker, StdInWorker, Worker};
1314

crates/cli/src/utils/rule_overwrite.rs

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
use super::SeverityArg;
2+
use crate::lang::SgLang;
3+
use crate::utils::ErrorContext as EC;
24

35
use anyhow::Result;
4-
use ast_grep_config::{SerializableRuleConfig, Severity};
6+
use ast_grep_config::{RuleConfig, Severity};
57
use ast_grep_core::Language;
8+
use regex::Regex;
69

710
use std::collections::HashMap;
811

9-
struct RuleOverwrite {
12+
#[derive(Default)]
13+
pub struct RuleOverwrite {
1014
default_severity: Option<Severity>,
1115
by_rule_id: HashMap<String, Severity>,
16+
rule_filter: Option<Regex>,
1217
}
1318

1419
fn read_severity(
@@ -28,7 +33,7 @@ fn read_severity(
2833
}
2934

3035
impl RuleOverwrite {
31-
pub fn new(cli: SeverityArg) -> Result<Self> {
36+
pub fn new(cli: &SeverityArg, filter: &Option<Regex>) -> Result<Self> {
3237
let mut default_severity = None;
3338
let mut by_rule_id = HashMap::new();
3439
read_severity(
@@ -64,10 +69,27 @@ impl RuleOverwrite {
6469
Ok(Self {
6570
default_severity,
6671
by_rule_id,
72+
rule_filter: filter.clone(),
6773
})
6874
}
6975

70-
pub fn find(&self, id: &str) -> OverwriteResult {
76+
pub fn process_configs(
77+
&self,
78+
configs: Vec<RuleConfig<SgLang>>,
79+
) -> Result<Vec<RuleConfig<SgLang>>> {
80+
let mut configs = if let Some(filter) = &self.rule_filter {
81+
filter_rule_by_regex(configs, filter)?
82+
} else {
83+
configs
84+
};
85+
for config in &mut configs {
86+
let overwrite = self.find(&config.id);
87+
overwrite.overwrite(config);
88+
}
89+
Ok(configs)
90+
}
91+
92+
fn find(&self, id: &str) -> OverwriteResult {
7193
let severity = self
7294
.by_rule_id
7395
.get(id)
@@ -77,12 +99,28 @@ impl RuleOverwrite {
7799
}
78100
}
79101

80-
pub struct OverwriteResult {
81-
pub severity: Option<Severity>,
102+
fn filter_rule_by_regex(
103+
configs: Vec<RuleConfig<SgLang>>,
104+
filter: &Regex,
105+
) -> Result<Vec<RuleConfig<SgLang>>> {
106+
let selected: Vec<_> = configs
107+
.into_iter()
108+
.filter(|c| filter.is_match(&c.id))
109+
.collect();
110+
111+
if selected.is_empty() {
112+
Err(anyhow::anyhow!(EC::RuleNotFound(filter.to_string())))
113+
} else {
114+
Ok(selected)
115+
}
116+
}
117+
118+
struct OverwriteResult {
119+
severity: Option<Severity>,
82120
}
83121

84122
impl OverwriteResult {
85-
pub fn overwrite<L>(&self, rule: &mut SerializableRuleConfig<L>)
123+
fn overwrite<L>(&self, rule: &mut RuleConfig<L>)
86124
where
87125
L: Language,
88126
{

crates/cli/src/verify.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ where
5757
}
5858

5959
fn run_test_rule_impl<R: Reporter + Send>(arg: TestArg, reporter: R) -> Result<()> {
60-
let collections = &find_rules(arg.config.clone(), None)?.0;
60+
let collections = &find_rules(arg.config.clone(), Default::default())?.0;
6161
let TestHarness {
6262
test_cases,
6363
snapshots,

crates/config/src/rule_config.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ impl<L: Language> Deref for RuleConfig<L> {
208208
}
209209
}
210210

211+
impl<L: Language> DerefMut for RuleConfig<L> {
212+
fn deref_mut(&mut self) -> &mut Self::Target {
213+
&mut self.inner
214+
}
215+
}
216+
211217
#[cfg(test)]
212218
mod test {
213219
use super::*;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy