Skip to content

Commit bbca886

Browse files
committed
feat: Connect --sort CLI arg to work with -x
1 parent 6511a2f commit bbca886

1 file changed

Lines changed: 42 additions & 1 deletion

File tree

src/walk.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::error::print_error;
2121
use crate::exec;
2222
use crate::exit_codes::{ExitCode, merge_exitcodes};
2323
use crate::filesystem;
24+
use crate::filter::SortKey;
2425
use crate::output;
2526

2627
/// The receiver thread can either be buffering results or directly streaming to the console.
@@ -411,7 +412,18 @@ impl WorkerState {
411412
// This will be set to `Some` if the `--exec` argument was supplied.
412413
if let Some(ref cmd) = config.command {
413414
if cmd.in_batch_mode() {
414-
exec::batch(rx.into_iter().flatten(), cmd, config)
415+
let mut results: Vec<WorkerResult> = rx.into_iter().flatten().collect();
416+
if let Some(sort_key) = config.sort_key {
417+
sort_worker_results(&mut results, sort_key);
418+
}
419+
exec::batch(results.into_iter(), cmd, config)
420+
} else if let Some(sort_key) = config.sort_key {
421+
// With --sort, we must collect all results before dispatching,
422+
// and run sequentially so the order is preserved.
423+
424+
let mut results: Vec<WorkerResult> = rx.into_iter().flatten().collect();
425+
sort_worker_results(&mut results, sort_key);
426+
return exec::job(results.into_iter(), cmd, config);
415427
} else {
416428
thread::scope(|scope| {
417429
// Each spawned job will store its thread handle in here.
@@ -663,6 +675,35 @@ impl WorkerState {
663675
}
664676
}
665677

678+
fn sort_worker_results(results: &mut Vec<WorkerResult>, sort_key: SortKey) {
679+
results.sort_by(|a, b| {
680+
// Errors sort to the end; two errors are considered equal
681+
let (WorkerResult::Entry(a), WorkerResult::Entry(b)) = (a, b) else {
682+
return match (a, b) {
683+
(WorkerResult::Error(_), WorkerResult::Entry(_)) => std::cmp::Ordering::Greater,
684+
(WorkerResult::Entry(_), WorkerResult::Error(_)) => std::cmp::Ordering::Less,
685+
_ => std::cmp::Ordering::Equal,
686+
};
687+
};
688+
689+
match sort_key {
690+
SortKey::Path => a.path().cmp(b.path()),
691+
SortKey::Size => {
692+
let size = |e: &DirEntry| e.metadata().map(|m| m.len()).unwrap_or(0);
693+
size(a).cmp(&size(b))
694+
}
695+
SortKey::Created => {
696+
let time = |e: &DirEntry| e.metadata().and_then(|m| m.created().ok());
697+
time(a).cmp(&time(b))
698+
}
699+
SortKey::Modified => {
700+
let time = |e: &DirEntry| e.metadata().and_then(|m| m.modified().ok());
701+
time(a).cmp(&time(b))
702+
}
703+
}
704+
});
705+
}
706+
666707
fn search_str_for_entry<'a>(
667708
entry_path: &'a std::path::Path,
668709
full_path_base: Option<&std::path::Path>,

0 commit comments

Comments
 (0)