ux: show scan/fix progress
This commit is contained in:
@@ -296,6 +296,10 @@ fn handle_scan(args: ScanArgs, common: &CommonArgs) -> Result<i32> {
|
|||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !config.report.json {
|
||||||
|
eprintln!("Scanning {} file(s)...", files.len());
|
||||||
|
}
|
||||||
|
|
||||||
let batch = run_scans(files, &config, &ruleset)?;
|
let batch = run_scans(files, &config, &ruleset)?;
|
||||||
let scans = batch.scans;
|
let scans = batch.scans;
|
||||||
let has_issues = scans.iter().any(|scan| !scan.issues.is_empty());
|
let has_issues = scans.iter().any(|scan| !scan.issues.is_empty());
|
||||||
@@ -372,6 +376,14 @@ fn handle_fix(args: FixArgs, common: &CommonArgs) -> Result<i32> {
|
|||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !config.report.json {
|
||||||
|
if args.dry_run {
|
||||||
|
eprintln!("Planning fixes for {} file(s)...", files.len());
|
||||||
|
} else {
|
||||||
|
eprintln!("Fixing {} file(s)...", files.len());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let (scans, fixes, errors) = run_fixes(files, &config, &ruleset, args.dry_run)?;
|
let (scans, fixes, errors) = run_fixes(files, &config, &ruleset, args.dry_run)?;
|
||||||
let fix_failed = fixes.iter().any(|fix| fix.applied && !fix.success);
|
let fix_failed = fixes.iter().any(|fix| fix.applied && !fix.success);
|
||||||
let has_issues = scans.iter().any(|scan| !scan.issues.is_empty());
|
let has_issues = scans.iter().any(|scan| !scan.issues.is_empty());
|
||||||
@@ -417,18 +429,27 @@ fn run_scans(files: Vec<PathBuf>, config: &Config, ruleset: &RuleSet) -> Result<
|
|||||||
};
|
};
|
||||||
|
|
||||||
let errors = AtomicUsize::new(0);
|
let errors = AtomicUsize::new(0);
|
||||||
|
let started = AtomicUsize::new(0);
|
||||||
|
let total = files.len();
|
||||||
|
let show_progress = !config.report.json;
|
||||||
|
|
||||||
let scans = if let Some(jobs) = jobs {
|
let scans = if let Some(jobs) = jobs {
|
||||||
let pool = ThreadPoolBuilder::new().num_threads(jobs).build()?;
|
let pool = ThreadPoolBuilder::new().num_threads(jobs).build()?;
|
||||||
pool.install(|| {
|
pool.install(|| {
|
||||||
files
|
files
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.filter_map(|path| match scan_file(path, config, ruleset) {
|
.filter_map(|path| {
|
||||||
Ok(scan) => Some(scan),
|
let idx = started.fetch_add(1, Ordering::SeqCst) + 1;
|
||||||
Err(err) => {
|
if show_progress {
|
||||||
eprintln!("[ERROR] {}: {}", path.display(), err);
|
eprintln!("[SCAN {}/{}] {}", idx, total, path.display());
|
||||||
errors.fetch_add(1, Ordering::SeqCst);
|
}
|
||||||
None
|
match scan_file(path, config, ruleset) {
|
||||||
|
Ok(scan) => Some(scan),
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("[ERROR] {}: {}", path.display(), err);
|
||||||
|
errors.fetch_add(1, Ordering::SeqCst);
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
@@ -436,12 +457,18 @@ fn run_scans(files: Vec<PathBuf>, config: &Config, ruleset: &RuleSet) -> Result<
|
|||||||
} else {
|
} else {
|
||||||
files
|
files
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|path| match scan_file(path, config, ruleset) {
|
.filter_map(|path| {
|
||||||
Ok(scan) => Some(scan),
|
let idx = started.fetch_add(1, Ordering::SeqCst) + 1;
|
||||||
Err(err) => {
|
if show_progress {
|
||||||
eprintln!("[ERROR] {}: {}", path.display(), err);
|
eprintln!("[SCAN {}/{}] {}", idx, total, path.display());
|
||||||
errors.fetch_add(1, Ordering::SeqCst);
|
}
|
||||||
None
|
match scan_file(path, config, ruleset) {
|
||||||
|
Ok(scan) => Some(scan),
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("[ERROR] {}: {}", path.display(), err);
|
||||||
|
errors.fetch_add(1, Ordering::SeqCst);
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
@@ -482,8 +509,15 @@ fn process_fix_batch(
|
|||||||
let mut scans = Vec::new();
|
let mut scans = Vec::new();
|
||||||
let mut fixes = Vec::new();
|
let mut fixes = Vec::new();
|
||||||
let mut errors = 0usize;
|
let mut errors = 0usize;
|
||||||
|
let total = files.len();
|
||||||
|
let show_progress = !config.report.json;
|
||||||
|
let mut idx = 0usize;
|
||||||
|
|
||||||
for path in files {
|
for path in files {
|
||||||
|
idx += 1;
|
||||||
|
if show_progress {
|
||||||
|
eprintln!("[FIX {}/{}] {}", idx, total, path.display());
|
||||||
|
}
|
||||||
let scan = match scan_file(&path, config, ruleset) {
|
let scan = match scan_file(&path, config, ruleset) {
|
||||||
Ok(scan) => scan,
|
Ok(scan) => scan,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -522,9 +556,16 @@ fn process_fix_batch_parallel(
|
|||||||
dry_run: bool,
|
dry_run: bool,
|
||||||
) -> Result<(Vec<ScanOutcome>, Vec<FixOutcome>, usize)> {
|
) -> Result<(Vec<ScanOutcome>, Vec<FixOutcome>, usize)> {
|
||||||
let errors = AtomicUsize::new(0);
|
let errors = AtomicUsize::new(0);
|
||||||
|
let started = AtomicUsize::new(0);
|
||||||
|
let total = files.len();
|
||||||
|
let show_progress = !config.report.json;
|
||||||
let results = files
|
let results = files
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.filter_map(|path| {
|
.filter_map(|path| {
|
||||||
|
let idx = started.fetch_add(1, Ordering::SeqCst) + 1;
|
||||||
|
if show_progress {
|
||||||
|
eprintln!("[FIX {}/{}] {}", idx, total, path.display());
|
||||||
|
}
|
||||||
let scan = match scan_file(path, config, ruleset) {
|
let scan = match scan_file(path, config, ruleset) {
|
||||||
Ok(scan) => scan,
|
Ok(scan) => scan,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -560,6 +601,9 @@ fn process_fix_batch_parallel(
|
|||||||
fn watch_scan(paths: Vec<PathBuf>, config: &Config, ruleset: &RuleSet) -> Result<()> {
|
fn watch_scan(paths: Vec<PathBuf>, config: &Config, ruleset: &RuleSet) -> Result<()> {
|
||||||
println!("Watch mode enabled. Waiting for files to settle...");
|
println!("Watch mode enabled. Waiting for files to settle...");
|
||||||
watch::watch_paths(&paths, config, |path| {
|
watch::watch_paths(&paths, config, |path| {
|
||||||
|
if !config.report.json {
|
||||||
|
eprintln!("[SCAN] {}", path.display());
|
||||||
|
}
|
||||||
match scan_file(&path, config, ruleset) {
|
match scan_file(&path, config, ruleset) {
|
||||||
Ok(scan) => {
|
Ok(scan) => {
|
||||||
println!("{}", render_scan_line(&scan));
|
println!("{}", render_scan_line(&scan));
|
||||||
@@ -574,6 +618,9 @@ fn watch_scan(paths: Vec<PathBuf>, config: &Config, ruleset: &RuleSet) -> Result
|
|||||||
fn watch_fix(paths: Vec<PathBuf>, config: &Config, ruleset: &RuleSet, dry_run: bool) -> Result<()> {
|
fn watch_fix(paths: Vec<PathBuf>, config: &Config, ruleset: &RuleSet, dry_run: bool) -> Result<()> {
|
||||||
println!("Watch mode enabled. Waiting for files to settle...");
|
println!("Watch mode enabled. Waiting for files to settle...");
|
||||||
watch::watch_paths(&paths, config, |path| {
|
watch::watch_paths(&paths, config, |path| {
|
||||||
|
if !config.report.json {
|
||||||
|
eprintln!("[FIX] {}", path.display());
|
||||||
|
}
|
||||||
match scan_file(&path, config, ruleset) {
|
match scan_file(&path, config, ruleset) {
|
||||||
Ok(scan) => {
|
Ok(scan) => {
|
||||||
let plan = fix::planner::plan_fix(&scan.issues, config.repair.policy);
|
let plan = fix::planner::plan_fix(&scan.issues, config.repair.policy);
|
||||||
|
|||||||
Reference in New Issue
Block a user