From 091fd3488d65bc1ea68360f02b9ec3f6347e1bbc Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Mon, 30 Jan 2023 14:36:00 +0100 Subject: [PATCH 1/8] fix bug when nothing to install for a specific backend --- src/backend/todo_per_backend.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backend/todo_per_backend.rs b/src/backend/todo_per_backend.rs index c2e26d7..2495045 100644 --- a/src/backend/todo_per_backend.rs +++ b/src/backend/todo_per_backend.rs @@ -46,6 +46,9 @@ impl ToDoPerBackend { F: Fn(&'a dyn Backend, &'a [Package]) -> Result, { for (backend, packages) in &self.0 { + if packages.is_empty() { + continue; + } let exit_status = func(&**backend, packages).with_context(|| { format!("{verb_continuous} packages for {}", backend.get_binary()) })?; From aa9cdbf3623f302665a96997674f68a4645d66f1 Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Mon, 30 Jan 2023 14:39:27 +0100 Subject: [PATCH 2/8] Revert "more review stuff" This reverts commit b95f3889bb982b79351dace96811e8968062917b. This is WIP and does not compile right now. See branch `review`. --- src/backend/actual/pacman.rs | 4 - src/backend/actual/rust.rs | 4 - src/backend/backend_trait.rs | 2 - src/review.rs | 227 +++++++++++++++-------------------- 4 files changed, 99 insertions(+), 138 deletions(-) diff --git a/src/backend/actual/pacman.rs b/src/backend/actual/pacman.rs index f8a8344..36afe6d 100644 --- a/src/backend/actual/pacman.rs +++ b/src/backend/actual/pacman.rs @@ -67,10 +67,6 @@ impl Backend for Pacman { cmd.status() .with_context(|| format!("running command [{cmd:?}]")) } - - fn supports_assigning_packages_as_dependency(&self) -> bool { - true - } } fn get_all_installed_packages_from_alpm() -> Result> { diff --git a/src/backend/actual/rust.rs b/src/backend/actual/rust.rs index 706d909..b4317c5 100644 --- a/src/backend/actual/rust.rs +++ b/src/backend/actual/rust.rs @@ -31,10 +31,6 @@ impl Backend for Rust { self.get_all_installed_packages() .context("getting all installed packages") } - - fn supports_assigning_packages_as_dependency(&self) -> bool { - false - } } fn extract_packages(json: Value) -> Result> { diff --git a/src/backend/backend_trait.rs b/src/backend/backend_trait.rs index d375de5..6376d92 100644 --- a/src/backend/backend_trait.rs +++ b/src/backend/backend_trait.rs @@ -33,8 +33,6 @@ pub(crate) trait Backend { .with_context(|| format!("running command {cmd:?}")) } - fn supports_assigning_packages_as_dependency(&self) -> bool; - /// Remove the specified packages. fn remove_packages(&self, packages: &[Package]) -> Result { let mut cmd = Command::new(self.get_binary()); diff --git a/src/review.rs b/src/review.rs index e28998e..d94274d 100644 --- a/src/review.rs +++ b/src/review.rs @@ -7,7 +7,6 @@ use termios::*; use crate::backend::{Backend, Backends, ToDoPerBackend}; use crate::grouping::{Group, Package, Section}; -use crate::ui::get_user_confirmation; #[derive(Debug)] enum ReviewAction { @@ -20,80 +19,23 @@ enum ReviewAction { Quit, } -struct Reviews { - pub delete: Vec, - pub assign: Vec, - pub as_dependency: Vec, +struct Reviews<'a> { + pub delete: Vec<(Rc>, Package)>, + pub assign: Vec<(Rc>, Package, &'a Group, &'a Section)>, } -struct AsDependency { - backend: Rc>, - package: Package, -} - -impl AsDependency { - fn new(backend: Rc>, package: Package) -> Self { - Self { backend, package } - } -} - -struct Assign { - backend: Rc>, - package: Package, - group: Rc, -} - -impl Assign { - fn new(backend: Rc>, package: Package, group: Rc) -> Self { - Self { - backend, - package, - group, - } - } -} - -struct Delete { - items: Vec<> - backend: Rc>, - package: Package, -} - -impl Delete { - fn new(backend: Rc>, package: Package) -> Self { - Self { backend, package } - } -} - -impl Reviews { +impl<'a> Reviews<'a> { fn new() -> Self { Self { delete: vec![], assign: vec![], - as_dependency: vec![], } } - - fn show_strategy(&mut self) { - self.delete - .sort_by_key(|d| (&d.backend.get_section(), &d.package)); - if !self.delete.is_empty() { - println!("Will delete the following packages:"); - let mut iter = self.delete.iter().peekable(); - // while let Some(delete) = iter.next() { - // delete. - // } - } - } - - fn execute(&self) -> Result<()> { - todo!() - } } pub(crate) fn review(todo_per_backend: ToDoPerBackend, groups: HashSet) -> Result<()> { let mut reviews = Reviews::new(); - let mut groups: Vec<_> = groups.into_iter().map(Rc::new).collect(); + let mut groups: Vec<_> = groups.into_iter().collect(); groups.sort_unstable(); if todo_per_backend.nothing_to_do_for_all_backends() { @@ -101,87 +43,110 @@ pub(crate) fn review(todo_per_backend: ToDoPerBackend, groups: HashSet) - return Ok(()); } - gather_reviews(todo_per_backend, groups, &mut reviews)?; - - reviews.show_strategy(); - - if !get_user_confirmation() { - return Ok(()); - } - - reviews.execute() -} - -fn gather_reviews( - todo_per_backend: ToDoPerBackend, - groups: Vec>, - reviews: &mut Reviews, -) -> Result<()> { for (backend, packages) in todo_per_backend.into_iter() { let backend = Rc::new(backend); for package in packages { println!("{}: {package}", backend.get_section()); - get_action_for_package(package, &groups, reviews, &backend)?; + get_action_for_package(package, &groups, &mut reviews, &backend)?; } } - Ok(()) + + todo!() } fn get_action_for_package( package: Package, - groups: &[Rc], + groups: &[Group], reviews: &mut Reviews, backend: &Rc>, ) -> Result<()> { - loop { - match ask_user_action_for_package(backend)? { - ReviewAction::AsDependency => { - let as_dependency = AsDependency::new(backend.clone(), package); - reviews.as_dependency.push(as_dependency); - break; - } - ReviewAction::AssignGroupBackend => { - if let Some(group) = assign_group(groups)? { - let assign = Assign::new(backend.clone(), package, group); - reviews.assign.push(assign); - break; - }; - } - ReviewAction::Delete => { - let delete = Delete::new(backend.clone(), package); - reviews.delete.push(delete); - break; - } - ReviewAction::Info => backend.show_package_info(&package)?, - ReviewAction::Invalid => (), - ReviewAction::Skip => break, - ReviewAction::Quit => bail!("user wants to quit"), // TODO requires an own error type? - } - } + todo!(); + // loop { + // match ask_user_action_for_package()? { + // ReviewAction::AsDependency => todo!(), + // ReviewAction::AssignGroupBackend => { + // if let Some(val) = assign_group_backend(&package, groups)? { + // break; + // }; + // } + // ReviewAction::Delete => { + // reviews.delete.push((backend.clone(), package)); + // break; + // } + // ReviewAction::Info => backend.show_package_info(&package)?, + // ReviewAction::Invalid => (), + // ReviewAction::Skip => break, + // ReviewAction::Quit => bail!("user wants to quit"), + // } + // } Ok(()) } -fn ask_user_action_for_package(backend: &Rc>) -> Result { - if backend.supports_assigning_packages_as_dependency() { - ask_action_including_dependency() +fn ask_user_group_section(groups: &[Group]) -> Result> { + let group = match ask_group(groups)? { + Some(group) => group, + None => return Ok(None), + }; + + let section_reply = match ask_section(&group.sections)? { + Some(reply) => reply, + None => return Ok(None), + }; + + let section = match section_reply { + SectionReply::Existing(section) => section, + SectionReply::New => return Ok(Some(GroupSectionReply::New)), + }; + + Ok(Some(GroupSectionReply::Existing((group, section)))) +} + +enum GroupSectionReply<'a> { + Existing((&'a Group, &'a Section)), + New, +} + +enum SectionReply<'a> { + Existing(&'a Section), + New, +} + +fn ask_section(sections: &HashSet
) -> Result> { + let sections: Vec<_> = sections.iter().collect(); + + let mut buf = String::new(); + stdin().read_line(&mut buf)?; + let reply = buf.trim(); + + let idx: usize = if let Ok(idx) = reply.parse() { + idx } else { - ask_action_without_dependency() + return Ok(None); + }; + + if idx < sections.len() { + Ok(Some(SectionReply::Existing(§ions[idx]))) + } else if idx == sections.len() { + Ok(Some(SectionReply::New)) + } else { + Ok(None) } } -fn ask_action_without_dependency() -> Result { - print!("assign to (g)roup, (d)elete, (s)kip, (i)nfo, (q)uit? "); - match read_single_char_from_terminal()? { - 'd' => Ok(ReviewAction::Delete), - 'g' => Ok(ReviewAction::AssignGroupBackend), - 'i' => Ok(ReviewAction::Info), - 'q' => Ok(ReviewAction::Quit), - 's' => Ok(ReviewAction::Skip), - _ => Ok(ReviewAction::Invalid), - } +fn ask_new_section_name() -> Result { + print!("new section name: "); + let reply = stdin().lines().next().context("reading line from stdin")?; + reply.map_err(|e| anyhow!(e)) } -fn ask_action_including_dependency() -> Result { +fn print_enumerated_sections(sections: &[Section]) { + for (i, section) in sections.iter().enumerate() { + println!("{i}: {}", section.name); + } + println!("{}: [new]", sections.len()); +} + +fn ask_user_action_for_package() -> Result { print!("assign to (g)roup, (d)elete, (s)kip, (i)nfo, (a)s dependency, (q)uit? "); match read_single_char_from_terminal()? { 'a' => Ok(ReviewAction::AsDependency), @@ -212,13 +177,14 @@ fn read_single_char_from_terminal() -> Result { Ok(result) } -fn print_enumerated_groups(groups: &[Rc]) { +fn print_enumerated_groups(groups: &[Group]) { for (i, group) in groups.iter().enumerate() { println!("{i}: {}", group.name); } } -fn ask_group(groups: &[Rc]) -> Result>> { +fn ask_group(groups: &[Group]) -> Result> { + print_enumerated_groups(groups); let mut buf = String::new(); stdin().read_line(&mut buf)?; let reply = buf.trim(); @@ -230,13 +196,18 @@ fn ask_group(groups: &[Rc]) -> Result>> { }; if idx < groups.len() { - Ok(Some(groups[idx].clone())) + Ok(Some(&groups[idx])) } else { Ok(None) } } -fn assign_group(groups: &[Rc]) -> Result>> { - print_enumerated_groups(groups); - ask_group(groups) +fn assign_group_backend(package: &Package, groups: &[Group]) -> Result<()> { + let reply = ask_user_group_section(groups)?; + match reply { + Some(val) => todo!(), + None => todo!(), + } + + todo!() } From ed7acaf69df85b2e45e88bb4ead23abc34a8186c Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Mon, 30 Jan 2023 14:57:40 +0100 Subject: [PATCH 3/8] add `Debug` supertrait for `Backend` --- src/backend/actual/pacman.rs | 1 + src/backend/actual/rust.rs | 1 + src/backend/backend_trait.rs | 3 ++- src/backend/todo_per_backend.rs | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backend/actual/pacman.rs b/src/backend/actual/pacman.rs index 36afe6d..b8b8653 100644 --- a/src/backend/actual/pacman.rs +++ b/src/backend/actual/pacman.rs @@ -8,6 +8,7 @@ use anyhow::{Context, Result}; use crate::backend::backend_trait::*; use crate::{impl_backend_constants, Group, Package}; +#[derive(Debug)] pub(crate) struct Pacman { pub(crate) binary: String, pub(crate) aur_rm_args: Option>, diff --git a/src/backend/actual/rust.rs b/src/backend/actual/rust.rs index b4317c5..e102060 100644 --- a/src/backend/actual/rust.rs +++ b/src/backend/actual/rust.rs @@ -8,6 +8,7 @@ use serde_json::Value; use crate::backend::backend_trait::*; use crate::{impl_backend_constants, Group, Package}; +#[derive(Debug)] pub(crate) struct Rust { pub(crate) packages: HashSet, } diff --git a/src/backend/backend_trait.rs b/src/backend/backend_trait.rs index 6376d92..2d1339e 100644 --- a/src/backend/backend_trait.rs +++ b/src/backend/backend_trait.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::process::Command; use std::{collections::HashSet, process::ExitStatus}; @@ -8,7 +9,7 @@ use crate::{Group, Package}; pub(in crate::backend) type Switches = &'static [&'static str]; pub(in crate::backend) type Text = &'static str; -pub(crate) trait Backend { +pub(crate) trait Backend: Debug { fn get_binary(&self) -> Text; fn get_section(&self) -> Text; fn get_switches_install(&self) -> Switches; diff --git a/src/backend/todo_per_backend.rs b/src/backend/todo_per_backend.rs index 2495045..98fc80e 100644 --- a/src/backend/todo_per_backend.rs +++ b/src/backend/todo_per_backend.rs @@ -5,6 +5,7 @@ use anyhow::{bail, ensure, Context, Result}; use super::Backend; use crate::Package; +#[derive(Debug)] pub(crate) struct ToDoPerBackend(Vec<(Box, Vec)>); impl ToDoPerBackend { From d710d19cdcca6ecc7c5ef88222a1cbe36743b991 Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Mon, 30 Jan 2023 15:05:27 +0100 Subject: [PATCH 4/8] add todos, adjust some context messages --- src/backend/actual/pacman.rs | 2 ++ src/backend/actual/rust.rs | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/backend/actual/pacman.rs b/src/backend/actual/pacman.rs index b8b8653..657f16e 100644 --- a/src/backend/actual/pacman.rs +++ b/src/backend/actual/pacman.rs @@ -15,8 +15,10 @@ pub(crate) struct Pacman { pub(crate) packages: HashSet, } +// TODO replace with paru const BINARY: Text = "yay"; const SECTION: Text = "pacman"; +// TODO replace these with the long version const SWITCHES_INSTALL: Switches = &["-S"]; const SWITCHES_REMOVE: Switches = &["-Rsn"]; diff --git a/src/backend/actual/rust.rs b/src/backend/actual/rust.rs index e102060..7d0a3a6 100644 --- a/src/backend/actual/rust.rs +++ b/src/backend/actual/rust.rs @@ -24,8 +24,9 @@ impl Backend for Rust { fn get_all_installed_packages(&self) -> Result> { let file = get_crates_file().context("getting path to crates file")?; let content = read_to_string(file).context("reading crates file")?; - let json: Value = serde_json::from_str(&content).context("parsing JSON")?; - extract_packages(json).context("extracing packages from JSON") + let json: Value = + serde_json::from_str(&content).context("parsing JSON from crates file")?; + extract_packages(json).context("extracing packages from crates file") } fn get_explicitly_installed_packages(&self) -> Result> { From 5f08ed271efa4ec4ce5807dce265ef3716b5e93d Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Mon, 30 Jan 2023 15:25:08 +0100 Subject: [PATCH 5/8] relax lifetime requirements in handle_backend_command --- src/backend/todo_per_backend.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/todo_per_backend.rs b/src/backend/todo_per_backend.rs index 98fc80e..da3a597 100644 --- a/src/backend/todo_per_backend.rs +++ b/src/backend/todo_per_backend.rs @@ -40,8 +40,8 @@ impl ToDoPerBackend { fn handle_backend_command<'a, F>( &'a self, func: F, - verb: &'static str, - verb_continuous: &'static str, + verb: &'_ str, + verb_continuous: &'_ str, ) -> Result<()> where F: Fn(&'a dyn Backend, &'a [Package]) -> Result, From dd4670094d3fe51163e8de19d658b9686cec92dd Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Mon, 30 Jan 2023 15:57:19 +0100 Subject: [PATCH 6/8] upgrade to clap v4 again i can't really live with the outdated library monochrome output is the lesser evil --- Cargo.lock | 165 +++++++++++++++++++++++++++++++++++++++++++--------- Cargo.toml | 3 +- src/args.rs | 17 +++--- 3 files changed, 145 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c97ce88..bea62f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,17 +36,6 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -60,29 +49,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "clap" -version = "3.2.23" +name = "cc" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "clap" +version = "4.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" dependencies = [ - "atty", "bitflags", "clap_lex", - "indexmap", + "is-terminal", "strsim", "termcolor", - "textwrap", ] [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" dependencies = [ "os_str_bytes", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -91,9 +105,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ "libc", ] @@ -108,6 +122,28 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "io-lifetimes" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi", + "io-lifetimes", + "rustix", + "windows-sys", +] + [[package]] name = "itoa" version = "1.0.5" @@ -120,6 +156,12 @@ version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "memchr" version = "2.5.0" @@ -223,6 +265,20 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "rustix" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "ryu" version = "1.0.12" @@ -259,9 +315,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.16" +version = "0.9.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92b5b431e8907b50339b51223b97d102db8d987ced36f6e4d03621db9316c834" +checksum = "8fb06d4b6cdaef0e0c51fa881acb721bed3c924cfaa71d9c94a3b771dfdf6567" dependencies = [ "indexmap", "itoa", @@ -305,12 +361,6 @@ dependencies = [ "libc", ] -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - [[package]] name = "unicode-ident" version = "1.0.6" @@ -353,3 +403,60 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" diff --git a/Cargo.toml b/Cargo.toml index c3f8729..0a97cb2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,7 @@ edition = "2021" [dependencies] alpm = "*" anyhow = "*" -# clap 4 until (at least) 4.0.32 have scrapped actual color support. we stay on 3.x until that's fixed. -clap = "3.*" +clap = "*" path-absolutize = "*" regex = "*" serde_json = "*" diff --git a/src/args.rs b/src/args.rs index c9a7e25..1895a4d 100644 --- a/src/args.rs +++ b/src/args.rs @@ -5,8 +5,8 @@ use path_absolutize::Absolutize; use crate::action::*; -fn get_arg_parser() -> Command<'static> { - let result = Command::new("pacdef") +fn get_arg_parser() -> Command { + Command::new("pacdef") .about("declarative package manager for Arch Linux") .version("1.0.0-alpha") .subcommand_required(true) @@ -16,14 +16,14 @@ fn get_arg_parser() -> Command<'static> { Command::new(EDIT) .about("edit one or more existing group files") .arg_required_else_help(true) - .arg(Arg::new("group").multiple_values(true)), + .arg(Arg::new("group").num_args(1..)), ) .subcommand(Command::new(GROUPS).about("show names of imported groups")) .subcommand( Command::new(IMPORT) .about("import one or more group files") .arg_required_else_help(true) - .arg(Arg::new("files").multiple_values(true)), + .arg(Arg::new("files").num_args(1..)), ) .subcommand( Command::new(NEW) @@ -36,13 +36,13 @@ fn get_arg_parser() -> Command<'static> { .help("edit the new group files after creation") .action(clap::ArgAction::SetTrue), ) - .arg(Arg::new("groups").multiple_values(true)), + .arg(Arg::new("groups").num_args(1..)), ) .subcommand( Command::new(REMOVE) .about("remove one or more previously imported groups") .arg_required_else_help(true) - .arg(Arg::new("groups").multiple_values(true)), + .arg(Arg::new("groups").num_args(1..)), ) .subcommand(Command::new(REVIEW).about("review unmanaged packages")) .subcommand( @@ -55,15 +55,14 @@ fn get_arg_parser() -> Command<'static> { Command::new(SHOW) .about("show packages under an imported group") .arg_required_else_help(true) - .arg(Arg::new("group").multiple_values(true)), + .arg(Arg::new("group").num_args(1..)), ) .subcommand(Command::new(SYNC).about("install packages from all imported groups")) .subcommand( Command::new(UNMANAGED) .about("show explicitly installed packages not managed by pacdef"), ) - .subcommand(Command::new(VERSION).about("show version info")); - result + .subcommand(Command::new(VERSION).about("show version info")) } #[must_use] From 1ef763d89ead0cbeeeef50bb81d785e4328cc997 Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Mon, 30 Jan 2023 16:34:25 +0100 Subject: [PATCH 7/8] add proper version string --- Cargo.lock | 2 +- Cargo.toml | 2 +- build.rs | 10 ++++++++++ src/args.rs | 3 ++- src/core.rs | 12 +++++++++++- 5 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 build.rs diff --git a/Cargo.lock b/Cargo.lock index bea62f7..0a55aa6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,7 +182,7 @@ checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" [[package]] name = "pacdef" -version = "0.1.0" +version = "1.0.0-alpha1" dependencies = [ "alpm", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 0a97cb2..86c7d84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pacdef" -version = "0.1.0" +version = "1.0.0-alpha1" edition = "2021" [dependencies] diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..33069fc --- /dev/null +++ b/build.rs @@ -0,0 +1,10 @@ +use std::process::Command; + +fn main() { + let output = Command::new("git") + .args(["rev-parse", "--short", "HEAD"]) + .output() + .unwrap(); + let git_hash = String::from_utf8(output.stdout).unwrap(); + println!("cargo:rustc-env=GIT_HASH={git_hash}"); +} diff --git a/src/args.rs b/src/args.rs index 1895a4d..ea7e052 100644 --- a/src/args.rs +++ b/src/args.rs @@ -4,11 +4,12 @@ use clap::{Arg, ArgMatches, Command}; use path_absolutize::Absolutize; use crate::action::*; +use crate::core::get_version_string; fn get_arg_parser() -> Command { Command::new("pacdef") .about("declarative package manager for Arch Linux") - .version("1.0.0-alpha") + .version(get_version_string()) .subcommand_required(true) .arg_required_else_help(true) .subcommand(Command::new(CLEAN).about("remove unmanaged packages")) diff --git a/src/core.rs b/src/core.rs index 6471423..3a6dc4e 100644 --- a/src/core.rs +++ b/src/core.rs @@ -136,7 +136,7 @@ impl Pacdef { } fn show_version(self) { - println!("pacdef, version: {}", env!("CARGO_PKG_VERSION")); + println!("{}", get_version_string()); } fn show_unmanaged_packages(mut self) { @@ -289,3 +289,13 @@ fn show_error(error: anyhow::Error, backend: Box) { None => println!("WARNING: skipping backend '{section}': {error}"), } } + +pub(crate) const fn get_version_string() -> &'static str { + concat!( + "pacdef, version: ", + env!("CARGO_PKG_VERSION"), + " (", + env!("GIT_HASH"), + ")", + ) +} From e67d663d42bef8c9cd0481ffb4619d01cb390d0a Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Wed, 1 Feb 2023 13:04:05 +0100 Subject: [PATCH 8/8] remove duplicate method --- src/backend/todo_per_backend.rs | 5 +---- src/core.rs | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/backend/todo_per_backend.rs b/src/backend/todo_per_backend.rs index da3a597..02bb114 100644 --- a/src/backend/todo_per_backend.rs +++ b/src/backend/todo_per_backend.rs @@ -50,6 +50,7 @@ impl ToDoPerBackend { if packages.is_empty() { continue; } + let exit_status = func(&**backend, packages).with_context(|| { format!("{verb_continuous} packages for {}", backend.get_binary()) })?; @@ -62,10 +63,6 @@ impl ToDoPerBackend { Ok(()) } - pub(crate) fn is_empty(&self) -> bool { - self.0.iter().all(|(_, packages)| packages.is_empty()) - } - pub(crate) fn show(&self, keyword: Option<&str>) { for (backend, packages) in self.iter() { if packages.is_empty() { diff --git a/src/core.rs b/src/core.rs index 3a6dc4e..f12e9b6 100644 --- a/src/core.rs +++ b/src/core.rs @@ -172,7 +172,7 @@ impl Pacdef { fn clean_packages(mut self) -> Result<()> { let to_remove = self.get_unmanaged_packages(); - if to_remove.is_empty() { + if to_remove.nothing_to_do_for_all_backends() { println!("nothing to do"); return Ok(()); }