Skip to content

Commit 6619afb

Browse files
Reimplementing directories scan
1 parent 7a80e03 commit 6619afb

File tree

3 files changed

+87
-66
lines changed

3 files changed

+87
-66
lines changed

src/cli.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ pub struct Args {
3232
short = 'w',
3333
long = "workers",
3434
help = "Number of threads to use for scanning repositories",
35-
default_value_t = 3,
36-
value_parser(clap::value_parser!(u16).range(1..=5)),
35+
default_value_t = 5,
36+
value_parser(clap::value_parser!(u16).range(1..=10)),
3737
required = false
3838
)]
3939
pub workers: u16,
@@ -56,4 +56,11 @@ pub struct Args {
5656
required = false
5757
)]
5858
pub exclude: Option<Vec<String>>,
59+
60+
#[arg(
61+
long = "scan-all",
62+
help = "Scan all git repos, with or without untracked files",
63+
required = false
64+
)]
65+
pub scan_all: bool,
5966
}

src/git_ops.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,47 @@ use git2::{DiffOptions, Repository, StatusOptions};
33
use std::io;
44
use std::io::ErrorKind;
55
use std::path::{Path, PathBuf};
6+
use std::sync::mpsc;
7+
use std::sync::mpsc::Sender;
8+
use threadpool::ThreadPool;
69
use walkdir::{DirEntry, WalkDir};
710

11+
// Check if a directory should be excluded
812
fn is_excluded_dir(entry: &DirEntry, exclude_dirs: &[String]) -> bool {
913
exclude_dirs.iter().any(|dir| entry.path().starts_with(dir))
1014
}
1115

12-
pub fn find_git_repos(start_path: &Path, exclude_dirs: &[String]) -> Vec<PathBuf> {
13-
let mut git_repos = Vec::new();
16+
// Send the path to the channel if it is a Git repository
17+
fn check_and_send_repo(path: PathBuf, tx: Sender<PathBuf>) {
18+
if path.join(".git").exists() {
19+
tx.send(path).unwrap();
20+
}
21+
}
1422

15-
for entry in WalkDir::new(start_path)
16-
.into_iter()
17-
.filter_map(|e| e.ok())
18-
.filter(|e| !is_excluded_dir(e, exclude_dirs))
19-
{
20-
let path = entry.path();
21-
if path.is_dir() && path.join(".git").exists() {
22-
git_repos.push(path.to_path_buf());
23+
// Find Git repositories starting from a given directory using a ThreadPool
24+
pub fn find_git_repos(
25+
start_path: &Path,
26+
exclude_dirs: &[String],
27+
num_threads: usize,
28+
) -> Vec<PathBuf> {
29+
let pool = ThreadPool::new(num_threads); // Create a thread pool with the specified number of threads
30+
let (tx, rx) = mpsc::channel(); // Create a channel to send results from threads to the main thread
31+
32+
// Iterate over all entries in the starting path
33+
for entry in WalkDir::new(start_path).into_iter().filter_map(|e| e.ok()) {
34+
let path = entry.path().to_path_buf();
35+
if path.is_dir() && !is_excluded_dir(&entry, exclude_dirs) {
36+
let tx = tx.clone(); // Clone the sender to be used in the thread
37+
pool.execute(move || {
38+
check_and_send_repo(path, tx); // Check if the directory is a Git repository and send the path if it is
39+
});
2340
}
2441
}
2542

26-
git_repos
43+
drop(tx); // Close the sender side of the channel to indicate no more sends
44+
45+
// Collect all the paths from the receiver into a vector
46+
rx.into_iter().collect()
2747
}
2848

2949
pub fn check_untracked_files(repo_path: &Path) -> Result<Vec<String>, git2::Error> {

src/main.rs

Lines changed: 47 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -39,58 +39,52 @@ fn main() {
3939
let start_path = Path::new(&args.path);
4040
// If user not specify exclude dirs, set it to empty
4141
let exclude_dirs = args.exclude.as_deref().unwrap_or(&[]);
42-
let git_repos = find_git_repos(start_path, exclude_dirs);
42+
let git_repos = find_git_repos(start_path, &exclude_dirs, args.workers as usize);
4343

44-
// Create a thread pool with a limited number of threads
45-
let num_threads: usize = args.workers as usize;
46-
let pool = ThreadPool::new(num_threads);
47-
48-
// Create a channel to send the results back to the main thread
49-
let (tx, rx) = mpsc::channel();
50-
51-
// Spawn a thread for each repo to check for untracked files
52-
for repo_path in git_repos {
53-
let tx = tx.clone();
54-
let repo_path = repo_path.clone();
55-
pool.execute(move || {
56-
match check_untracked_files(&repo_path) {
57-
Ok(untracked_files) => {
58-
if !untracked_files.is_empty() {
59-
// Send the results back to the main thread
60-
tx.send((repo_path.clone(), untracked_files)).unwrap();
61-
}
62-
}
63-
Err(e) => eprintln!("{}: {}", "Error checking repository".red(), e),
64-
}
65-
});
66-
}
67-
68-
// Close the sending side of the channel
69-
drop(tx);
70-
71-
// Print the results as they arrive
72-
let mut has_results = false;
73-
while let Ok((repo_path, untracked_files)) = rx.recv() {
74-
has_results = true;
75-
println_orange!("Untracked files in: {}", repo_path.display());
76-
if !args.summary {
77-
for file in untracked_files {
78-
println_light_orange!(" - {}", file);
79-
if args.diff {
80-
match show_diff(&repo_path, &file) {
81-
Ok(diff) => println!("{}", diff),
82-
Err(e) => eprintln!("{}: {}", "Error showing diff".red(), e),
83-
}
84-
}
85-
}
86-
}
87-
}
88-
89-
// Print a message if no results were found
90-
if !has_results {
91-
println_orange!(
92-
"-----> There are no changes to git in {}",
93-
start_path.display()
94-
);
95-
}
44+
//
45+
// // Spawn a thread for each repo to check for untracked files
46+
// for repo_path in git_repos {
47+
// let tx = tx.clone();
48+
// let repo_path = repo_path.clone();
49+
// pool.execute(move || {
50+
// match check_untracked_files(&repo_path) {
51+
// Ok(untracked_files) => {
52+
// if !untracked_files.is_empty() {
53+
// // Send the results back to the main thread
54+
// tx.send((repo_path.clone(), untracked_files)).unwrap();
55+
// }
56+
// }
57+
// Err(e) => eprintln!("{}: {}", "Error checking repository".red(), e),
58+
// }
59+
// });
60+
// }
61+
//
62+
// // Close the sending side of the channel
63+
// drop(tx);
64+
//
65+
// // Print the results as they arrive
66+
// let mut has_results = false;
67+
// while let Ok((repo_path, untracked_files)) = rx.recv() {
68+
// has_results = true;
69+
// println_orange!("Untracked files in: {}", repo_path.display());
70+
// if !args.summary {
71+
// for file in untracked_files {
72+
// println_light_orange!(" - {}", file);
73+
// if args.diff {
74+
// match show_diff(&repo_path, &file) {
75+
// Ok(diff) => println!("{}", diff),
76+
// Err(e) => eprintln!("{}: {}", "Error showing diff".red(), e),
77+
// }
78+
// }
79+
// }
80+
// }
81+
// }
82+
//
83+
// // Print a message if no results were found
84+
// if !has_results {
85+
// println_orange!(
86+
// "-----> There are no changes to git in {}",
87+
// start_path.display()
88+
// );
89+
// }
9690
}

0 commit comments

Comments
 (0)