1use std::process::Command;
2use std::str;
3
4use camino::{Utf8Path, Utf8PathBuf};
5
6use crate::Error;
7
8pub fn config_dir() -> crate::Result<Utf8PathBuf> {
10 let config_dir = dirs_next::config_dir()
11 .ok_or_else(|| Error::InvalidValue("failed getting config directory".to_string()))?;
12 let config_dir = Utf8PathBuf::from_path_buf(config_dir)
13 .map_err(|e| Error::InvalidValue(format!("invalid bugbite config directory: {e:?}")))?;
14
15 Ok(config_dir.join("bugbite"))
16}
17
18pub fn current_dir() -> crate::Result<Utf8PathBuf> {
20 Utf8PathBuf::from(".")
21 .canonicalize_utf8()
22 .map_err(|e| Error::InvalidValue(format!("invalid current working directory: {e}")))
23}
24
25pub(crate) fn get_mime_type<P: AsRef<Utf8Path>>(path: P) -> crate::Result<String> {
30 let output = Command::new("file")
31 .args(["-b", "--mime-type"])
32 .arg(path.as_ref())
33 .output()?;
34
35 match str::from_utf8(&output.stdout).map(|s| s.trim()) {
36 Ok(s) if !s.is_empty() => Ok(s.to_string()),
37 _ => Err(Error::InvalidValue(
38 "file command returned invalid value".to_string(),
39 )),
40 }
41}
42
43#[macro_export]
47macro_rules! is_terminal {
48 ($fd:expr) => {
49 std::io::IsTerminal::is_terminal($fd)
50 || (cfg!(feature = "test") && std::env::var("BUGBITE_IS_TERMINAL").is_ok())
51 };
52}
53pub use is_terminal;