2019-01-23 09:33:51 -05:00
|
|
|
// 2015-edition macros.
|
|
|
|
#[macro_use]
|
|
|
|
extern crate clap;
|
|
|
|
|
2019-01-22 17:01:33 -05:00
|
|
|
use structopt::StructOpt;
|
|
|
|
|
2019-06-14 08:43:21 -04:00
|
|
|
arg_enum! {
|
2019-01-23 09:33:51 -05:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
|
|
|
enum Format {
|
|
|
|
Silent,
|
|
|
|
Brief,
|
|
|
|
Long,
|
|
|
|
Json,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Format {
|
2019-04-16 19:27:55 -04:00
|
|
|
fn report(self) -> defenestrate::report::Report {
|
2019-01-23 09:33:51 -05:00
|
|
|
match self {
|
2019-04-16 19:27:55 -04:00
|
|
|
Format::Silent => defenestrate::report::print_silent,
|
|
|
|
Format::Brief => defenestrate::report::print_brief,
|
|
|
|
Format::Long => defenestrate::report::print_long,
|
|
|
|
Format::Json => defenestrate::report::print_json,
|
2019-01-23 09:33:51 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Format {
|
|
|
|
fn default() -> Self {
|
|
|
|
Format::Long
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-22 17:01:33 -05:00
|
|
|
#[derive(Debug, StructOpt)]
|
|
|
|
struct Options {
|
2019-01-23 09:34:05 -05:00
|
|
|
#[structopt(parse(from_os_str), default_value = ".")]
|
2019-01-22 17:01:33 -05:00
|
|
|
/// Paths to check
|
|
|
|
path: Vec<std::path::PathBuf>,
|
|
|
|
|
2019-06-14 08:43:21 -04:00
|
|
|
#[structopt(
|
|
|
|
long = "format",
|
|
|
|
raw(possible_values = "&Format::variants()", case_insensitive = "true"),
|
|
|
|
default_value = "long"
|
|
|
|
)]
|
2019-01-23 09:33:51 -05:00
|
|
|
pub format: Format,
|
|
|
|
|
2019-06-14 08:43:21 -04:00
|
|
|
#[structopt(short = "j", long = "threads", default_value = "0")]
|
2019-01-22 17:01:33 -05:00
|
|
|
/// The approximate number of threads to use.
|
|
|
|
threads: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Options {
|
|
|
|
pub fn infer(mut self) -> Self {
|
2019-06-14 08:51:22 -04:00
|
|
|
if self.path.len() == 1 && self.path[0].is_file() {
|
|
|
|
self.threads = 1;
|
2019-01-22 17:01:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run() -> Result<(), failure::Error> {
|
|
|
|
let options = Options::from_args().infer();
|
|
|
|
|
2019-04-16 19:27:55 -04:00
|
|
|
let dictionary = defenestrate::Dictionary::new();
|
2019-01-22 17:01:33 -05:00
|
|
|
|
2019-06-14 08:43:21 -04:00
|
|
|
let first_path = &options
|
|
|
|
.path
|
|
|
|
.get(0)
|
|
|
|
.expect("arg parsing enforces at least one");
|
2019-01-22 17:01:33 -05:00
|
|
|
let mut walk = ignore::WalkBuilder::new(first_path);
|
|
|
|
for path in &options.path[1..] {
|
|
|
|
walk.add(path);
|
|
|
|
}
|
|
|
|
walk.threads(options.threads);
|
|
|
|
// TODO Add build_parallel for options.threads != 1
|
|
|
|
for entry in walk.build() {
|
|
|
|
let entry = entry?;
|
|
|
|
if entry.file_type().map(|t| t.is_file()).unwrap_or(true) {
|
2019-04-16 19:27:55 -04:00
|
|
|
defenestrate::process_file(entry.path(), &dictionary, options.format.report())?;
|
2019-01-22 17:01:33 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
run().unwrap();
|
|
|
|
}
|