distro_info: match changelog suite names with their series
Debian packages conventionally target 'unstable' in their debian/changelog distribution field, but the series data (the distro-info CSVs) only knows codenames: the suite is the alias 'unstable' of the series 'sid', a mapping the debian-distro-info tool resolves internally without exposing it in its data. Add a per-dist suite_aliases reference-data key (debian: unstable -> sid), with two helpers on top: resolve_suite_alias, identifying a changelog suite name with its series codename and the dist that codename belongs to, and series_suite_alias, the inverse direction. The two names identify the same series.
This commit is contained in:
@@ -28,6 +28,12 @@
|
|||||||
## series (`<series>-updates`, ...). Deliberately not the
|
## series (`<series>-updates`, ...). Deliberately not the
|
||||||
## `pockets` key: that one is the *search order* of pull,
|
## `pockets` key: that one is the *search order* of pull,
|
||||||
## where backports must not fold in.
|
## where backports must not fold in.
|
||||||
|
## suite_aliases: the changelog suite names that alias a series
|
||||||
|
## codename: Debian packages conventionally target
|
||||||
|
## 'unstable' where the series data carries 'sid'.
|
||||||
|
## Mapped suite name -> series codename; the two
|
||||||
|
## names identify the same series, and the selector
|
||||||
|
## offers the aliased entry as '<suite> (<series>)'.
|
||||||
## build_profiles: the vendor's default DEB_BUILD_PROFILES (Ubuntu
|
## build_profiles: the vendor's default DEB_BUILD_PROFILES (Ubuntu
|
||||||
## activates derivative.ubuntu noudeb, Debian none),
|
## activates derivative.ubuntu noudeb, Debian none),
|
||||||
## mirroring what Dpkg::BuildProfiles resolves when the
|
## mirroring what Dpkg::BuildProfiles resolves when the
|
||||||
@@ -47,6 +53,10 @@ dist:
|
|||||||
- updates
|
- updates
|
||||||
- security
|
- security
|
||||||
- proposed-updates
|
- proposed-updates
|
||||||
|
# Debian changelogs conventionally target 'unstable'; the series data
|
||||||
|
# knows the same series as 'sid'.
|
||||||
|
suite_aliases:
|
||||||
|
unstable: sid
|
||||||
sections:
|
sections:
|
||||||
# Valid Section values for debian/control: the Debian policy section
|
# Valid Section values for debian/control: the Debian policy section
|
||||||
# list unioned with the sections observed in the live Ubuntu archive.
|
# list unioned with the sections observed in the live Ubuntu archive.
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ struct DistData {
|
|||||||
cross_pockets: Vec<String>,
|
cross_pockets: Vec<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
build_profiles: Vec<String>,
|
build_profiles: Vec<String>,
|
||||||
|
/// Changelog suite names aliasing a distro-info series codename
|
||||||
|
/// ('unstable' for Debian's 'sid'): the two names identify the same
|
||||||
|
/// series ([`series_suite_alias`], [`resolve_suite_alias`])
|
||||||
|
#[serde(default)]
|
||||||
|
suite_aliases: HashMap<String, String>,
|
||||||
series: SeriesInfo,
|
series: SeriesInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,6 +418,30 @@ pub async fn get_dist_from_series(series: &str) -> Result<String, Box<dyn Error>
|
|||||||
Err(format!("Unknown series: {}", series).into())
|
Err(format!("Unknown series: {}", series).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The changelog suite name that aliases the series codename of `dist`
|
||||||
|
/// (Debian's 'unstable' for 'sid'): the two names identify the same
|
||||||
|
/// series. `None` when the series carries no suite alias.
|
||||||
|
pub fn series_suite_alias(dist: &str, series: &str) -> Option<String> {
|
||||||
|
dist_data(dist)
|
||||||
|
.ok()?
|
||||||
|
.suite_aliases
|
||||||
|
.iter()
|
||||||
|
.find(|(_suite, codename)| codename.as_str() == series)
|
||||||
|
.map(|(suite, _)| suite.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Identify a changelog suite name with the distro-info series codename
|
||||||
|
/// it aliases (Debian's 'unstable' is 'sid'), and the dist that codename
|
||||||
|
/// belongs to. `None` when `suite` is not a known alias of any dist.
|
||||||
|
pub fn resolve_suite_alias(suite: &str) -> Option<(String, String)> {
|
||||||
|
for (dist, data) in DATA.dist.iter() {
|
||||||
|
if let Some(codename) = data.suite_aliases.get(suite) {
|
||||||
|
return Some((dist.clone(), codename.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the package pockets available for a given distribution, in search order
|
/// Get the package pockets available for a given distribution, in search order
|
||||||
///
|
///
|
||||||
/// The main archive ('') comes first so that a search without an explicit
|
/// The main archive ('') comes first so that a search without an explicit
|
||||||
@@ -1035,6 +1064,41 @@ mod tests {
|
|||||||
assert!(series.contains(&"jammy".to_string()));
|
assert!(series.contains(&"jammy".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Suite aliases identify a changelog suite name with the series
|
||||||
|
/// codename of the same series: Debian's 'unstable' is 'sid'
|
||||||
|
#[test]
|
||||||
|
fn test_suite_aliases() {
|
||||||
|
assert_eq!(
|
||||||
|
resolve_suite_alias("unstable"),
|
||||||
|
Some(("debian".to_string(), "sid".to_string()))
|
||||||
|
);
|
||||||
|
// A series codename or unknown suite is not an alias
|
||||||
|
assert_eq!(resolve_suite_alias("sid"), None);
|
||||||
|
assert_eq!(resolve_suite_alias("noble"), None);
|
||||||
|
assert_eq!(
|
||||||
|
series_suite_alias("debian", "sid"),
|
||||||
|
Some("unstable".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(series_suite_alias("debian", "trixie"), None);
|
||||||
|
assert_eq!(series_suite_alias("ubuntu", "noble"), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Every suite alias must map to a real series of its dist, or the
|
||||||
|
/// selector would offer a phantom entry
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_suite_aliases_target_real_series() {
|
||||||
|
for (dist, data) in DATA.dist.iter() {
|
||||||
|
for (suite, codename) in &data.suite_aliases {
|
||||||
|
let series = get_ordered_series_name(dist).await.unwrap_or_default();
|
||||||
|
assert!(
|
||||||
|
series.contains(codename),
|
||||||
|
"suite alias '{suite}' of {dist} maps to '{codename}', \
|
||||||
|
which is not a known series"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_get_dist_from_series() {
|
async fn test_get_dist_from_series() {
|
||||||
assert_eq!(get_dist_from_series("sid").await.unwrap(), "debian");
|
assert_eq!(get_dist_from_series("sid").await.unwrap(), "debian");
|
||||||
|
|||||||
Reference in New Issue
Block a user