Skip to main content

bugbite/
utils.rs

1use std::process::Command;
2use std::str;
3
4use camino::{Utf8Path, Utf8PathBuf};
5
6use crate::Error;
7
8/// Get the user config directory for bugbite.
9pub 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
18/// Get the current working directory as an absolute [`Utf8PathBuf`].
19pub 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
25/// Try to get the MIME type of a file path using the `file` utility.
26///
27/// Note that `file` can misidentify plain text file types as various text/* subtypes depending
28/// on formatting within the file.
29pub(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/// Return true if a given file descriptor is a terminal/tty, otherwise false.
44///
45/// Allows overriding the return value for testing purposes.
46#[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;