pub mod version;
pub use version::{fetch_version, increment_version};
use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct FoundXbpConfig {
pub project_root: PathBuf,
pub config_path: PathBuf,
pub kind: &'static str,
pub location: String,
}
pub fn find_xbp_config_upwards(start_dir: &Path) -> Option<FoundXbpConfig> {
for dir in start_dir.ancestors() {
let candidates: [(PathBuf, &'static str); 6] = [
(dir.join(".xbp").join("xbp.yaml"), "yaml"),
(dir.join(".xbp").join("xbp.yml"), "yaml"),
(dir.join(".xbp").join("xbp.json"), "json"),
(dir.join("xbp.yaml"), "yaml"),
(dir.join("xbp.yml"), "yaml"),
(dir.join("xbp.json"), "json"),
];
for (path, kind) in candidates {
if !path.exists() {
continue;
}
let project_root = path
.parent()
.and_then(|p| {
if p.file_name() == Some(std::ffi::OsStr::new(".xbp")) {
p.parent().map(|pp| pp.to_path_buf())
} else {
Some(p.to_path_buf())
}
})
.unwrap_or_else(|| dir.to_path_buf());
let location = path
.strip_prefix(&project_root)
.ok()
.map(|p| p.to_string_lossy().replace('\\', "/"))
.unwrap_or_else(|| path.to_string_lossy().replace('\\', "/"));
return Some(FoundXbpConfig {
project_root,
config_path: path,
kind,
location,
});
}
}
None
}
pub fn expand_home_in_string(input: &str) -> String {
let home = dirs::home_dir()
.unwrap_or_else(|| std::path::PathBuf::from("."))
.to_string_lossy()
.to_string();
if input == "~" {
return home;
}
if let Some(rest) = input
.strip_prefix("~/")
.or_else(|| input.strip_prefix("~\\"))
{
return format!("{}{}{}", home, std::path::MAIN_SEPARATOR, rest);
}
if let Some(rest) = input
.strip_prefix("$HOME/")
.or_else(|| input.strip_prefix("$HOME\\"))
{
return format!("{}{}{}", home, std::path::MAIN_SEPARATOR, rest);
}
if let Some(rest) = input
.strip_prefix("${HOME}/")
.or_else(|| input.strip_prefix("${HOME}\\"))
{
return format!("{}{}{}", home, std::path::MAIN_SEPARATOR, rest);
}
input.to_string()
}
pub fn collapse_home_to_env(input: &str) -> String {
let home = dirs::home_dir()
.unwrap_or_else(|| std::path::PathBuf::from("."))
.to_string_lossy()
.to_string();
if input == home {
return "$HOME".to_string();
}
if let Some(rest) = input.strip_prefix(&(home.clone() + "/")) {
return format!("$HOME/{}", rest);
}
if let Some(rest) = input.strip_prefix(&(home.clone() + "\\")) {
return format!("$HOME\\{}", rest);
}
input.to_string()
}