use std::path::{Path, PathBuf};
use crate::core::config::{DEFAULT_SCHEMA_PATH, SchemaDrift, classify_alef_config_schema};
pub(super) struct VendoredSchemaFinding {
path: PathBuf,
drift: SchemaDrift,
}
impl VendoredSchemaFinding {
pub(super) fn describes_a_different_surface(&self) -> bool {
self.drift.describes_a_different_surface()
}
pub(super) fn report_lines(&self) -> Vec<String> {
let display = self.path.display();
match &self.drift {
SchemaDrift::None => Vec::new(),
SchemaDrift::Shape => vec![
"Vendored alef config schema describes a different alef.toml surface than this alef \
(an editor validating alef.toml against this copy is answering for a different \
release -- regenerate it):"
.to_string(),
format!(" {display} -- fix with: alef schema --output {display}"),
],
SchemaDrift::SurfaceUnchanged {
found_version,
expected_version,
} => {
let detail = match found_version.as_deref() {
Some(found) if found == expected_version.as_str() => {
format!("stamped {found}, but reserialized -- byte differences are formatting only")
}
Some(found) => format!("stamped {found}, running alef {expected_version}"),
None => format!("carries no version stamp; running alef {expected_version}"),
};
vec![
"Vendored alef config schema differs from this alef's (informational -- the \
described alef.toml surface is unchanged, so editor validation is still \
correct; refresh it whenever convenient):"
.to_string(),
format!(" {display} -- {detail}; refresh with: alef schema --output {display}"),
]
}
}
}
}
pub(super) fn find_stale_vendored_schema(base_dir: &Path, cli_version: &str) -> Option<VendoredSchemaFinding> {
let path = base_dir.join(DEFAULT_SCHEMA_PATH);
if !path.is_file() {
return None;
}
let drift = match classify_alef_config_schema(&path, cli_version) {
Ok(drift) => drift,
Err(error) => {
tracing::debug!(
"could not classify vendored config schema {}: {error:#}",
path.display()
);
return None;
}
};
if drift == SchemaDrift::None {
return None;
}
Some(VendoredSchemaFinding { path, drift })
}
#[cfg(test)]
mod tests;