use crate::core::config::ResolvedCrateConfig;
use crate::core::config::extras::Language;
use crate::core::managed_versions;
pub(crate) struct ManagedVersions<'a> {
language: Language,
overrides: &'a std::collections::BTreeMap<String, String>,
}
impl<'a> ManagedVersions<'a> {
pub(crate) fn new(config: &'a ResolvedCrateConfig, language: Language) -> Self {
Self {
language,
overrides: config.dependency_version_overrides(language),
}
}
pub(crate) fn get(&self, key: &'static str) -> &'a str {
managed_versions::resolve(self.language, key, self.overrides).unwrap_or_else(|| {
panic!(
"`{key}` is not a registered managed version for {}; add it to \
`core::managed_versions::MANAGED_DEPENDENCIES` or fix the lookup",
self.language
)
})
}
}
pub(crate) fn override_notice_lines(language: Language) -> Vec<String> {
vec![
"Dependency versions here are alef-managed and are rewritten on every `alef build`.".to_string(),
format!(
"To raise one durably, set it in `{}`; a direct edit to this file is discarded.",
managed_versions::override_table(language)
),
]
}
pub(crate) fn override_notice_hash(language: Language) -> String {
override_notice_lines(language)
.into_iter()
.enumerate()
.map(|(index, line)| {
if index == 0 {
format!("# {line} ~keep\n")
} else {
format!("# {line}\n")
}
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::config::NewAlefConfig;
const CONFIG: &str = r#"
[workspace]
languages = ["ruby"]
[[crates]]
name = "sample-lib"
sources = ["src/lib.rs"]
[crates.ruby.dependency_versions]
"gem:rspec" = "~> 99.0"
"#;
fn resolved() -> ResolvedCrateConfig {
let parsed: NewAlefConfig = toml::from_str(CONFIG).expect("config parses");
parsed.resolve().expect("config resolves").remove(0)
}
#[test]
fn an_override_replaces_the_default_and_leaves_its_siblings_alone() {
let config = resolved();
let versions = ManagedVersions::new(&config, Language::Ruby);
assert_eq!(versions.get("gem:rspec"), "~> 99.0");
assert_eq!(versions.get("gem:steep"), crate::core::template_versions::gem::STEEP);
}
#[test]
fn a_language_without_the_table_falls_back_to_every_default() {
let config = resolved();
let versions = ManagedVersions::new(&config, Language::Python);
assert_eq!(versions.get("cargo:pyo3"), crate::core::template_versions::cargo::PYO3);
}
#[test]
#[should_panic(expected = "is not a registered managed version")]
fn an_unregistered_key_panics_rather_than_emitting_an_empty_literal() {
let config = resolved();
ManagedVersions::new(&config, Language::Ruby).get("gem:not-a-real-entry");
}
#[test]
fn the_notice_carries_a_keep_marker_and_names_the_real_table() {
let notice = override_notice_hash(Language::Python);
assert!(notice.contains("~keep"), "notice must be keep-marked, got:\n{notice}");
assert!(
notice.contains("[crates.python.dependency_versions]"),
"notice must name the real table, got:\n{notice}"
);
for line in notice.lines() {
assert_eq!(line.trim_end(), line, "notice line has trailing whitespace: {line:?}");
}
}
}