use crate::mode::Mode;
use anyhow::{Result, bail};
use clap::Parser;
use std::{fs::OpenOptions, io::Write, path::PathBuf};
#[derive(Parser)]
#[clap(author, version, about, long_about = None)]
pub struct Cli {
pub file_name: Option<String>,
#[arg(short, long, value_enum, default_value_t = Mode::Normal)]
pub mode: Mode,
#[arg(short, long, default_value_t = true)]
pub debug: bool,
}
impl Cli {
pub fn parse_path() -> Result<(Self, Option<PathBuf>)> {
let cli = Self::parse();
match cli.file_name {
Some(ref path) => {
let path = PathBuf::from(path);
if path.is_dir() {
bail!("Orinfar does not support directory navigation");
} else if path.is_file() {
Ok((cli, Some(path)))
} else {
std::fs::write(&path, "")?;
Ok((cli, Some(path)))
}
}
None => Ok((cli, None)),
}
}
}
pub fn try_get_git_hash(path: Option<&PathBuf>) -> Option<String> {
let mut git_hash: Option<String> = None;
if let Some(path) = path {
let path = if path.is_dir() {
path
} else {
path.parent().unwrap()
}
.to_str()
.unwrap();
let git_stem = if path.is_empty() {
String::from(".git")
} else {
format!("{path}/.git")
};
let head_path = format!("{git_stem}/HEAD");
if let Ok(head_str) = std::fs::read_to_string(head_path).map(|s| s.trim().to_string()) {
let head = head_str.split(' ').collect::<Vec<&str>>()[1];
let ref_path = format!("{git_stem}/{head}");
git_hash = std::fs::read_to_string(ref_path)
.ok()
.map(|s| s.trim().chars().take(7).collect::<String>());
}
}
git_hash
}
pub fn log_dir() -> PathBuf {
let base = xdg::BaseDirectories::with_prefix("orinfar");
base.get_state_home().expect("Could not find home")
}
pub fn log_file() -> PathBuf {
log_dir().join("log")
}
pub fn log(contents: &impl ToString) {
let mut file = OpenOptions::new()
.append(true)
.open(log_file())
.expect("unable to open file");
file.write_all(format!("{}\n", contents.to_string()).as_bytes())
.expect("unable to append data");
}
#[macro_export]
macro_rules! log {
($($arg:tt)*) => {
if unsafe { DEBUG } {
log(&format!($($arg)*))
}
};
}