Skip to content

Commit

Permalink
feat(collection): allow dynamic collection names
Browse files Browse the repository at this point in the history
  • Loading branch information
QaidVoid committed Oct 20, 2024
1 parent a480c85 commit d37bad0
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 212 deletions.
54 changes: 27 additions & 27 deletions src/registry/fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ use crate::core::{
util::{download, get_platform},
};

use super::{package::Package, storage::RepositoryPackages};
use super::package::Package;

pub struct RegistryFetcher;

#[derive(Deserialize)]
struct RepositoryResponse {
bin: Vec<Package>,
base: Vec<Package>,
pkg: Vec<Package>,
#[serde(flatten)]
collection: HashMap<String, Vec<Package>>,
}

impl RegistryFetcher {
Expand All @@ -43,29 +42,30 @@ impl RegistryFetcher {
let parsed: RepositoryResponse =
serde_json::from_slice(&content).context("Failed to parse registry json")?;

let convert_to_hashmap = |packages: Vec<Package>| -> HashMap<String, Vec<Package>> {
let mut result = HashMap::new();
for package in packages {
let variant = package
.download_url
.split('/')
.rev()
.nth(1)
.map(|v| v.to_owned())
.filter(|v| v != ARCH && v != &platform && v != &platform.replace('-', "_"));
let package_entry = result
.entry(package.name.to_owned())
.or_insert_with(Vec::new);
package_entry.push(Package { variant, ..package });
}
result
};

let package_registry = RepositoryPackages {
bin: convert_to_hashmap(parsed.bin),
base: convert_to_hashmap(parsed.base),
pkg: convert_to_hashmap(parsed.pkg),
};
let package_registry: HashMap<String, HashMap<String, Vec<Package>>> = parsed
.collection
.iter()
.map(|(key, packages)| {
let package_map: HashMap<String, Vec<Package>> =
packages.iter().fold(HashMap::new(), |mut acc, package| {
acc.entry(package.name.clone()).or_default().push(Package {
variant: package
.download_url
.split('/')
.rev()
.nth(1)
.map(|v| v.to_owned())
.filter(|v| {
v != ARCH && v != &platform && v != &platform.replace('-', "_")
}),
..package.clone()
});
acc
});

(key.clone(), package_map)
})
.collect();

let content = rmp_serde::to_vec(&package_registry)
.context("Failed to serialize package registry to MessagePack")?;
Expand Down
8 changes: 4 additions & 4 deletions src/registry/installed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,23 +63,23 @@ 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.to_string()
&& installed.collection == package.collection
&& installed.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.to_string()
&& installed.collection == package.collection
&& installed.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.to_string()
&& installed.collection == package.collection
&& installed.name == package.package.full_name('-')
})
}
Expand Down Expand Up @@ -117,7 +117,7 @@ impl InstalledPackages {
true => {
self.packages.retain(|installed| {
!(installed.repo_name == resolved_package.repo_name
&& installed.collection == resolved_package.collection.to_string()
&& installed.collection == resolved_package.collection
&& installed.name == resolved_package.package.full_name('-'))
});
}
Expand Down
17 changes: 1 addition & 16 deletions src/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ use fetcher::RegistryFetcher;
use futures::future::try_join_all;
use installed::InstalledPackages;
use loader::RegistryLoader;
use package::{
image::PackageImage, parse_package_query, update::Updater, ResolvedPackage, Collection,
};
use package::{image::PackageImage, parse_package_query, update::Updater, ResolvedPackage};
use serde::Deserialize;
use storage::{PackageStorage, RepositoryPackages};
use tokio::{fs, sync::Mutex};
Expand Down Expand Up @@ -320,19 +318,6 @@ impl PackageRegistry {
}

pub async fn list(&self, collection: Option<&str>) -> Result<()> {
let collection = match collection {
Some(rp) => match rp.to_lowercase().as_str() {
"base" => Ok(Some(Collection::Base)),
"bin" => Ok(Some(Collection::Bin)),
"pkg" => Ok(Some(Collection::Pkg)),
_ => Err(anyhow::anyhow!(
"Invalid collection: {}",
rp.color(Color::BrightGreen)
)),
},
None => Ok(None),
}?;

let packages = self.storage.list_packages(collection);
for resolved_package in packages {
let package = resolved_package.package.clone();
Expand Down
8 changes: 4 additions & 4 deletions src/registry/package/appimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ fn is_appimage(file: &mut BufReader<File>) -> bool {
}

async fn create_symlink(from: &Path, to: &Path) -> Result<()> {
if to.exists() {
if to.read_link().is_ok() && !to.read_link()?.starts_with(&*PACKAGES_PATH) {
if to.is_symlink() {
if to.exists() && !to.read_link()?.starts_with(&*PACKAGES_PATH) {
error!(
"{} is not managed by soar",
to.to_string_lossy().color(Color::Blue)
Expand All @@ -109,8 +109,8 @@ async fn create_symlink(from: &Path, to: &Path) -> Result<()> {
}

async fn remove_link(path: &Path) -> Result<()> {
if path.exists() {
if path.read_link().is_ok() && !path.read_link()?.starts_with(&*PACKAGES_PATH) {
if path.is_symlink() {
if path.exists() && !path.read_link()?.starts_with(&*PACKAGES_PATH) {
error!(
"{} is not managed by soar",
path.to_string_lossy().color(Color::Blue)
Expand Down
10 changes: 4 additions & 6 deletions src/registry/package/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ use crate::{
error,
registry::{
installed::InstalledPackages,
package::{
appimage::{check_user_ns, extract_appimage, setup_portable_dir},
Collection,
},
package::appimage::{check_user_ns, extract_appimage, setup_portable_dir},
},
warn,
};
Expand Down Expand Up @@ -169,7 +166,8 @@ impl Installer {

self.save_file().await?;
self.symlink_bin(&installed_packages).await?;
if self.resolved_package.collection == Collection::Pkg {
// TODO: use magic bytes instead
if self.resolved_package.collection == "pkg" {
extract_appimage(package, &self.install_path).await?;
setup_portable_dir(
&package.bin_name,
Expand Down Expand Up @@ -201,7 +199,7 @@ impl Installer {
);
}

if self.resolved_package.collection == Collection::Pkg {
if self.resolved_package.collection == "pkg" {
check_user_ns().await;
}

Expand Down
60 changes: 5 additions & 55 deletions src/registry/package/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,15 @@ mod remove;
pub mod run;
pub mod update;

use std::{fmt::Display, path::PathBuf, sync::Arc};
use std::{path::PathBuf, sync::Arc};

use anyhow::Result;
use install::Installer;
use remove::Remover;
use serde::{Deserialize, Serialize};
use tokio::sync::Mutex;

use crate::{
core::{
color::{Color, ColorExt},
constant::PACKAGES_PATH,
},
error,
};
use crate::core::constant::PACKAGES_PATH;

use super::installed::InstalledPackages;

Expand Down Expand Up @@ -47,7 +41,7 @@ pub struct Package {
#[derive(Default, Debug, Clone)]
pub struct ResolvedPackage {
pub repo_name: String,
pub collection: Collection,
pub collection: String,
pub package: Package,
}

Expand Down Expand Up @@ -111,37 +105,13 @@ impl Package {
pub struct PackageQuery {
pub name: String,
pub variant: Option<String>,
pub collection: Option<Collection>,
}

#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub enum Collection {
#[default]
Bin,
Base,
Pkg,
pub collection: Option<String>,
}

pub fn parse_package_query(query: &str) -> PackageQuery {
let (base_query, collection) = query
.rsplit_once('#')
.map(|(n, r)| {
(
n.to_owned(),
match r.to_lowercase().as_str() {
"base" => Some(Collection::Base),
"bin" => Some(Collection::Bin),
"pkg" => Some(Collection::Pkg),
_ => {
error!(
"Invalid collection path provided for {}",
query.color(Color::Red)
);
std::process::exit(-1);
}
},
)
})
.map(|(n, r)| (n.to_owned(), (!r.is_empty()).then(|| r.to_lowercase())))
.unwrap_or((query.to_owned(), None));

let (name, variant) = base_query
Expand All @@ -155,23 +125,3 @@ pub fn parse_package_query(query: &str) -> PackageQuery {
collection,
}
}

impl Display for Collection {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Collection::Bin => write!(f, "bin"),
Collection::Base => write!(f, "base"),
Collection::Pkg => write!(f, "pkg"),
}
}
}

impl From<String> for Collection {
fn from(value: String) -> Self {
match value.as_ref() {
"base" => Collection::Base,
"pkg" => Collection::Pkg,
_ => Collection::Bin,
}
}
}
Loading

0 comments on commit d37bad0

Please sign in to comment.