use std::collections::HashMap;
use color_eyre::Result;
use crate::models::PACKAGE_CACHE;
pub fn create_delta_world_from_specs(package_specs: &[String]) -> HashMap<String, String> {
use crate::parse_requires::{parse_package_spec_with_version, format_version_constraint_for_world};
let mut delta_world = HashMap::new();
for spec in package_specs {
let (pkgname, constraints) = parse_package_spec_with_version(spec, crate::models::PackageFormat::Apk);
let constraint_str = if let Some(ref constraints) = constraints {
format_version_constraint_for_world(constraints)
} else {
String::new()
};
delta_world.insert(pkgname, constraint_str);
}
delta_world
}
pub fn apply_delta_world(delta_world: &HashMap<String, String>) {
let packages_to_remove: Vec<String> = delta_world.keys().cloned().collect();
remove_from_no_install(packages_to_remove.iter());
let mut world = PACKAGE_CACHE.world.write().unwrap();
for (pkgname, constraint_str) in delta_world {
world.insert(pkgname.clone(), constraint_str.clone());
}
}
pub fn remove_from_no_install<'a, I>(packages_to_remove: I)
where
I: Iterator<Item = &'a String>,
{
let mut no_install_set = get_no_install_set();
let mut changed = false;
for pkgname in packages_to_remove {
if no_install_set.remove(pkgname) {
changed = true;
}
}
if changed {
update_no_install_in_world(no_install_set);
}
}
fn update_no_install_in_world(no_install_set: std::collections::HashSet<String>) {
let mut no_install_vec: Vec<String> = no_install_set.into_iter().collect();
no_install_vec.sort();
let mut world = PACKAGE_CACHE.world.write().unwrap();
if no_install_vec.is_empty() {
world.remove("no-install");
} else {
world.insert("no-install".to_string(), no_install_vec.join(" "));
}
}
pub fn apply_no_install_changes() -> Result<()> {
let config = crate::models::config();
if config.install.no_install.is_empty() {
return Ok(());
}
let mut no_install_set = get_no_install_set();
for item in config.install.no_install.split(',') {
let item = item.trim();
if item.is_empty() {
continue;
}
if item.starts_with('-') {
let pkg = item[1..].trim().to_string();
if !pkg.is_empty() {
no_install_set.remove(&pkg);
}
} else {
no_install_set.insert(item.to_string());
}
}
update_no_install_in_world(no_install_set);
Ok(())
}
pub fn add_essential_packages_to_delta_world(delta_world: &mut HashMap<String, String>) -> Result<()> {
let essential_pkgnames = crate::mmio::get_essential_pkgnames()?;
let world = PACKAGE_CACHE.world.read().unwrap();
let mut added = 0usize;
for essential_pkgname in &essential_pkgnames {
if !world.contains_key(essential_pkgname) && !delta_world.contains_key(essential_pkgname) {
delta_world.insert(essential_pkgname.clone(), String::new());
added += 1;
}
}
log::info!(
"add_essential_packages_to_delta_world: {} essential from repo, {} added to delta_world",
essential_pkgnames.len(),
added
);
Ok(())
}
pub fn get_no_install_set() -> std::collections::HashSet<String> {
PACKAGE_CACHE.world.read().unwrap()
.get("no-install")
.map(|s| {
s.split_whitespace()
.map(|pkg| pkg.to_string())
.collect()
})
.unwrap_or_default()
}