mod core;
mod utils;
mod cli;
use crate::core::api::{
scan_dirs,
scan_all,
list,
add,
remove_repos,
remove_all,
check_repos,
check_all
};
use crate::utils::{
APP_NAME,
TrackingFile,
handle_error,
path_is_repo
};
use crate::cli::{Cli, Commands};
use std::fs::{self, File};
use std::io::Write as _;
use std::fmt::Write as _;
use clap::Parser;
use colored::Colorize;
#[tokio::main]
async fn main() {
let mut tracking_file = TrackingFile {
path: String::new(),
contents: String::new()
};
let mut home_dir = String::new();
if let Some(home_path) = home::home_dir() {
if let Some(home_path_str) = home_path.to_str() {
home_dir = home_path_str.to_string();
let app_data_dir = format!("{home_dir}/.local/share/{APP_NAME}");
tracking_file.path = format!("{app_data_dir}/tracked");
match fs::create_dir_all(&app_data_dir) {
Ok(()) => (),
Err(e) => handle_error(format!("{app_data_dir}: {e}").as_str(), 1)
};
if let Ok(str) = fs::read_to_string(&tracking_file.path) {
for line in str.lines() {
match path_is_repo(line) {
Ok(is_repo) => {
if is_repo {
if let Err(e) = writeln!(tracking_file.contents, "{line}") {
handle_error(e.to_string().as_str(), 1);
}
}
},
Err(e) => handle_error(e.as_str(), 1)
};
}
match File::create(&tracking_file.path) {
Ok(mut f) => {
match f.write_all(tracking_file.contents.as_bytes()) {
Ok(()) => (),
Err(e) => handle_error(format!("{}: {e}", tracking_file.path).as_str(), 1)
}
},
Err(e) => handle_error(format!("{}: {e}", tracking_file.path).as_str(), 1)
};
}
}
else {
handle_error("Could not obtain the home directory path: the path contains invalid UTF-8 characters", 1);
}
}
else {
handle_error("Could not find the home directory", 1);
}
match Cli::parse().get_command() {
Commands::Scan { dirs, all, hidden, quiet} => {
let result: Result<String, String>;
if *all {
result = scan_all(home_dir, &tracking_file, *hidden);
}
else {
result = scan_dirs(dirs.to_owned(), &tracking_file, *hidden);
}
match result {
Ok(repos) => {
if !*quiet {
if repos.is_empty() {
println!("{APP_NAME}: No untracked repositories found");
}
else {
println!("{APP_NAME}: Found untracked repositories:\n");
print!("{}", repos.bold());
}
}
},
Err(e) => handle_error(&e, 2)
}
},
Commands::List => {
if let Err(e) = list(tracking_file.contents.as_str()) {
handle_error(&e, 3);
}
},
Commands::Add { repos } => {
if let Err(e) = add(repos.to_owned(), &tracking_file) {
handle_error(&e, 4);
}
},
Commands::Rm { repos, all } => {
if *all {
if let Err(e) = remove_all(&tracking_file) {
handle_error(&e, 5);
}
}
else if let Err(e) = remove_repos(repos.to_owned(), &tracking_file) {
handle_error(&e, 5);
}
},
Commands::Check { repos, all, status, remotes } => {
if *all {
if let Err(e) = check_all(&tracking_file, &[*status, *remotes]).await {
handle_error(&e, 6);
}
}
else if let Err(e) = check_repos(repos.to_owned(), &[*status, *remotes]).await {
handle_error(&e, 6);
}
}
};
}