From b5c19f9a369baac2013ccbea96c2c2ae237bad30 Mon Sep 17 00:00:00 2001 From: iff Date: Wed, 9 Apr 2025 17:16:58 +0200 Subject: [PATCH] feat: allow regex in conditions --- module-runtime-rules/src/rules.rs | 16 ++++++++++------ parser/src/lib.rs | 17 ++++++++++++----- rules/pr_general.toml | 2 +- utils/src/evals.rs | 5 +++++ 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/module-runtime-rules/src/rules.rs b/module-runtime-rules/src/rules.rs index 8e370fd..439ab23 100644 --- a/module-runtime-rules/src/rules.rs +++ b/module-runtime-rules/src/rules.rs @@ -29,7 +29,6 @@ pub fn runtime_match( let split_command = split_command(last_command); let mut pure_suggest; - for match_err in rule.match_err { for pattern in match_err.pattern { if error_msg.contains(&pattern) { @@ -53,7 +52,11 @@ pub fn runtime_match( for condition in conditions { let (mut condition, arg) = condition.split_once('(').unwrap(); condition = condition.trim(); - let arg = arg.trim_start_matches('(').trim_end_matches(')'); + let arg = arg + .to_string() + .chars() + .take(arg.len() - 1) + .collect::(); let reverse = match condition.starts_with('!') { true => { condition = condition.trim_start_matches('!'); @@ -63,7 +66,7 @@ pub fn runtime_match( }; if eval_condition( condition, - arg, + &arg, shell, last_command, error_msg, @@ -79,6 +82,7 @@ pub fn runtime_match( } else { pure_suggest = suggest.to_owned(); } + // replacing placeholders if pure_suggest.contains("{{command}}") { pure_suggest = pure_suggest.replace("{{command}}", last_command); @@ -90,6 +94,7 @@ pub fn runtime_match( print!("<_PR_BR>"); } } + break; } } } @@ -106,9 +111,8 @@ fn eval_condition( ) -> bool { match condition { "executable" => executables.contains(&arg.to_string()), - "err_contains" => error_msg.contains(arg), - "cmd_contains" => last_command.contains(arg), - "exe_contains" => split_command[0].contains(arg), + "err_contains" => regex_match(arg, error_msg), + "cmd_contains" => regex_match(arg, last_command), "min_length" => split_command.len() >= arg.parse::().unwrap(), "length" => split_command.len() == arg.parse::().unwrap(), "max_length" => split_command.len() <= arg.parse::().unwrap() + 1, diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 0953abe..f181507 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -105,6 +105,7 @@ fn gen_match_rules(rules: &[Rule]) -> TokenStream { for pattern in #patterns_tokens { if error_msg.contains(pattern) { #suggestion_tokens; + break; }; })* }) @@ -149,7 +150,14 @@ fn parse_conditions(suggest: &str) -> (String, Vec) { for condition in conditions { let (mut condition, arg) = condition.split_once('(').unwrap(); condition = condition.trim(); - let arg = arg.trim_start_matches('(').trim_end_matches(')'); + // remove only the last character which is ')' + // other ')' are kept for regex + let arg = arg + .to_string() + .chars() + .take(arg.len() - 1) + .collect::(); + let reverse = match condition.starts_with('!') { true => { condition = condition.trim_start_matches('!'); @@ -157,7 +165,7 @@ fn parse_conditions(suggest: &str) -> (String, Vec) { } false => false, }; - let evaluated_condition = eval_condition(condition, arg); + let evaluated_condition = eval_condition(condition, &arg); eval_conditions.push(quote! {#evaluated_condition == !#reverse}); } @@ -170,9 +178,8 @@ fn parse_conditions(suggest: &str) -> (String, Vec) { fn eval_condition(condition: &str, arg: &str) -> TokenStream2 { match condition { "executable" => quote! {executables.contains(&#arg.to_string())}, - "err_contains" => quote! {error_msg.contains(#arg)}, - "cmd_contains" => quote! {last_command.contains(#arg)}, - "exe_contains" => quote! {split[0].contains(#arg)}, + "err_contains" => quote! {regex_match(#arg, &error_msg)}, + "cmd_contains" => quote! {regex_match(#arg, &last_command)}, "min_length" => quote! {(split.len() >= #arg.parse::().unwrap())}, "length" => quote! {(split.len() == #arg.parse::().unwrap())}, "max_length" => quote! {(split.len() <= #arg.parse::().unwrap() + 1)}, diff --git a/rules/pr_general.toml b/rules/pr_general.toml index 967fe30..515b89f 100644 --- a/rules/pr_general.toml +++ b/rules/pr_general.toml @@ -19,7 +19,7 @@ pattern = [ ] suggest = [ ''' -#[exe_contains(/)] +#[cmd_contains((?m)^(\S*)\/(\S*))] chmod +x {{command[0]}} && {{command}}''' ] diff --git a/utils/src/evals.rs b/utils/src/evals.rs index f6263e1..f2666cb 100644 --- a/utils/src/evals.rs +++ b/utils/src/evals.rs @@ -18,6 +18,11 @@ fn regex_captures(regex: &str, string: &str) -> Vec { caps } +pub fn regex_match(regex: &str, string: &str) -> bool { + let regex = Regex::new(regex).unwrap(); + regex.is_match(string) +} + pub fn opt_regex(regex: &str, command: &mut String) -> String { let opts = regex_captures(regex, command);