|
1 | 1 | use clap::{arg, command, Parser, ValueEnum}; |
2 | 2 | use keepsorted::process_file; |
3 | 3 | use std::io; |
4 | | -use std::path::Path; |
| 4 | +use std::path::{Path, PathBuf}; |
5 | 5 | use std::process::{self, Command}; |
6 | 6 |
|
7 | 7 | /// Exit code used when the command is invoked incorrectly. |
@@ -110,6 +110,10 @@ struct Args { |
110 | 110 | )] |
111 | 111 | positional_path: Option<String>, |
112 | 112 |
|
| 113 | + /// Recursively traverse directories for files |
| 114 | + #[arg(short = 'r', long, help = "Process directories recursively")] |
| 115 | + recursive: bool, |
| 116 | + |
113 | 117 | #[arg( |
114 | 118 | short = 'f', |
115 | 119 | long, |
@@ -190,12 +194,29 @@ fn main() { |
190 | 194 | let mut exit_code = 0; |
191 | 195 |
|
192 | 196 | if path.is_dir() { |
193 | | - eprintln!( |
194 | | - "{}: read {}: is a directory", |
195 | | - env!("CARGO_PKG_NAME"), |
196 | | - path.display() |
197 | | - ); |
198 | | - process::exit(EXIT_USAGE_ERROR); |
| 197 | + if !args.recursive { |
| 198 | + eprintln!( |
| 199 | + "{}: read {}: is a directory", |
| 200 | + env!("CARGO_PKG_NAME"), |
| 201 | + path.display() |
| 202 | + ); |
| 203 | + process::exit(EXIT_USAGE_ERROR); |
| 204 | + } |
| 205 | + let mut files = Vec::new(); |
| 206 | + if let Err(e) = collect_files(path, &mut files) { |
| 207 | + eprintln!( |
| 208 | + "{}: failed to read directory {}: {}", |
| 209 | + env!("CARGO_PKG_NAME"), |
| 210 | + path.display(), |
| 211 | + e |
| 212 | + ); |
| 213 | + process::exit(EXIT_RUNTIME_ERROR); |
| 214 | + } |
| 215 | + for file in files { |
| 216 | + if !handle_file(&file, &features, mode, args.diff_command.as_deref()) { |
| 217 | + exit_code = EXIT_CHECK_FAILED; |
| 218 | + } |
| 219 | + } |
199 | 220 | } else if !handle_file(path, &features, mode, args.diff_command.as_deref()) { |
200 | 221 | exit_code = EXIT_CHECK_FAILED; |
201 | 222 | } |
@@ -335,3 +356,16 @@ fn handle_file(path: &Path, features: &[Feature], mode: Mode, diff_command: Opti |
335 | 356 | } |
336 | 357 | } |
337 | 358 | } |
| 359 | + |
| 360 | +fn collect_files(dir: &Path, out: &mut Vec<PathBuf>) -> io::Result<()> { |
| 361 | + for entry in std::fs::read_dir(dir)? { |
| 362 | + let entry = entry?; |
| 363 | + let path = entry.path(); |
| 364 | + if path.is_dir() { |
| 365 | + collect_files(&path, out)?; |
| 366 | + } else if path.is_file() { |
| 367 | + out.push(path); |
| 368 | + } |
| 369 | + } |
| 370 | + Ok(()) |
| 371 | +} |
0 commit comments