diff --git a/src/core/constant.rs b/src/core/constant.rs index 8b2b7eb..e5f86cf 100644 --- a/src/core/constant.rs +++ b/src/core/constant.rs @@ -15,7 +15,7 @@ pub static PACKAGES_PATH: LazyLock = pub const ELF_MAGIC_BYTES: [u8; 4] = [0x7f, 0x45, 0x4c, 0x46]; pub const APPIMAGE_MAGIC_BYTES: [u8; 4] = [0x41, 0x49, 0x02, 0x00]; -pub const FLATIMAGE_MAGIC_BYTES: [u8; 4] = [0x46, 0x49, 0x02, 0x00]; +pub const FLATIMAGE_MAGIC_BYTES: [u8; 4] = [0x46, 0x49, 0x01, 0x00]; pub const CAP_SYS_ADMIN: i32 = 21; pub const CAP_MKNOD: i32 = 27; diff --git a/src/registry/installed.rs b/src/registry/installed.rs index 1f32387..d3ea436 100644 --- a/src/registry/installed.rs +++ b/src/registry/installed.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, path::Path}; +use std::collections::HashMap; use anyhow::{Context, Result}; use chrono::{DateTime, Utc}; @@ -21,6 +21,7 @@ pub struct InstalledPackage { pub repo_name: String, pub collection: String, pub name: String, + pub variant: Option, pub bin_name: String, pub version: String, pub checksum: String, @@ -61,26 +62,22 @@ impl InstalledPackages { } pub fn is_installed(&self, package: &ResolvedPackage) -> bool { - self.packages.iter().any(|installed| { - installed.repo_name == package.repo_name - && installed.collection == package.collection - && installed.name == package.package.full_name('-') - }) + self.packages + .iter() + .any(|installed| installed.full_name('-') == package.package.full_name('-')) } fn find_package_mut(&mut self, package: &ResolvedPackage) -> Option<&mut InstalledPackage> { - self.packages.iter_mut().find(|installed| { - installed.repo_name == package.repo_name - && installed.collection == package.collection - && installed.name == package.package.full_name('-') - }) + self.packages + .iter_mut() + .find(|installed| installed.full_name('-') == package.package.full_name('-')) } pub fn find_package(&self, package: &ResolvedPackage) -> Option<&InstalledPackage> { self.packages.iter().find(|installed| { installed.repo_name == package.repo_name && installed.collection == package.collection - && installed.name == package.package.full_name('-') + && installed.full_name('-') == package.package.full_name('-') }) } @@ -90,20 +87,22 @@ impl InstalledPackages { checksum: &str, ) -> Result<()> { let package = resolved_package.package.to_owned(); + + let new_installed = InstalledPackage { + repo_name: resolved_package.repo_name.to_owned(), + collection: resolved_package.collection.to_string().to_owned(), + name: package.name, + variant: package.variant, + bin_name: package.bin_name, + version: package.version, + checksum: checksum.to_owned(), + size: parse_size(&package.size).unwrap_or_default(), + timestamp: Utc::now(), + }; + if let Some(installed) = self.find_package_mut(resolved_package) { - installed.version = package.version.clone(); - installed.checksum = package.bsum.clone(); + *installed = new_installed; } else { - let new_installed = InstalledPackage { - repo_name: resolved_package.repo_name.to_owned(), - collection: resolved_package.collection.to_string().to_owned(), - name: package.full_name('-'), - bin_name: package.bin_name, - version: package.version, - checksum: checksum.to_owned(), - size: parse_size(&package.size).unwrap_or_default(), - timestamp: Utc::now(), - }; self.packages.push(new_installed); } @@ -116,9 +115,7 @@ impl InstalledPackages { match self.is_installed(resolved_package) { true => { self.packages.retain(|installed| { - !(installed.repo_name == resolved_package.repo_name - && installed.collection == resolved_package.collection - && installed.name == resolved_package.package.full_name('-')) + installed.full_name('-') != resolved_package.package.full_name('-') }); } false => { @@ -221,19 +218,6 @@ impl InstalledPackages { Ok(()) } - pub fn reverse_package_search(&self, path: &Path) -> Option { - let path_str = path.to_string_lossy(); - if path_str.len() > 64 { - let checksum = &path_str[..64]; - self.packages - .iter() - .find(|package| package.checksum == checksum) - .cloned() - } else { - None - } - } - pub async fn use_package(&self, resolved_package: &ResolvedPackage) -> Result<()> { if let Some(installed) = self.find_package(resolved_package) { let install_path = resolved_package @@ -265,3 +249,14 @@ impl InstalledPackages { Ok(()) } } + +impl InstalledPackage { + pub fn full_name(&self, join_char: char) -> String { + let variant_prefix = self + .variant + .to_owned() + .map(|variant| format!("{}{}", variant, join_char)) + .unwrap_or_default(); + format!("{}{}", variant_prefix, self.name) + } +} diff --git a/src/registry/mod.rs b/src/registry/mod.rs index 5594ff3..2cb9dcd 100644 --- a/src/registry/mod.rs +++ b/src/registry/mod.rs @@ -283,9 +283,8 @@ impl PackageRegistry { } pub async fn update(&self, package_names: Option<&[String]>) -> Result<()> { - let mut installed_guard = self.installed_packages.lock().await; let updater = Updater::new(package_names); - updater.execute(self, &mut installed_guard).await + updater.execute(self).await } pub async fn info(&self, package_names: Option<&[String]>) -> Result<()> { diff --git a/src/registry/package/install.rs b/src/registry/package/install.rs index affcd83..4539eed 100644 --- a/src/registry/package/install.rs +++ b/src/registry/package/install.rs @@ -207,7 +207,7 @@ impl Installer { } self.save_file().await?; - self.symlink_bin(&installed_packages).await?; + self.symlink_bin().await?; let mut file = BufReader::new(File::open(&self.install_path)?); let file_type = get_file_type(&mut file); @@ -290,21 +290,23 @@ impl Installer { Ok(()) } - async fn symlink_bin(&self, installed_packages: &Arc>) -> Result<()> { + async fn symlink_bin(&self) -> Result<()> { let package = &self.resolved_package.package; let install_path = &self.install_path; let symlink_path = &BIN_PATH.join(&package.bin_name); - let installed_guard = installed_packages.lock().await; if symlink_path.exists() { if let Ok(link) = symlink_path.read_link() { if &link != install_path { - if let Some(path_owner) = - installed_guard.reverse_package_search(link.strip_prefix(&*PACKAGES_PATH)?) - { - if path_owner.name != package.full_name('-') { + if let Ok(parent) = link.strip_prefix(&*PACKAGES_PATH) { + let package_name = + parent.parent().unwrap().to_string_lossy()[9..].replacen("-", "/", 1); + + if package_name == package.full_name('-') { + fs::remove_dir_all(link.parent().unwrap()).await?; + } else { warn!( "The package {} owns the binary {}", - path_owner.name, &package.bin_name + package_name, &package.bin_name ); print!( "Do you want to switch to {} (y/N)? ", @@ -319,7 +321,7 @@ impl Installer { return Ok(()); } } - } + }; } } fs::remove_file(symlink_path).await?; diff --git a/src/registry/package/mod.rs b/src/registry/package/mod.rs index 9fa2ae5..7832cda 100644 --- a/src/registry/package/mod.rs +++ b/src/registry/package/mod.rs @@ -60,7 +60,7 @@ impl ResolvedPackage { multi_progress: Arc, yes: bool, ) -> Result<()> { - let install_path = self.package.get_install_path(&self.package.bsum); + let install_path = self.package.get_install_path(&self.package.bsum[..8]); let mut installer = Installer::new(self, install_path); installer .execute( @@ -88,7 +88,7 @@ impl ResolvedPackage { impl Package { pub fn get_install_dir(&self, checksum: &str) -> PathBuf { - PACKAGES_PATH.join(format!("{}-{}", checksum, self.full_name('-'))) + PACKAGES_PATH.join(format!("{}-{}", &checksum[..8], self.full_name('-'))) } pub fn get_install_path(&self, checksum: &str) -> PathBuf { diff --git a/src/registry/package/update.rs b/src/registry/package/update.rs index 725233d..4804550 100644 --- a/src/registry/package/update.rs +++ b/src/registry/package/update.rs @@ -2,12 +2,11 @@ use std::sync::Arc; use anyhow::Result; use indicatif::MultiProgress; -use tokio::sync::MutexGuard; use crate::{ core::color::{Color, ColorExt}, error, - registry::{installed::InstalledPackages, PackageRegistry}, + registry::PackageRegistry, success, }; @@ -24,11 +23,8 @@ impl Updater { } } - pub async fn execute( - &self, - registry: &PackageRegistry, - installed_packages: &mut MutexGuard<'_, InstalledPackages>, - ) -> Result<()> { + pub async fn execute(&self, registry: &PackageRegistry) -> Result<()> { + let installed_guard = registry.installed_packages.lock().await; let packages = match &self.package_names { Some(r) => { let resolved_packages: Result> = r @@ -37,7 +33,7 @@ impl Updater { .collect(); resolved_packages? } - None => installed_packages + None => installed_guard .packages .iter() .filter_map(|installed| { @@ -58,11 +54,11 @@ impl Updater { let multi_progress = Arc::new(MultiProgress::new()); for package in packages { - if let Some(installed_package) = installed_packages.packages.iter().find(|installed| { - installed.repo_name == package.repo_name - && installed.name == package.package.full_name('/') - && installed.collection == package.collection - }) { + if let Some(installed_package) = installed_guard + .packages + .iter() + .find(|installed| installed.full_name('-') == package.package.full_name('-')) + { if installed_package.checksum != package.package.bsum { packages_to_update.push(package); } @@ -74,6 +70,8 @@ impl Updater { } } + drop(installed_guard); + if packages_to_update.is_empty() { error!("No updates available"); } else {