use std::collections::HashMap;
use std::path::{Path, PathBuf};
use serde::Deserialize;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum PreflightSeverity {
#[default]
Error,
Warning,
Off,
}
impl PreflightSeverity {
pub fn from_opt(raw: Option<&str>) -> Self {
match raw.map(|s| s.to_ascii_lowercase()) {
Some(v) if v == "warning" || v == "warn" => Self::Warning,
Some(v) if v == "off" || v == "allow" || v == "silent" => Self::Off,
_ => Self::Error,
}
}
}
#[derive(Debug, Default, Clone, Deserialize)]
pub struct CheckConfig {
#[serde(default)]
pub strict: bool,
#[serde(default)]
pub strict_types: bool,
#[serde(default)]
pub trusted_host_dispatch: bool,
#[serde(default)]
pub disable_rules: Vec<String>,
#[serde(default)]
pub host_capabilities: HashMap<String, Vec<String>>,
#[serde(default, alias = "host_capabilities_file")]
pub host_capabilities_path: Option<String>,
#[serde(default)]
pub bundle_root: Option<String>,
#[serde(default, alias = "preflight-severity")]
pub preflight_severity: Option<String>,
#[serde(default, alias = "preflight-allow")]
pub preflight_allow: Vec<String>,
}
pub(crate) fn absolutize_check_config_paths(
mut config: CheckConfig,
manifest_dir: &Path,
) -> CheckConfig {
if let Some(path) = config.host_capabilities_path.clone() {
let candidate = PathBuf::from(&path);
if !candidate.is_absolute() {
config.host_capabilities_path =
Some(manifest_dir.join(candidate).display().to_string());
}
}
if let Some(path) = config.bundle_root.clone() {
let candidate = PathBuf::from(&path);
if !candidate.is_absolute() {
config.bundle_root = Some(manifest_dir.join(candidate).display().to_string());
}
}
config
}
pub fn load_check_config(harn_file: Option<&std::path::Path>) -> CheckConfig {
let anchor = harn_file
.map(Path::to_path_buf)
.unwrap_or_else(|| std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")));
if let Some((manifest, dir)) =
crate::package::manifest_search::nearest_manifest_or_warn(&anchor)
{
return absolutize_check_config_paths(manifest.check, &dir);
}
CheckConfig::default()
}