use crate::auditwheel::PlatformTag;
use once_cell::sync::Lazy;
use serde::Deserialize;
use std::cmp::{Ordering, PartialOrd};
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::fmt::{Display, Formatter};
pub static POLICIES: Lazy<Vec<Policy>> = Lazy::new(|| {
let mut policies: Vec<Policy> = serde_json::from_slice(include_bytes!("policy.json"))
.expect("invalid manylinux policy.json file");
policies.sort_by_key(|policy| -policy.priority);
policies
});
#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct Policy {
pub name: String,
pub aliases: Vec<String>,
pub priority: i64,
#[serde(rename = "symbol_versions")]
pub symbol_versions: HashMap<String, HashMap<String, HashSet<String>>>,
#[serde(rename = "lib_whitelist")]
pub lib_whitelist: HashSet<String>,
}
impl Default for Policy {
fn default() -> Self {
Policy::from_priority(0).unwrap()
}
}
impl Display for Policy {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
if self.aliases.is_empty() {
f.write_str(&self.name)
} else {
f.write_fmt(format_args!(
"{}(aka {})",
&self.name,
self.aliases.join(",")
))
}
}
}
impl PartialOrd for Policy {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.priority.partial_cmp(&other.priority)
}
}
impl Policy {
pub fn higher_priority_policies(&self) -> impl Iterator<Item = &Policy> {
POLICIES.iter().filter(move |p| p.priority > self.priority)
}
pub fn platform_tag(&self) -> PlatformTag {
self.name.parse().expect("unknown platform tag")
}
pub fn from_name(name: &str) -> Option<Self> {
POLICIES
.iter()
.find(|p| p.name == name || p.aliases.iter().any(|alias| alias == name))
.cloned()
}
pub fn from_priority(priority: i64) -> Option<Self> {
POLICIES.iter().find(|p| p.priority == priority).cloned()
}
}
#[cfg(test)]
mod test {
use super::{Policy, POLICIES};
#[test]
fn test_load_policy() {
let linux = Policy::from_name("linux").unwrap();
assert!(linux.symbol_versions.is_empty());
assert!(linux.lib_whitelist.is_empty());
let manylinux2010 = Policy::from_name("manylinux2010").unwrap();
assert!(manylinux2010.lib_whitelist.contains("libc.so.6"));
let symbol_version = &manylinux2010.symbol_versions["x86_64"];
assert_eq!(symbol_version["CXXABI"].len(), 4);
let cxxabi = &symbol_version["CXXABI"];
for version in &["1.3", "1.3.1", "1.3.2", "1.3.3"] {
assert!(cxxabi.contains(*version));
}
}
#[test]
fn test_policy_manylinux_tag() {
for policy in POLICIES.iter() {
let _tag = policy.platform_tag();
}
}
}