use std::{io, process::Command};
use eyre::Result;
use thiserror::Error;
use crate::{
config::{Config, CONFIG_FILE_NAME, VERSION},
hint, warning,
};
#[derive(Debug, Error)]
pub enum NotInGitWorktree {
#[error("Failed to run the git command")]
CannotRunGit(#[from] io::Error),
#[error("Not in a Git repository")]
NotInRepo,
#[error("Not inside a Git worktree")]
NotInWorktree,
}
pub fn ensure_in_git_worktree() -> Result<(), NotInGitWorktree> {
let is_inside_work_tree = Command::new("git")
.args(["rev-parse", "--is-inside-work-tree"])
.output()?;
if !is_inside_work_tree.status.success() {
return Err(NotInGitWorktree::NotInRepo);
}
if is_inside_work_tree.stdout == b"true\n" {
Ok(())
} else {
Err(NotInGitWorktree::NotInWorktree)
}
}
pub fn load_config() -> Result<Config> {
let config = Config::load()?;
if config.version != VERSION {
warning!("The configuration in {CONFIG_FILE_NAME} is out of date.");
hint!("You can update it by running `git z update`.");
}
Ok(config)
}
pub fn uncapitalise(s: &str) -> String {
let mut chars = s.chars();
match chars.next() {
None => String::new(),
Some(c) => c.to_lowercase().collect::<String>() + chars.as_str(),
}
}
#[macro_export]
macro_rules! success {
($($arg:tt)*) => {{
use colored::Colorize;
let message = format!($($arg)*).green().bold();
println!("{message}");
}};
}
#[macro_export]
macro_rules! warning {
($($arg:tt)*) => {{
use colored::Colorize;
let message = format!($($arg)*).yellow().bold();
eprintln!("{message}");
}};
}
#[macro_export]
macro_rules! error {
($($arg:tt)*) => {{
use colored::Colorize;
let message = format!($($arg)*);
let message = $crate::command::helpers::uncapitalise(&message);
let message = format!("Error: {message}").red().bold();
eprintln!("{message}");
}};
}
#[macro_export]
macro_rules! hint {
($($arg:tt)*) => {{
use colored::Colorize;
let message = format!($($arg)*).blue();
eprintln!("{message}");
}};
}