From ead64c0bd39ab2a99bb395b40eb48626b7b6078e Mon Sep 17 00:00:00 2001 From: elipeter Date: Tue, 17 Jun 2025 17:42:41 +0200 Subject: [PATCH] Refactor project and index handling - Standardized formatting across key functions in `project.rs`. - Updated `index::handle` and `build_index` to incorporate the `config` parameter. - Improved index-building logic to include project details and enhanced issue tracking. - Replaced variable names like `files` with `paths` for clarity in `scan.rs`. --- src/commands/index.rs | 37 ++++++++++++++++++++++++++++++---- src/commands/mod.rs | 2 +- src/commands/scan.rs | 17 ++++++++-------- src/utils/project.rs | 46 +++++++++++++++++++++---------------------- 4 files changed, 66 insertions(+), 36 deletions(-) diff --git a/src/commands/index.rs b/src/commands/index.rs index 03e7e022..913e430c 100644 --- a/src/commands/index.rs +++ b/src/commands/index.rs @@ -1,10 +1,15 @@ use std::fs; use crate::cli::IndexAction; +use crate::database::index::{Indexer, IssueRow}; +use crate::patterns::Severity; +use crate::utils::Config; use crate::utils::project::get_project_info; +use crate::walk::spawn_senders; pub fn handle( action: IndexAction, database_dir: &std::path::Path, + config: &Config, ) -> Result<(), Box> { match action { IndexAction::Build { path, force } => { @@ -12,8 +17,7 @@ pub fn handle( let (project_name, db_path) = get_project_info(&build_path, database_dir)?; if force || !db_path.exists() { - println!("Building index for: {}", project_name); - build_index(&build_path, &db_path)?; + build_index(&project_name, &build_path, &db_path, config)?; println!("Index built: {}", db_path.display()); } else { println!("Index already exists. Use --force to rebuild."); @@ -38,10 +42,35 @@ pub fn handle( } pub fn build_index( - _project_path: &std::path::Path, + project_name: &str, + project_path: &std::path::Path, db_path: &std::path::Path, + config: &Config, ) -> Result<(), Box> { - // TODO: Implement actual index building + tracing::debug!("Building index for: {}", project_name); fs::File::create(db_path)?; + + let mut indexer = Indexer::new(&project_name, &db_path)?; + let rx = spawn_senders(project_path, config); + for path in rx.iter().flatten() { + let issues = crate::commands::scan::run_rules_on_file(&path, config)?; + let file_id = indexer.upsert_file(&path)?; + + let issue_rows: Vec = issues + .iter() + .map(|d| IssueRow { + rule_id: d.id.as_ref(), + severity: match d.severity { + Severity::High => "HIGH", + Severity::Medium => "MEDIUM", + Severity::Low => "LOW", + }, + line: d.line as i64, + col: d.col as i64, + }) + .collect(); + + indexer.replace_issues(file_id, issue_rows)?; + } Ok(()) } \ No newline at end of file diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 6d81a9e4..c0d80f38 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -17,7 +17,7 @@ pub fn handle_command( scan::handle(&path, no_index, rebuild_index, format, high_only, database_dir, config) } Commands::Index { action } => { - index::handle(action, database_dir) + index::handle(action, database_dir, config) } Commands::List { verbose } => { list::handle(verbose, database_dir) diff --git a/src/commands/scan.rs b/src/commands/scan.rs index a9c7d3b9..2b7bfe76 100644 --- a/src/commands/scan.rs +++ b/src/commands/scan.rs @@ -40,7 +40,8 @@ pub fn handle( diags = scan_filesystem(&scan_path, config)?; } else { if rebuild_index || !db_path.exists() { - crate::commands::index::build_index(&scan_path, &db_path)?; + tracing::debug!("Scanning filesystem index filesystem"); + crate::commands::index::build_index(&project_name,&scan_path, &db_path, config)?; } diags = scan_with_index(&project_name, &db_path, config, &mut indexer)?; } @@ -90,12 +91,12 @@ fn scan_with_index( cfg: &Config, indexer: &mut Indexer, ) -> Result, Box> { - let files = indexer.get_files(project).unwrap_or_default(); + let paths = indexer.get_files(project).unwrap_or_default(); let mut issues: Vec = Vec::new(); - for file in files { - if indexer.should_scan(&file)? { - let mut diags = run_rules_on_file(&file, cfg)?; - let file_id = indexer.upsert_file(&file)?; + for path in paths { + if indexer.should_scan(&path)? { + let mut diags = run_rules_on_file(&path, cfg)?; + let file_id = indexer.upsert_file(&path)?; let issue_rows: Vec = diags .iter() @@ -115,7 +116,7 @@ fn scan_with_index( issues.append(&mut diags); continue; } - issues.append(&mut indexer.get_issues_from_file(&file)?); + issues.append(&mut indexer.get_issues_from_file(&path)?); } Ok(issues) } @@ -123,7 +124,7 @@ fn scan_with_index( // -------------------------------------------------------------------------------------------- // Tree‑sitter‑based rule runner – returns a Vec // -------------------------------------------------------------------------------------------- -fn run_rules_on_file( +pub(crate) fn run_rules_on_file( path: &Path, cfg: &Config, ) -> Result, Box> { diff --git a/src/utils/project.rs b/src/utils/project.rs index c53cf256..145ef4d0 100644 --- a/src/utils/project.rs +++ b/src/utils/project.rs @@ -3,29 +3,29 @@ use std::path::{Path, PathBuf}; pub fn get_project_info( project_path: &Path, config_dir: &Path, -) -> Result<(String, PathBuf), Box> { - let project_name = project_path - .file_name() - .and_then(|name| name.to_str()) - .ok_or("Unable to determine project name")?; - - let db_name = sanitize_project_name(project_name); - let db_path = config_dir.join(format!("{}.sqlite", db_name)); - - Ok((project_name.to_string(), db_path)) +) -> Result<(String, PathBuf), Box> { + let project_name = project_path + .file_name() + .and_then(|name| name.to_str()) + .ok_or("Unable to determine project name")?; + + let db_name = sanitize_project_name(project_name); + let db_path = config_dir.join(format!("{}.sqlite", db_name)); + + Ok((project_name.to_string(), db_path)) } -pub fn sanitize_project_name(name: &str) -> String { - name.to_lowercase() - .chars() - .map(|c| match c { - ' ' | '\t' | '\n' | '\r' => '_', - c if c.is_alphanumeric() || c == '_' || c == '-' => c, - _ => '_' - }) - .collect::() - .split('_') - .filter(|s| !s.is_empty()) - .collect::>() - .join("_") +pub fn sanitize_project_name(name: &str) -> String { + name.to_lowercase() + .chars() + .map(|c| match c { + ' ' | '\t' | '\n' | '\r' => '_', + c if c.is_alphanumeric() || c == '_' || c == '-' => c, + _ => '_' + }) + .collect::() + .split('_') + .filter(|s| !s.is_empty()) + .collect::>() + .join("_") } \ No newline at end of file