From df2e06eac02c546632716ddc0227b0ab56b3f39f Mon Sep 17 00:00:00 2001 From: ripytide Date: Sun, 17 Nov 2024 17:44:43 +0000 Subject: [PATCH 1/2] fix: add warning when arch packages are not found --- Cargo.lock | 7 +++++ Cargo.toml | 1 + src/backends/arch.rs | 64 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b88436b..11d9a6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,6 +435,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + [[package]] name = "is-terminal" version = "0.4.13" @@ -528,6 +534,7 @@ dependencies = [ "dirs", "home", "hostname", + "indoc", "itertools", "libc", "log", diff --git a/Cargo.toml b/Cargo.toml index 920e644..2f5d1bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ walkdir = "2.5.0" toml_edit = "0.22.22" tempfile = "3.14.0" strum = {version = "0.26.3", features = ["derive"]} +indoc = "2.0.5" [dev-dependencies] assert_cmd = "2.0.16" diff --git a/src/backends/arch.rs b/src/backends/arch.rs index 042b4d4..f4d17c1 100644 --- a/src/backends/arch.rs +++ b/src/backends/arch.rs @@ -68,29 +68,67 @@ impl Backend for Arch { } } - let mut final_packages = BTreeMap::new(); + let mut packages = { + let mut final_packages = BTreeMap::new(); - for (main_package, opts) in packages { - let overridden = final_packages - .insert(main_package.clone(), Self::InstallOptions::default()) - .is_some(); - - if overridden { - log::warn!("Package {main_package} overwrote another entry"); - } - - for package in opts.optional_deps.iter() { + for (package, install_options) in packages { let overridden = final_packages .insert(package.clone(), Self::InstallOptions::default()) .is_some(); if overridden { - log::warn!("Dependency {package} of {main_package} overwrote another entry"); + log::warn!("Package {package} overwrote another entry"); + } + + for dependency in install_options.optional_deps.iter() { + let overridden = final_packages + .insert(dependency.clone(), Self::InstallOptions::default()) + .is_some(); + + if overridden { + log::warn!("arch package {dependency} has been overridden by a dependency of the {package} package"); + } } } + + final_packages + }; + + let packages_cloned = packages.keys().cloned().collect::>(); + + for package in packages_cloned { + let is_real_package = run_command( + [ + config.arch_package_manager.as_command(), + "--sync", + "--info", + &package, + ], + Perms::Same, + ) + .is_ok(); + + if !is_real_package { + packages.remove(&package); + + log::warn!( + "{}", + indoc::formatdoc! {" + arch package {package} was not found as an available package and so was ignored, it may be due to one of the following issues: + - the package name has a typo as written in your group files + - the package is a virtual package (https://wiki.archlinux.org/title/Pacman#Virtual_packages) + and so is ambiguous. You can run `pacman -S {package}` to list non-virtual packages which + which supply the virtual package + - the package was removed from the repositories + - the package was renamed to a different name + - the local package database is out of date and so doesn't yet contain the package: + update it with `sudo pacman -Sy` + "} + ); + } } - Ok(final_packages) + Ok(packages) } fn query_installed_packages(config: &Config) -> Result> { From 94c0a8d5247c403e239167a098ebc4dc24099f4b Mon Sep 17 00:00:00 2001 From: ripytide Date: Sun, 17 Nov 2024 21:46:24 +0000 Subject: [PATCH 2/2] refactor: make log messages quote packages --- src/backends/all.rs | 4 ++-- src/backends/arch.rs | 46 ++++++++++++++++++++++++++------------------ src/backends/dnf.rs | 6 +++--- src/core.rs | 4 ++-- src/groups.rs | 16 +++++++-------- 5 files changed, 42 insertions(+), 34 deletions(-) diff --git a/src/backends/all.rs b/src/backends/all.rs index 624536b..586d13e 100644 --- a/src/backends/all.rs +++ b/src/backends/all.rs @@ -125,8 +125,8 @@ macro_rules! package_ids { $( if !self.$lower_backend.is_empty() { writeln!(f, "[{}]", AnyBackend::$upper_backend)?; - for package_id in self.$lower_backend.iter() { - writeln!(f, "{package_id}")?; + for package in self.$lower_backend.iter() { + writeln!(f, "{package}")?; } writeln!(f)?; } diff --git a/src/backends/arch.rs b/src/backends/arch.rs index f4d17c1..c56974b 100644 --- a/src/backends/arch.rs +++ b/src/backends/arch.rs @@ -62,7 +62,7 @@ impl Backend for Arch { .is_some(); if overridden { - log::warn!("arch package {group_package} has been overridden by the {group} package group"); + log::warn!("arch package {group_package:?} has been overridden by the {group:?} package group"); } } } @@ -77,7 +77,7 @@ impl Backend for Arch { .is_some(); if overridden { - log::warn!("Package {package} overwrote another entry"); + log::warn!("Package {package:?} overwrote another entry"); } for dependency in install_options.optional_deps.iter() { @@ -86,7 +86,7 @@ impl Backend for Arch { .is_some(); if overridden { - log::warn!("arch package {dependency} has been overridden by a dependency of the {package} package"); + log::warn!("arch package {dependency:?} has been overridden by a dependency of the {package:?} package"); } } } @@ -96,17 +96,22 @@ impl Backend for Arch { let packages_cloned = packages.keys().cloned().collect::>(); + let all_packages: BTreeSet = run_command_for_stdout( + [ + config.arch_package_manager.as_command(), + "--sync", + "--list", + "--quiet", + ], + Perms::Same, + false, + )? + .lines() + .map(String::from) + .collect(); + for package in packages_cloned { - let is_real_package = run_command( - [ - config.arch_package_manager.as_command(), - "--sync", - "--info", - &package, - ], - Perms::Same, - ) - .is_ok(); + let is_real_package = all_packages.contains(&package); if !is_real_package { packages.remove(&package); @@ -114,15 +119,18 @@ impl Backend for Arch { log::warn!( "{}", indoc::formatdoc! {" - arch package {package} was not found as an available package and so was ignored, it may be due to one of the following issues: + arch package {package:?} was not found as an available package and so was ignored (you can test + if the package exists via `pacman -Si {package:?}` or similar command using your chosen AUR helper) + + it may be due to one of the following issues: - the package name has a typo as written in your group files - the package is a virtual package (https://wiki.archlinux.org/title/Pacman#Virtual_packages) - and so is ambiguous. You can run `pacman -S {package}` to list non-virtual packages which - which supply the virtual package + and so is ambiguous. You can run `pacman -Ss {package:?}` to list non-virtual packages which + which provide the virtual package - the package was removed from the repositories - the package was renamed to a different name - the local package database is out of date and so doesn't yet contain the package: - update it with `sudo pacman -Sy` + update it with `sudo pacman -Sy` or similar command using your chosen AUR helper "} ); } @@ -149,8 +157,8 @@ impl Backend for Arch { let mut result = BTreeMap::new(); - for package_id in explicit_packages.lines() { - result.insert(package_id.to_string(), ArchQueryInfo {}); + for package in explicit_packages.lines() { + result.insert(package.to_string(), ArchQueryInfo {}); } Ok(result) diff --git a/src/backends/dnf.rs b/src/backends/dnf.rs index c2ebb85..f1ac7b5 100644 --- a/src/backends/dnf.rs +++ b/src/backends/dnf.rs @@ -82,9 +82,9 @@ impl Backend for Dnf { .chain( packages .iter() - .flat_map(|(package_id, options)| match &options.repo { - Some(repo) => vec![package_id, "--repo", repo.as_str()], - None => vec![package_id.as_str()], + .flat_map(|(package, options)| match &options.repo { + Some(repo) => vec![package, "--repo", repo.as_str()], + None => vec![package.as_str()], }), ), Perms::Sudo, diff --git a/src/core.rs b/src/core.rs index a1b97a7..860ca9c 100644 --- a/src/core.rs +++ b/src/core.rs @@ -202,8 +202,8 @@ fn missing(managed: &InstallOptions, config: &Config) -> Result macro_rules! x { ($(($upper_backend:ident, $lower_backend:ident)),*) => { $( - for package_id in installed.$lower_backend { - missing.$lower_backend.remove(&package_id); + for package in installed.$lower_backend { + missing.$lower_backend.remove(&package); } )* }; diff --git a/src/groups.rs b/src/groups.rs index e07d211..7afaf95 100644 --- a/src/groups.rs +++ b/src/groups.rs @@ -39,9 +39,9 @@ impl Groups { macro_rules! x { ($(($upper_backend:ident, $lower_backend:ident)),*) => { $( - for package_id in raw_package_ids.$lower_backend { + for package in raw_package_ids.$lower_backend { reoriented - .entry((AnyBackend::$upper_backend, package_id.clone())) + .entry((AnyBackend::$upper_backend, package.clone())) .or_default() .entry(group_file.clone()) .or_default() @@ -54,9 +54,9 @@ impl Groups { } //warn the user about duplicated packages and output a deduplicated InstallOptions - for ((backend, package_id), group_files) in reoriented.iter() { + for ((backend, package), group_files) in reoriented.iter() { if group_files.len() > 1 { - log::warn!("duplicate {package_id:?} package in group files: {group_files:?} for the {backend} backend"); + log::warn!("duplicate {package:?} package in group files: {group_files:?} for the {backend} backend"); log::warn!("only one of the duplicated will be used which could may cause unintended behaviour if the duplicates have different install options"); } } @@ -144,9 +144,9 @@ fn parse_toml_key_value(group_file: &Path, key: &str, value: &Value) -> Result (x.to_string(), Default::default()), toml::Value::Table(x) => ( x.clone().try_into::()?.package, @@ -155,7 +155,7 @@ fn parse_toml_key_value(group_file: &Path, key: &str, value: &Value) -> Result return Err(eyre!("the {} backend in the {group_file:?} group file has a package which is neither a string or a table", $upper_backend)), }; - raw_install_options.$lower_backend.push((package_id, package_install_options)); + raw_install_options.$lower_backend.push((package, package_install_options)); } return Ok(raw_install_options);