diff --git a/src/main.rs b/src/main.rs index 80558fb..765f4af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,8 @@ +use std::ffi::OsString; use std::fs; use std::env; +use std::path::Path; +use std::path::PathBuf; use colored::Colorize; use gitignore; use path_absolutize::*; @@ -11,58 +14,59 @@ fn main() { return } - let is_ok = fs::metadata(args[1].to_owned()).is_ok(); - if !is_ok { + let path = Path::new(&args[1]); + if !path.exists() { println!("{}", "ERR: Path provided does not exist".red()); return } - let is_dir = fs::metadata(args[1].to_owned()).unwrap().is_dir(); - if !is_dir { + if !path.is_dir() { println!("{}", "ERR: Path provided is not a directory".red()); return } // TODO find safer way to check for gitignore (windows compatible) - let gi_exists = fs::metadata(args[1].to_owned() + "/.gitignore").is_ok(); + let gi_exists = path.join(".gitignore").exists(); if !gi_exists { println!("{}", "WRN: .gitignore not found, may output TODOs in dependencies".yellow()) } let mut todos = vec!(); - if gi_exists { - let gi_str = args[1].to_owned() + "/.gitignore"; - let _p = std::path::Path::new(&gi_str).absolutize().unwrap(); - let gi_str_abs = _p.to_str().unwrap(); - let gi_path = std::path::Path::new(&gi_str_abs); - let gi= gitignore::File::new(gi_path).unwrap(); + let gi_path = path.join(".gitignore"); + let gi_path_abs = gi_path.absolutize().unwrap(); + let gi= gitignore::File::new(&gi_path_abs).unwrap(); iterate_included_files(&mut todos, &gi).unwrap(); } else { - traverse_dir(&args[1], &mut todos).unwrap(); + traverse_dir(&path, &mut todos).unwrap(); } // TODO eventually add option to export to file println!("{:4} {:05} {:20} {:50}", "", "LINE".bold(), "FILE".bold(), "COMMENT".bold()); for todo in todos { - println!("{:4} {:05} {:20} {:50}", "TODO".bold(), todo.line_number.to_string().yellow(), todo.file_name.green(), todo.comment); + println!("{:4} {:05} {:20} {:50}", "TODO".bold(), todo.line_number.to_string().yellow(), todo.file_name.into_string().unwrap().green(), todo.comment); } } -fn traverse_dir(path: &str, todos: &mut Vec) -> Result<(), std::io::Error> { - let objects = fs::read_dir(path.to_owned())?; +fn traverse_dir(path: &Path, todos: &mut Vec) -> Result<(), std::io::Error> { + let objects = fs::read_dir(path)?; 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() { - traverse_dir(obj_str, todos)?; + if obj_path.is_dir() { + traverse_dir(&obj_path, todos)?; } - else if obj_metadata.is_file() && obj_str.ends_with(".py") { // TODO support other files besides .py - get_todos(obj_str, todos)?; + else if obj_path.is_file() { + let extension = match obj_path.extension() { + Some(ext) => { ext.to_owned().into_string().unwrap() } + None => { String::from("") } + }; + + // TODO support other files besides .py + if extension == "py" { + get_todos(&obj_path, todos)?; + } } } @@ -70,26 +74,31 @@ fn traverse_dir(path: &str, todos: &mut Vec) -> Result<(), std::io::Error> } fn iterate_included_files(todos: &mut Vec, gi: &gitignore::File) -> Result<(), std::io::Error> { - for file_path in gi.included_files().unwrap() { - let file_str = file_path.to_str().unwrap(); - if file_str.ends_with(".py") { // TODO support other files besides .py - get_todos(file_str, todos)?; + for obj_path in gi.included_files().unwrap() { + let extension = match obj_path.extension() { + Some(ext) => { ext.to_owned().into_string().unwrap() } + None => { String::from("") } + }; + + // TODO support other files besides .py + if !obj_path.is_dir() && extension == "py" { + get_todos(&obj_path, todos)?; } } Ok(()) } -fn get_todos(path: &str, todos: &mut Vec) -> Result<(), std::io::Error> { - let contents = fs::read_to_string(path)?; +fn get_todos(path: &PathBuf, todos: &mut Vec) -> Result<(), std::io::Error> { + let file_name = path.file_name().to_owned().unwrap(); let mut line_number = 0; - let file_name = path.split("/").last().unwrap(); - for line in contents.lines() { + for line in fs::read_to_string(path)?.lines() { line_number += 1; if line.contains("TODO") { let (_, comment) = line.split_once("TODO").unwrap(); let cleaned_comment = comment.replace(":", "").trim().to_owned(); + todos.push(Todo::new(cleaned_comment, file_name.to_owned(), line_number)) } } @@ -99,12 +108,12 @@ fn get_todos(path: &str, todos: &mut Vec) -> Result<(), std::io::Error> { struct Todo { comment: String, - file_name: String, + file_name: OsString, line_number: u32 } impl Todo { - fn new(comment: String, file_name: String, line_number: u32) -> Todo { + fn new(comment: String, file_name: OsString, line_number: u32) -> Todo { Todo { comment: comment, file_name: file_name,