Skip to content

Commit

Permalink
fix(package): fix multi-repo install handling
Browse files Browse the repository at this point in the history
  • Loading branch information
QaidVoid committed Oct 31, 2024
1 parent e94d480 commit 8654fbb
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 67 deletions.
2 changes: 1 addition & 1 deletion src/core/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub static PACKAGES_PATH: LazyLock<PathBuf> =

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;
75 changes: 35 additions & 40 deletions src/registry/installed.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, path::Path};
use std::collections::HashMap;

use anyhow::{Context, Result};
use chrono::{DateTime, Utc};
Expand All @@ -21,6 +21,7 @@ pub struct InstalledPackage {
pub repo_name: String,
pub collection: String,
pub name: String,
pub variant: Option<String>,
pub bin_name: String,
pub version: String,
pub checksum: String,
Expand Down Expand Up @@ -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('-')
})
}

Expand All @@ -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);
}

Expand All @@ -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 => {
Expand Down Expand Up @@ -221,19 +218,6 @@ impl InstalledPackages {
Ok(())
}

pub fn reverse_package_search(&self, path: &Path) -> Option<InstalledPackage> {
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
Expand Down Expand Up @@ -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)
}
}
3 changes: 1 addition & 2 deletions src/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<()> {
Expand Down
20 changes: 11 additions & 9 deletions src/registry/package/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -290,21 +290,23 @@ impl Installer {
Ok(())
}

async fn symlink_bin(&self, installed_packages: &Arc<Mutex<InstalledPackages>>) -> 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)? ",
Expand All @@ -319,7 +321,7 @@ impl Installer {
return Ok(());
}
}
}
};
}
}
fs::remove_file(symlink_path).await?;
Expand Down
4 changes: 2 additions & 2 deletions src/registry/package/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl ResolvedPackage {
multi_progress: Arc<MultiProgress>,
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(
Expand Down Expand Up @@ -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 {
Expand Down
24 changes: 11 additions & 13 deletions src/registry/package/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand All @@ -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<Vec<ResolvedPackage>> = r
Expand All @@ -37,7 +33,7 @@ impl Updater {
.collect();
resolved_packages?
}
None => installed_packages
None => installed_guard
.packages
.iter()
.filter_map(|installed| {
Expand All @@ -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);
}
Expand All @@ -74,6 +70,8 @@ impl Updater {
}
}

drop(installed_guard);

if packages_to_update.is_empty() {
error!("No updates available");
} else {
Expand Down

0 comments on commit 8654fbb

Please sign in to comment.