use std::fs;
use serde::Deserialize;
use xshell::Shell;
use crate::environment::{get_workspace_root, WorkspaceManifest};
#[derive(Deserialize, Default)]
struct RbmtConfig {
version: Option<String>,
}
pub fn check(sh: &Shell) -> Result<(), Box<dyn std::error::Error>> {
let manifest_path = get_workspace_root(sh)?.join("Cargo.toml");
let contents = fs::read_to_string(manifest_path)?;
let toml: WorkspaceManifest<RbmtConfig> = toml::from_str(&contents)?;
let expected_version =
toml.workspace.metadata.rbmt.version.or(toml.package.metadata.rbmt.version);
if let Some(expected) = expected_version {
let actual_version = env!("CARGO_PKG_VERSION");
let actual_hash = env!("RBMT_GIT_HASH");
if expected.len() >= 40 && expected.chars().all(|c| c.is_ascii_hexdigit()) {
if actual_hash.is_empty() {
return Err(format!(
"cargo-rbmt version mismatch: expected commit {}, but git hash unavailable (likely installed from registry)",
expected
)
.into());
}
if !actual_hash.starts_with(&expected) {
return Err(format!(
"cargo-rbmt version mismatch: expected commit {}, found {}",
expected, actual_hash
)
.into());
}
} else {
if expected != actual_version {
return Err(format!(
"cargo-rbmt version mismatch: expected {}, found {}",
expected, actual_version
)
.into());
}
}
}
Ok(())
}