use std::{env, path::Path};
#[derive(Debug, PartialEq, Eq)]
pub enum InstallationMethod {
Installer,
Cargo,
Nix,
Homebrew,
Source,
Unknown(Option<String>),
}
pub fn detect_installation_method(data_dir: impl AsRef<Path>) -> InstallationMethod {
let current_exe = match env::current_exe() {
Ok(path) => path,
Err(_) => return InstallationMethod::Unknown(None),
};
detect_installation_method_inner(¤t_exe, data_dir.as_ref())
}
fn detect_installation_method_inner(current_exe: &Path, data_dir: &Path) -> InstallationMethod {
let installer_bin_path = data_dir.join("bin");
if current_exe.starts_with(installer_bin_path) {
return InstallationMethod::Installer;
}
let path_str = current_exe.to_string_lossy();
if path_str.starts_with("/nix/store/") {
InstallationMethod::Nix
} else if path_str.contains(".cargo/bin") {
InstallationMethod::Cargo
} else if path_str.contains("target/debug") || path_str.contains("target/release") {
InstallationMethod::Source
} else if path_str.starts_with("/opt/homebrew/")
|| path_str.starts_with("/home/linuxbrew/.linuxbrew/")
|| path_str.contains("/Cellar/")
|| path_str.contains("/homebrew/")
{
InstallationMethod::Homebrew
} else {
InstallationMethod::Unknown(Some(path_str.to_string()))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_detect_installation_method() {
let data_dir = Path::new("/home/user/.config/intelli-shell");
assert_eq!(
detect_installation_method_inner(
Path::new("/home/user/.config/intelli-shell/bin/intelli-shell"),
data_dir
),
InstallationMethod::Installer
);
assert_eq!(
detect_installation_method_inner(
Path::new("/nix/store/abc-intelli-shell/bin/intelli-shell"),
data_dir
),
InstallationMethod::Nix
);
assert_eq!(
detect_installation_method_inner(
Path::new("/home/user/.cargo/bin/intelli-shell"),
data_dir
),
InstallationMethod::Cargo
);
assert_eq!(
detect_installation_method_inner(
Path::new("/home/user/projects/intelli-shell/target/release/intelli-shell"),
data_dir
),
InstallationMethod::Source
);
assert_eq!(
detect_installation_method_inner(
Path::new("/opt/homebrew/bin/intelli-shell"),
data_dir
),
InstallationMethod::Homebrew
);
assert_eq!(
detect_installation_method_inner(
Path::new("/usr/local/Cellar/intelli-shell/3.4.3/bin/intelli-shell"),
data_dir
),
InstallationMethod::Homebrew
);
assert_eq!(
detect_installation_method_inner(
Path::new("/home/linuxbrew/.linuxbrew/bin/intelli-shell"),
data_dir
),
InstallationMethod::Homebrew
);
assert_eq!(
detect_installation_method_inner(
Path::new("/usr/local/bin/intelli-shell"),
data_dir
),
InstallationMethod::Unknown(Some("/usr/local/bin/intelli-shell".to_string()))
);
}
}