Publish harness and TUI open-source
initial sync from the monorepo
This commit is contained in:
commit
c68e39f604
2734 changed files with 1437016 additions and 0 deletions
212
crates/codegen/xai-grok-config/src/version_overrides.rs
Normal file
212
crates/codegen/xai-grok-config/src/version_overrides.rs
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
//! Version-aware config layering. A `[[version_overrides]]` array carries
|
||||
//! semver-gated patches deep-merged in ascending `minimum_version` order.
|
||||
//!
|
||||
//! ```toml
|
||||
//! [[version_overrides]]
|
||||
//! minimum_version = "1.7.0"
|
||||
//! [version_overrides.features]
|
||||
//! logging = true
|
||||
//!
|
||||
//! [[version_overrides]]
|
||||
//! minimum_version = "1.8.0"
|
||||
//! maximum_version = "1.9.999"
|
||||
//! [version_overrides.features.telemetry]
|
||||
//! enabled = true
|
||||
//! ```
|
||||
|
||||
use semver::Version;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::config_override::{PATCH_STRIP_KEYS, apply_patches, take_patch_array};
|
||||
|
||||
pub const VERSION_OVERRIDES_KEY: &str = "version_overrides";
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct VersionOverrideMeta {
|
||||
#[serde(default)]
|
||||
pub minimum_version: Option<String>,
|
||||
#[serde(default)]
|
||||
pub maximum_version: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum VersionOverrideError {
|
||||
#[error("version_overrides: failed to deserialize: {0}")]
|
||||
Deserialize(#[from] toml::de::Error),
|
||||
#[error("version_overrides[{index}].minimum_version = {value:?} is not valid semver: {source}")]
|
||||
InvalidMinimumVersion {
|
||||
index: usize,
|
||||
value: String,
|
||||
#[source]
|
||||
source: semver::Error,
|
||||
},
|
||||
#[error("version_overrides[{index}].maximum_version = {value:?} is not valid semver: {source}")]
|
||||
InvalidMaximumVersion {
|
||||
index: usize,
|
||||
value: String,
|
||||
#[source]
|
||||
source: semver::Error,
|
||||
},
|
||||
}
|
||||
|
||||
/// Strips `version_overrides` (always) and deep-merges each matching
|
||||
/// patch in ascending `minimum_version` order.
|
||||
pub fn apply_version_overrides(
|
||||
config: &mut toml::Value,
|
||||
version: &Version,
|
||||
) -> Result<(), VersionOverrideError> {
|
||||
let entries = take_patch_array::<VersionOverrideMeta>(config, VERSION_OVERRIDES_KEY)?;
|
||||
|
||||
// Parse all bounds upfront so an invalid entry fails before any merge.
|
||||
// Missing minimum_version => Version::new(0, 0, 0) (no lower bound).
|
||||
let mut parsed: Vec<(Version, Option<Version>, toml::Table)> =
|
||||
Vec::with_capacity(entries.len());
|
||||
for (index, entry) in entries.into_iter().enumerate() {
|
||||
let min_v = match &entry.meta.minimum_version {
|
||||
Some(s) => Version::parse(s.trim()).map_err(|source| {
|
||||
VersionOverrideError::InvalidMinimumVersion {
|
||||
index,
|
||||
value: s.clone(),
|
||||
source,
|
||||
}
|
||||
})?,
|
||||
None => Version::new(0, 0, 0),
|
||||
};
|
||||
let max_v = match &entry.meta.maximum_version {
|
||||
Some(max_str) => Some(Version::parse(max_str.trim()).map_err(|source| {
|
||||
VersionOverrideError::InvalidMaximumVersion {
|
||||
index,
|
||||
value: max_str.clone(),
|
||||
source,
|
||||
}
|
||||
})?),
|
||||
None => None,
|
||||
};
|
||||
parsed.push((min_v, max_v, entry.patch));
|
||||
}
|
||||
|
||||
// Stable sort -- ties on minimum_version keep declared order so later
|
||||
// entries win.
|
||||
parsed.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
|
||||
let patches = parsed.into_iter().filter_map(|(min_v, max_v, patch)| {
|
||||
if version < &min_v {
|
||||
return None;
|
||||
}
|
||||
if let Some(ref m) = max_v
|
||||
&& version > m
|
||||
{
|
||||
return None;
|
||||
}
|
||||
Some(patch)
|
||||
});
|
||||
apply_patches(config, patches, PATCH_STRIP_KEYS);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn parse(s: &str) -> toml::Value {
|
||||
toml::from_str(s).expect("valid toml")
|
||||
}
|
||||
|
||||
fn v(s: &str) -> Version {
|
||||
Version::parse(s).unwrap()
|
||||
}
|
||||
|
||||
/// Helper asserts the section is stripped on every call, so the
|
||||
/// "stripped even on no match" contract is covered across all 8 cases.
|
||||
#[test]
|
||||
fn version_match_boundaries() {
|
||||
fn applies(min: Option<&str>, max: Option<&str>, cli: &str) -> bool {
|
||||
let line = |k: &str, val: Option<&str>| {
|
||||
val.map(|s| format!("\n {k} = \"{s}\""))
|
||||
.unwrap_or_default()
|
||||
};
|
||||
let mut cfg = parse(&format!(
|
||||
r#"
|
||||
x = 0
|
||||
|
||||
[[version_overrides]]{}{}
|
||||
x = 1
|
||||
"#,
|
||||
line("minimum_version", min),
|
||||
line("maximum_version", max),
|
||||
));
|
||||
apply_version_overrides(&mut cfg, &v(cli)).unwrap();
|
||||
assert!(
|
||||
cfg.get(VERSION_OVERRIDES_KEY).is_none(),
|
||||
"section must be stripped"
|
||||
);
|
||||
cfg["x"].as_integer() == Some(1)
|
||||
}
|
||||
assert!(applies(Some("1.7.0"), None, "1.7.0")); // min inclusive
|
||||
assert!(applies(Some("1.0.0"), Some("1.7.0"), "1.7.0")); // max inclusive
|
||||
assert!(!applies(Some("1.7.0"), None, "1.6.0")); // below min
|
||||
assert!(!applies(Some("1.0.0"), Some("1.5.0"), "2.0.0")); // above max
|
||||
assert!(applies(Some("1.7.0"), None, "99.0.0")); // unbounded above
|
||||
assert!(applies(None, Some("2.0.0"), "1.5.0")); // max-only, within
|
||||
assert!(!applies(None, Some("2.0.0"), "2.0.1")); // max-only, above
|
||||
assert!(applies(None, None, "1.0.0")); // unbounded both = always
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn later_matching_override_wins_on_same_key() {
|
||||
let mut cfg = parse(
|
||||
r#"
|
||||
[features.telemetry]
|
||||
enabled = false
|
||||
|
||||
[[version_overrides]]
|
||||
minimum_version = "1.7.0"
|
||||
[version_overrides.features.telemetry]
|
||||
enabled = true
|
||||
sample_rate = 0.1
|
||||
|
||||
[[version_overrides]]
|
||||
minimum_version = "1.8.0"
|
||||
[version_overrides.features.telemetry]
|
||||
sample_rate = 0.5
|
||||
"#,
|
||||
);
|
||||
apply_version_overrides(&mut cfg, &v("1.8.0")).unwrap();
|
||||
let t = &cfg["features"]["telemetry"];
|
||||
assert_eq!(t["enabled"].as_bool(), Some(true));
|
||||
assert_eq!(t["sample_rate"].as_float(), Some(0.5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_semver_in_bounds_is_hard_error() {
|
||||
let mut cfg = parse(
|
||||
r#"
|
||||
[[version_overrides]]
|
||||
minimum_version = "not-a-version"
|
||||
x = 1
|
||||
"#,
|
||||
);
|
||||
let err = apply_version_overrides(&mut cfg, &v("1.0.0")).unwrap_err();
|
||||
assert!(matches!(
|
||||
err,
|
||||
VersionOverrideError::InvalidMinimumVersion { .. }
|
||||
));
|
||||
// Section is consumed even on error.
|
||||
assert!(cfg.get(VERSION_OVERRIDES_KEY).is_none());
|
||||
|
||||
let mut cfg = parse(
|
||||
r#"
|
||||
[[version_overrides]]
|
||||
minimum_version = "1.0.0"
|
||||
maximum_version = "garbage"
|
||||
x = 1
|
||||
"#,
|
||||
);
|
||||
let err = apply_version_overrides(&mut cfg, &v("1.0.0")).unwrap_err();
|
||||
assert!(matches!(
|
||||
err,
|
||||
VersionOverrideError::InvalidMaximumVersion { .. }
|
||||
));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue