diff --git a/Cargo.lock b/Cargo.lock index 9fd1e6e4..ba760651 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2399,6 +2399,7 @@ dependencies = [ "log", "lsp-server", "lsp-types", + "rayon", "serde", "serde_json", "simplelog", diff --git a/Cargo.toml b/Cargo.toml index 426a3607..30a96322 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,6 +72,7 @@ url = "2.5.4" crossbeam-channel = "0.5.15" crossbeam-utils = "0.8.21" jod-thread = "0.1.2" +rayon = "1" libc = "0.2.171" tracing = "0.1.40" rustc-hash = "2.1.1" diff --git a/crates/squawk/Cargo.toml b/crates/squawk/Cargo.toml index 1406347d..36e7f063 100644 --- a/crates/squawk/Cargo.toml +++ b/crates/squawk/Cargo.toml @@ -34,6 +34,7 @@ squawk-server.workspace = true squawk-thread.workspace = true toml.workspace = true glob.workspace = true +rayon.workspace = true anyhow.workspace = true annotate-snippets.workspace = true line-index.workspace = true diff --git a/crates/squawk/src/reporter.rs b/crates/squawk/src/reporter.rs index f840e7bc..b3820ce0 100644 --- a/crates/squawk/src/reporter.rs +++ b/crates/squawk/src/reporter.rs @@ -4,6 +4,7 @@ use console::style; use line_index::LineIndex; use line_index::TextRange; use log::info; +use rayon::prelude::*; use serde::Serialize; use squawk_linter::{Fix, Linter, Rule, Version}; use squawk_syntax::SourceFile; @@ -151,44 +152,45 @@ pub(crate) struct LintArgs { } pub fn lint_files(args: &LintArgs) -> Result> { - let mut violations = vec![]; match &args.input { Input::Stdin(stdin) => { info!("reading content from stdin"); let sql = sql_from_stdin()?; - // ignore stdin if it's empty. if sql.trim().is_empty() { info!("ignoring empty stdin"); - } else { - let path = stdin.path.clone().unwrap_or_else(|| "stdin".into()); - let content = check_sql( - &sql, - &path, - &args.included_rules, - &args.excluded_rules, - args.pg_version, - args.assume_in_transaction, - ); - violations.push(content); + return Ok(vec![]); } + let path = stdin.path.clone().unwrap_or_else(|| "stdin".into()); + let content = check_sql( + &sql, + &path, + &args.included_rules, + &args.excluded_rules, + args.pg_version, + args.assume_in_transaction, + ); + Ok(vec![content]) } Input::Paths(path_bufs) => { - for path in path_bufs { - info!("checking file path: {}", path.display()); - let sql = sql_from_path(path)?; - let content = check_sql( - &sql, - path.to_str().unwrap(), - &args.included_rules, - &args.excluded_rules, - args.pg_version, - args.assume_in_transaction, - ); - violations.push(content); - } + let mut reports: Vec = path_bufs + .par_iter() + .map(|path| { + info!("checking file path: {}", path.display()); + let sql = sql_from_path(path)?; + Ok(check_sql( + &sql, + path.to_str().unwrap(), + &args.included_rules, + &args.excluded_rules, + args.pg_version, + args.assume_in_transaction, + )) + }) + .collect::>>()?; + reports.sort_by(|a, b| a.filename.cmp(&b.filename)); + Ok(reports) } } - Ok(violations) } pub fn lint_and_report(f: &mut W, args: LintArgs) -> Result { @@ -460,6 +462,7 @@ fn fmt_gitlab(f: &mut W, reports: Vec) -> Result<()> #[derive(Debug)] pub struct CheckReport { + // TODO: rename this to path pub filename: String, pub sql: String, pub violations: Vec,