diff --git a/Cargo.toml b/Cargo.toml index b2333d5..ff31a64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -colored = "2.0.0" \ No newline at end of file +colored = "2.0.0" +gitignore = "1.0.7" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 8655505..e017e06 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,11 @@ use std::fs; use std::env; use colored::Colorize; +use gitignore; fn main() { let args: Vec = env::args().collect(); - if args.len() != 2 { + if args.len() <= 1{ println!("{}", "ERR: Invalid number of arguments provided".red()); return } @@ -21,30 +22,50 @@ fn main() { return } + // TODO: find safer way to check for gitignore + let gi_exists = fs::metadata(args[1].to_owned() + "/.gitignore").is_ok(); + if !gi_exists { + println!("{}", "WRN: .gitignore not found, may output TODOs in dependencies".yellow()) + } + let mut todos = vec!(); - traverse_dir(&args[1], &mut todos).unwrap(); + + if gi_exists { + let gi_str = args[1].to_owned() + "/.gitignore"; + let gi_path = std::path::Path::new(&gi_str); + let gi= gitignore::File::new(gi_path).unwrap(); + traverse_dir(&args[1], &mut todos, Some(&gi)).unwrap(); + } + else { + traverse_dir(&args[1], &mut todos, None).unwrap(); + } + for todo in todos { println!("TODO: {}", todo.green()); } } -fn traverse_dir(path: &str, todos: &mut Vec) -> Result<(), std::io::Error> { +fn traverse_dir(path: &str, todos: &mut Vec, gi_option: Option<&gitignore::File>) -> Result<(), std::io::Error> { let objects = fs::read_dir(path.to_owned())?; for result in objects { let obj_path = result?.path(); let obj_str = obj_path.to_str().unwrap(); let obj_metadata = fs::metadata(obj_str)?; - - if obj_metadata.is_dir() { - // println!("DIRC: {}", obj_str.yellow()); - traverse_dir(obj_str, todos)?; - } - else if obj_metadata.is_file() { - if obj_str.ends_with(".py") { - // println!("FILE: {}", obj_str.yellow()); - get_todos(obj_str, todos)?; + + let is_excluded = match gi_option { + Some(gi) => { + let dir_path = std::path::Path::new(obj_str); + gi.is_excluded(dir_path).unwrap() } + None => { false } + }; + + if !is_excluded && obj_metadata.is_dir() { + traverse_dir(obj_str, todos, gi_option)?; + } + else if !is_excluded && obj_metadata.is_file() && obj_str.ends_with(".py") { + get_todos(obj_str, todos)?; } }