use std::{path::PathBuf, fs, sync::{Arc, Mutex}}; use rowan::ast::AstNode; use threadpool::ThreadPool; use crate::{status_reporter::*, queries::{SyntaxNode, Parse}, parse_nexp, apply_changes}; #[allow(unreachable_code, unused)] pub fn batchmode(tasks: Vec, query: Parse, debug: bool) { fn do_task(path: PathBuf, query: Parse, debug: bool) -> anyhow::Result<(PathBuf, Option)> { let (content, nexp) = match parse_nexp(&path) { Err(e) => { anyhow::bail!("could not parse file {path:?}") }, Ok(exp) => exp }; let (changes, _) = query.apply(&content, nexp.syntax().clone())?; let changed = apply_changes(&content, changes, debug); Ok((path, if changed != content { Some(changed) } else { None })) } let pool = ThreadPool::new(16); let results = Arc::new(Mutex::new(vec![])); let printer = Arc::new(StatusReport::new(tasks.len(), tasks.len())); for path in tasks { pool.execute({ let results = Arc::clone(&results); let printer = Arc::clone(&printer); let query = query.clone(); move || { printer.enter_file(&format!("{path:?}")); let result = do_task(path, query, debug); results.lock().unwrap().push(result); } }); } pool.join(); println!("\n\nSummary:"); let mut c_errors = 0; let mut c_total = 0; let mut c_changes = 0; for r in results.lock().unwrap().iter() { match r { Err(e) => { println!(" {}", e); c_errors += 1; }, Ok((_, Some(_))) => c_changes += 1, _ => () } c_total += 1; } println!("\n ({c_total} sites total, {c_errors} errors, generated {} edits)", c_changes); let edits: Vec<_> = Arc::into_inner(results).unwrap().into_inner().unwrap() .into_iter() .filter_map(|r| r.ok()) .collect(); println!("applying changes ..."); for (filename, content) in edits { if let Some(content) = content { fs::write(&filename, content.as_bytes()).unwrap(); } } }