diff --git a/Cargo.lock b/Cargo.lock index 5bbbb5c..121beed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,6 +96,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "heck" version = "0.4.1" @@ -151,6 +157,7 @@ name = "todos" version = "0.1.0" dependencies = [ "clap", + "glob", "termcolor", ] diff --git a/Cargo.toml b/Cargo.toml index 55ae5e1..c1ef24e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,4 +9,5 @@ description = "An intuitive system for organizing TODOs in code" [dependencies] clap = { version = "4.4.8", features = ["derive"] } +glob = "0.3.1" termcolor = "1.4.0" diff --git a/src/main.rs b/src/main.rs index 2ba1dff..4c9fdd8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use clap::Parser; -use scan::scan_readme_file; +use scan::{scan_readme_file, add_excludes_from_gitignore}; use crate::entries::Entry; use crate::render::render_entries; use crate::scan::{Stats, scan_dir, scan_todo_file}; @@ -86,8 +86,10 @@ fn main() { scan_readme_file(&readme_path, &mut entries).unwrap(); } + add_excludes_from_gitignore(&root_dir, &mut excludes); + for p in &paths { - scan_dir(p.as_path(), &mut entries, &excludes, &mut stats).unwrap(); + scan_dir(p.as_path(), &mut entries, &mut excludes, &mut stats).unwrap(); } render_entries(entries); diff --git a/src/scan.rs b/src/scan.rs index 9d5306d..d0323ec 100644 --- a/src/scan.rs +++ b/src/scan.rs @@ -1,6 +1,8 @@ +use std::ffi::OsStr; use std::io; use std::fs; use std::path::{Path, PathBuf}; +use glob::glob; const PRIORITY_CHARS: [char; 10] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; @@ -49,6 +51,24 @@ fn clean_line<'a>(line: &'a str, delimiter_word: &str) -> &'a str { .trim(); } +pub fn add_excludes_from_gitignore(base_dir: &PathBuf, excludes: &mut Vec) { + let mut gitignore = base_dir.clone(); + gitignore.push(".gitignore"); + + if ! gitignore.exists() { + return; + } + + for line in std::fs::read_to_string(gitignore).unwrap().lines() { + for path in glob(line).unwrap() { + let mut exclude = base_dir.clone(); + exclude.push(path.unwrap()); + + excludes.push(exclude); + } + } +} + pub fn scan_string(str: String, filename: PathBuf, entries: &mut Vec) { for (line_num, line) in str.lines().enumerate() { if ! line.to_lowercase().contains("todo") { @@ -118,7 +138,7 @@ pub fn scan_file(path: &Path, entries: &mut Vec) -> io::Result<()> { Ok(()) } -pub fn scan_dir(path: &Path, entries: &mut Vec, excludes: &Vec, stats: &mut Stats) -> io::Result<()> { +pub fn scan_dir(path: &Path, entries: &mut Vec, excludes: &mut Vec, stats: &mut Stats) -> io::Result<()> { stats.visited_folders += 1; 'entry: for entry in fs::read_dir(path)? { @@ -126,10 +146,14 @@ pub fn scan_dir(path: &Path, entries: &mut Vec, excludes: &Vec, let path = entry.path(); if path.components().last().unwrap().as_os_str().to_string_lossy().starts_with('.') { + if path.file_name().unwrap() == OsStr::new(".gitignore") { + add_excludes_from_gitignore(&path.parent().unwrap().to_path_buf(), excludes); + } + continue; } - for exclude in excludes { + for exclude in &*excludes { if path == *exclude { continue 'entry; }