use std::path::Path;
use super::config::read_toml_value;
use super::date::parse_relative_days;
use super::detect::get_delay_days;
use super::types::{
missing_status_for_path, unsupported_with_message_if_configured, CheckStatus, Recommendation,
};
use super::version::{extract_version_str, parse_semver};
pub(crate) const UV_KEY: &str = "exclude-newer";
const UV_MIN_MAJOR: u64 = 0;
const UV_MIN_MINOR: u64 = 9;
const UV_MIN_PATCH: u64 = 17;
fn supports_relative_duration(version: &str) -> bool {
let ver = extract_version_str(version);
parse_semver(ver).is_some_and(|(major, minor, patch)| {
(major, minor, patch) >= (UV_MIN_MAJOR, UV_MIN_MINOR, UV_MIN_PATCH)
})
}
pub fn scan(path: &Path, version: &str) -> Vec<Recommendation> {
let days = get_delay_days();
let ver = extract_version_str(version);
let val = read_toml_value(path, UV_KEY);
let status = match &val {
Some(v) => {
match parse_relative_days(v) {
Some(d) if d == days => CheckStatus::Ok(v.clone()),
_ => CheckStatus::WrongValue(v.clone()),
}
}
None => missing_status_for_path(path),
};
let rec = Recommendation {
key: UV_KEY.into(),
description: format!("Delay new versions by {days} days"),
expected: format!("{days} days"),
status,
};
let configured_relative_duration = val.as_deref().and_then(parse_relative_days).is_some();
let rec = if configured_relative_duration && !supports_relative_duration(version) {
unsupported_with_message_if_configured(
rec,
format!(
"requires uv \u{2265} {UV_MIN_MAJOR}.{UV_MIN_MINOR}.{UV_MIN_PATCH} (have {ver})"
),
)
} else {
rec
};
vec![rec]
}