use std::path::{Path, PathBuf};
use anyhow::Result;
use crate::git;
macro_rules! domain_bail {
($($arg:tt)*) => {
return Err($crate::DomainError(format!($($arg)*)).into())
};
}
pub(crate) use domain_bail;
pub(crate) fn is_quiet() -> bool {
crate::QUIET.load(std::sync::atomic::Ordering::Relaxed)
}
pub(crate) fn tickets_dir() -> Result<PathBuf> {
let cwd = std::env::current_dir()?;
let root = git::repo_root(&cwd)?;
let dir = root.join(".tickets");
if !dir.is_dir() {
domain_bail!("no .tickets/ directory in {}", root.display());
}
Ok(dir)
}
pub(crate) fn project_config(tickets_dir: &Path) -> crate::config::ProjectConfig {
let cfg = crate::config::ProjectConfig::load(tickets_dir);
for key in &cfg.unknown_keys {
eprintln!(
"warning: unknown config key {:?} in .tickets/config.toml",
key
);
}
cfg
}
pub(crate) fn success_msg(verb: &str, id: &str, slug: &str, detail: &str) -> String {
format!(
"{} {} {} {} ({})",
crate::color::sym_ok(),
verb,
id,
slug,
detail
)
}
pub(crate) fn slug_from_filename(path: &Path) -> String {
let name = path
.file_name()
.unwrap_or_default()
.to_string_lossy()
.to_string();
if let Some(pos) = name.find('-') {
name[pos + 1..].trim_end_matches(".md").to_string()
} else {
name.trim_end_matches(".md").to_string()
}
}