pub use crate::{AppConfig, AppInfo, AppManifest};
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
pub fn get_rew_root() -> PathBuf {
if let Ok(rew_root) = env::var("REW_ROOT") {
return PathBuf::from(rew_root);
}
#[cfg(target_os = "windows")]
{
let local_app_data = env::var("LOCALAPPDATA").unwrap_or_else(|_| {
let home = env::var("USERPROFILE").unwrap_or_else(|_| ".".to_string());
format!("{}\\AppData\\Local", home)
});
PathBuf::from(format!("{}\\rew", local_app_data))
}
#[cfg(not(target_os = "windows"))]
{
if std::path::Path::new("/opt/rew").exists() {
PathBuf::from("/opt/rew")
} else {
let home = env::var("HOME").unwrap_or_else(|_| ".".to_string());
PathBuf::from(format!("{}/.rew", home))
}
}
}
pub fn pimmy_data_path() -> Option<PathBuf> {
Some(get_rew_root().join(".pimmy"))
}
pub fn find_app_by_package(package_name: &str) -> Option<AppInfo> {
let rew_root = get_rew_root();
let apps_dir = rew_root.join("apps");
if !apps_dir.exists() {
return None;
}
let app_dirs = fs::read_dir(&apps_dir).ok()?;
for dir_entry in app_dirs.flatten() {
let app_dir = dir_entry.path();
if !app_dir.is_dir() {
continue;
}
let config_path = app_dir.join("app.yaml");
if !config_path.exists() {
continue;
}
let config_str = fs::read_to_string(&config_path).ok()?;
let config: AppConfig = serde_yaml::from_str(&config_str).ok()?;
if let Some(manifest) = &config.manifest {
if let Some(pkg) = &manifest.package {
if pkg == package_name {
return Some(AppInfo {
path: app_dir,
config,
});
}
}
}
}
None
}
pub fn find_app_info(file_path: &Path) -> Option<AppInfo> {
let mut current = file_path;
while let Some(parent) = current.parent() {
let config_path = parent.join("app.yaml");
if config_path.exists() {
let config_str = fs::read_to_string(&config_path).ok()?;
let config: AppConfig = serde_yaml::from_str(&config_str).ok()?;
return Some(AppInfo {
path: parent.to_path_buf(),
config,
});
}
current = parent;
}
None
}
pub fn resolve_app_entry(package_name: &str, entry_name: Option<&str>) -> Option<PathBuf> {
let app_info = find_app_by_package(package_name)?;
let entries = app_info.config.entries.as_ref()?;
let entry_key = entry_name.unwrap_or("main");
let entry_path = entries.get(entry_key)?;
Some(app_info.path.join(entry_path))
}
pub fn find_app_path(dir_path: &Path) -> Option<PathBuf> {
let mut current = dir_path;
while let Some(parent) = current.parent() {
let config_path = parent.join("app.yaml");
if config_path.exists() {
return Some(parent.to_path_buf());
}
current = parent;
}
None
}
pub fn is_valid_utf8<P: AsRef<Path>>(path: P) -> std::io::Result<bool> {
let bytes = std::fs::read(path)?;
Ok(std::str::from_utf8(&bytes).is_ok())
}