Skip to content

Commit

Permalink
Don't igore Install Options and skip empty backends for unmanaged (#38
Browse files Browse the repository at this point in the history
)

* fix: install options fixes #30

* refactor: switch PackageIds and RawPackageIds back to macro form for consistency

* fix: don't serialize empty backends
  • Loading branch information
ripytide authored Oct 29, 2024
1 parent eeffcf4 commit 305237d
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 106 deletions.
157 changes: 73 additions & 84 deletions src/backends/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,16 @@ macro_rules! is_empty {
macro_rules! to_package_ids {
($($backend:ident),*) => {
pub fn to_package_ids(&self) -> PackageIds {
PackageIds (
BTreeMap::from([
$( (AnyBackend::$backend, self.$backend.keys().cloned().collect()), )*
])
)
PackageIds {
$( $backend: self.$backend.keys().cloned().collect() ),*
}
}
};
}

macro_rules! any {
($($backend:ident),*) => {
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, derive_more::FromStr, derive_more::Display)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, derive_more::FromStr, derive_more::Display)]
pub enum AnyBackend {
$($backend,)*
}
Expand All @@ -51,93 +49,86 @@ macro_rules! any {
}
apply_public_backends!(any);

#[derive(Debug, Clone, Default, Serialize, derive_more::Deref, derive_more::DerefMut)]
#[serde(transparent)]
pub struct RawPackageIds(BTreeMap<AnyBackend, Vec<String>>);
impl RawPackageIds {
pub fn contains(&self, backend: AnyBackend, package: &String) -> bool {
self.get(&backend).is_some_and(|x| x.contains(package))
macro_rules! raw_package_ids {
($($backend:ident),*) => {
#[derive(Debug, Clone, Default)]
#[allow(non_snake_case)]
pub struct RawPackageIds {
$(
pub $backend: Vec<String>,
)*
}
impl RawPackageIds {
pub fn contains(&self, backend: AnyBackend, package: &str) -> bool {
match backend {
$( AnyBackend::$backend => self.$backend.iter().any(|p| p == package) ),*
}
}
}
}
}
apply_public_backends!(raw_package_ids);

#[derive(Debug, Clone, Default, Serialize, derive_more::Deref, derive_more::DerefMut)]
#[serde(transparent)]
pub struct PackageIds(BTreeMap<AnyBackend, BTreeSet<String>>);
impl PackageIds {
pub fn append(&mut self, other: &mut Self) {
for (backend, packages) in other.iter_mut() {
self.entry(*backend).or_default().append(packages);
macro_rules! package_ids {
($($backend:ident),*) => {
#[derive(Debug, Clone, Default, Serialize)]
#[allow(non_snake_case)]
pub struct PackageIds {
$(
#[serde(skip_serializing_if = "BTreeSet::is_empty")]
pub $backend: BTreeSet<String>,
)*
}
}
impl PackageIds {
append!($($backend),*);
is_empty!($($backend),*);

pub fn is_empty(&self) -> bool {
self.values().all(|x| x.is_empty())
}
pub fn contains(&self, backend: AnyBackend, package: &str) -> bool {
match backend {
$( AnyBackend::$backend => self.$backend.contains(package) ),*
}
}

pub fn contains(&self, backend: AnyBackend, package: &str) -> bool {
self.get(&backend).is_some_and(|x| x.contains(package))
}
pub fn remove(&mut self, backend: AnyBackend, package: &str) -> bool {
match backend {
$( AnyBackend::$backend => self.$backend.remove(package) ),*
}
}

pub fn remove(&mut self, backend: AnyBackend, package: &str) -> bool {
if let Some(packages) = self.get_mut(&backend) {
packages.remove(package)
} else {
false
}
}
pub fn difference(&self, other: &Self) -> Self {
let mut output = Self::default();

pub fn difference(&self, other: &Self) -> Self {
let mut output = Self::default();
for (backend, packages) in self.iter() {
if let Some(other_packages) = other.get(backend) {
output.0.insert(
*backend,
packages.difference(other_packages).cloned().collect(),
);
}
}
output
}
$(
output.$backend = self.$backend.difference(&other.$backend).cloned().collect();
)*

pub fn remove_packages(&self, no_confirm: bool, config: &Config) -> Result<()> {
for (backend, packages) in self.0.iter() {
if is_enabled(*backend, config) {
backend.remove_packages(packages, no_confirm, config)?;
output
}
}

Ok(())
}
}
impl std::fmt::Display for PackageIds {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for (backend, packages) in self.iter() {
if !packages.is_empty() {
writeln!(f, "[{backend}]")?;
for package in packages {
writeln!(f, "{package}")?;
}
writeln!(f)?;
pub fn remove_packages(&self, no_confirm: bool, config: &Config) -> Result<()> {
$(
if is_enabled(AnyBackend::$backend, config) {
AnyBackend::$backend.remove_packages(&self.$backend, no_confirm, config)?;
}
)*

Ok(())
}
}
Ok(())
}
}
macro_rules! package_ids {
($($backend:ident),*) => {
impl PackageIds {
pub fn to_install_options(self) -> InstallOptions {
InstallOptions {
$(
$backend: if let Some(packages) = self.get(&AnyBackend::$backend) {
packages.iter().map(|x| (x.clone(), <$backend as Backend>::InstallOptions::default())).collect()
} else {
Default::default()
},
)*
}
}
impl std::fmt::Display for PackageIds {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
$(
if !self.$backend.is_empty() {
writeln!(f, "[{}]", AnyBackend::$backend)?;
for package_id in self.$backend.iter() {
writeln!(f, "{package_id}")?;
}
writeln!(f)?;
}
)*

Ok(())
}
}
}
}
Expand Down Expand Up @@ -187,11 +178,9 @@ macro_rules! raw_install_options {
append!($($backend),*);

pub fn to_raw_package_ids(&self) -> RawPackageIds {
RawPackageIds(
BTreeMap::from([
$( (AnyBackend::$backend, self.$backend.iter().map(|(x, _)| x).cloned().collect()), )*
])
)
RawPackageIds {
$( $backend: self.$backend.iter().map(|(x, _)| x).cloned().collect() ),*
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/backends/arch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ impl Backend for Arch {

let mut result = BTreeMap::new();

for package in explicit_packages.lines() {
result.insert(package.to_string(), ArchQueryInfo {});
for package_id in explicit_packages.lines() {
result.insert(package_id.to_string(), ArchQueryInfo {});
}

Ok(result)
Expand Down
27 changes: 19 additions & 8 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ impl SyncCommand {
return Ok(());
}

println!("{missing}");
println!("{}", missing.to_package_ids());

println!("these packages will be installed\n");

Expand All @@ -152,9 +152,7 @@ impl SyncCommand {
return Ok(());
}

missing
.to_install_options()
.install_packages(self.no_confirm, config)
missing.install_packages(self.no_confirm, config)
}
}

Expand All @@ -176,8 +174,21 @@ fn unmanaged(managed: &InstallOptions, config: &Config) -> Result<PackageIds> {
QueryInfos::query_installed_packages(config)
.map(|x| x.to_package_ids().difference(&managed.to_package_ids()))
}
fn missing(managed: &InstallOptions, config: &Config) -> Result<PackageIds> {
Ok(managed
.to_package_ids()
.difference(&QueryInfos::query_installed_packages(config)?.to_package_ids()))
fn missing(managed: &InstallOptions, config: &Config) -> Result<InstallOptions> {
let installed = QueryInfos::query_installed_packages(config)?.to_package_ids();

let mut missing = managed.clone();

macro_rules! x {
($($backend:ident),*) => {
$(
for package_id in installed.$backend {
missing.$backend.remove(&package_id);
}
)*
};
}
apply_public_backends!(x);

Ok(missing)
}
31 changes: 19 additions & 12 deletions src/groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::{
pub struct Groups(BTreeMap<PathBuf, RawInstallOptions>);

impl Groups {
pub fn contains(&self, backend: AnyBackend, package: &String) -> Vec<PathBuf> {
pub fn contains(&self, backend: AnyBackend, package: &str) -> Vec<PathBuf> {
let mut result = Vec::new();
for (group_file, raw_install_options) in self.0.iter() {
if raw_install_options
Expand All @@ -34,16 +34,23 @@ impl Groups {
BTreeMap::new();

for (group_file, raw_install_options) in self.iter() {
for (backend, package_ids) in raw_install_options.to_raw_package_ids().iter() {
for package_id in package_ids {
reoriented
.entry((*backend, package_id.clone()))
.or_default()
.entry(group_file.clone())
.or_default()
.add_assign(1);
}
let raw_package_ids = raw_install_options.to_raw_package_ids();

macro_rules! x {
($($backend:ident),*) => {
$(
for package_id in raw_package_ids.$backend {
reoriented
.entry((AnyBackend::$backend, package_id.clone()))
.or_default()
.entry(group_file.clone())
.or_default()
.add_assign(1);
}
)*
};
}
apply_public_backends!(x);
}

//warn the user about duplicated packages and output a deduplicated InstallOptions
Expand Down Expand Up @@ -137,9 +144,9 @@ fn parse_toml_key_value(group_file: &Path, key: &str, value: &Value) -> Result<R
eyre!("the {} backend in the {group_file:?} group file has a non-array value", $backend)
)?;

for package in packages {
for package_id in packages {
let (package_id, package_install_options) =
match package {
match package_id {
toml::Value::String(x) => (x.to_string(), Default::default()),
toml::Value::Table(x) => (
x.clone().try_into::<StringPackageStruct>()?.package,
Expand Down

0 comments on commit 305237d

Please sign in to comment.