#![allow(clippy::missing_errors_doc)]
#![allow(clippy::missing_panics_doc)]
use std::fs;
use std::path::Path;
use std::process::{self, Command, Stdio};
pub const APP_NAME: &str = env!("CARGO_PKG_NAME");
pub const SPINNER_TICK: u64 = 60;
pub struct TrackingFile {
pub path: String,
pub contents: String
}
#[allow(clippy::must_use_candidate)]
pub fn repo_is_tracked(repo: &str, track_file_contents: &str) -> bool {
let track_file_lines: Vec<&str> = track_file_contents
.lines()
.collect();
track_file_lines.contains(&repo)
}
pub fn path_is_repo(path: &str) -> Result<bool, String> {
let git_status = Command::new("git")
.args(["-C", path, "status"])
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.map_err(|e| format!("git: {e}"))?;
Ok(git_status.success())
}
pub fn repos_valid(repos: &[String]) -> Result<Vec<String>, String> {
let mut repos_abs = Vec::from(repos);
let mut repos_ok = true;
for repo in &mut repos_abs {
if let Ok(p) = Path::new(&repo).try_exists() {
if !p {
eprintln!("{APP_NAME}: Repository '{repo}' does not exist");
repos_ok = false;
continue;
}
}
else {
eprintln!("{APP_NAME}: Cannot check the existance of repository '{repo}'");
repos_ok = false;
continue;
}
match path_is_repo(repo) {
Ok(is_repo) => {
if !is_repo {
eprintln!("{APP_NAME}: '{repo}' is not a git repository");
repos_ok = false;
}
},
Err(e) => return Err(e)
};
if let Some(s) = fs::canonicalize(&repo)
.map_err(|e| format!("{repo}: {e}"))?
.to_str() {
*repo = s.to_string();
}
else {
eprintln!("{APP_NAME}: {repo}: The path contains invalid UTF-8 characters");
repos_ok = false;
}
}
if !repos_ok {
return Err(String::from("Repositories validation failed"));
}
Ok(repos_abs)
}
pub fn handle_error(error: &str, code: i32) {
eprintln!("{APP_NAME}: {error}");
process::exit(code);
}