diff --git a/Cargo.lock b/Cargo.lock index 633d63c..a238443 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,7 @@ dependencies = [ "regex", "rm_rf", "serde", + "spinoff", "ureq", ] @@ -252,6 +253,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + [[package]] name = "matches" version = "0.1.9" @@ -447,6 +454,12 @@ dependencies = [ "stacker", ] +[[package]] +name = "rustversion" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" + [[package]] name = "ryu" version = "1.0.11" @@ -517,6 +530,18 @@ dependencies = [ "serde", ] +[[package]] +name = "spinoff" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c139aa6a2b4ed01ef761dfd593eb5b02218dbf35a3a0f10940b72f5bfe70426" +dependencies = [ + "colored", + "maplit", + "once_cell", + "strum", +] + [[package]] name = "stacker" version = "0.1.15" @@ -536,6 +561,28 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + [[package]] name = "syn" version = "1.0.99" diff --git a/Cargo.toml b/Cargo.toml index aee3c3d..736946d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,4 +26,5 @@ ureq = { version = "2.4.0", default-features = false, features = [ "native-tls", serde = { version = "1.0.138", default-features = false, features = [ "derive", "serde_derive" ] } native-tls = { version = "0.2.10", default-features = false } libc = { version = "0.2.126", default-features = false } -rm_rf = { version = "0.6.2", default-features = false } \ No newline at end of file +rm_rf = { version = "0.6.2", default-features = false } +spinoff = { version = "0.5.3", default-features = false } \ No newline at end of file diff --git a/src/internal/detect.rs b/src/internal/detect.rs index 9553b56..b9b88dd 100644 --- a/src/internal/detect.rs +++ b/src/internal/detect.rs @@ -1,20 +1,22 @@ use crate::internal::commands::ShellCommand; use crate::internal::error::SilentUnwrap; use crate::internal::exit_code::AppExitCode; -use crate::{info, prompt, warn}; +use crate::{prompt, warn, spinner}; +use std::env; pub fn detect() { - info!("Scanning for pacnew files"); + // Start spinner + let sp = spinner!("Scanning for pacnew files"); let mut pacnew = vec![]; // Run `find` to find pacnew files and split by lines into a vec - let find = std::process::Command::new("sudo") - .arg("pacdiff") - .arg("-f") - .output() - .unwrap(); - let find_lines = std::str::from_utf8(&find.stdout).unwrap().split('\n'); + let find = ShellCommand::pacdiff() + .args(&["-o", "-f"]) + .elevated() + .wait_with_output() + .silent_unwrap(AppExitCode::PacmanError); + let find_lines = find.stdout.split('\n'); for line in find_lines { if !line.is_empty() { pacnew.push(line.to_string()); @@ -23,16 +25,28 @@ pub fn detect() { // If pacnew files are found, warn the user and prompt to pacdiff if !pacnew.is_empty() { - let choice = prompt!(default false, "It appears that at least one program you have installed / upgraded has installed a .pacnew/.pacsave config file. Would you like to run pacdiff to deal with this? You can always deal with this later by running `sudo pacdiff`"); + sp.stop_bold("It appears that at least one program you have installed / upgraded has installed a .pacnew/.pacsave config file. These are created when you have modified a program's configuration, and a package upgrade could not automatically merge the new file."); + + let choice = prompt!(default false, "Would you like to run pacdiff to deal with this? You can always deal with this later by running `sudo pacdiff`"); if choice { - warn!("Unless you've set an alternative using the DIFFPROG environment variable, pacdiff uses `vimdiff` by default to edit files for merging. Make sure you know how to exit vim before proceeding"); - let cont = prompt!(default false, "Continue?"); - if cont { + if env::var("PACDIFF_WARNING").unwrap_or_else(|_| "1".to_string()) != "0" { + warn!("Pacdiff uses `vimdiff` by default to edit files for merging. Make sure you know how to exit vim before proceeding!"); + warn!("You can surpress this warning in the future by setting the `PACDIFF_WARNING` environment variable to `0`"); + let cont = prompt!(default false, "Continue?"); + if cont { + ShellCommand::pacdiff() + .elevated() + .wait() + .silent_unwrap(AppExitCode::PacmanError); + } + } else { ShellCommand::pacdiff() .elevated() .wait() .silent_unwrap(AppExitCode::PacmanError); } } + } else { + sp.stop_bold("No pacnew files found"); } } diff --git a/src/internal/utils.rs b/src/internal/utils.rs index eadb0ec..ee04076 100644 --- a/src/internal/utils.rs +++ b/src/internal/utils.rs @@ -50,6 +50,13 @@ macro_rules! prompt { } } +#[macro_export] +macro_rules! spinner { + ($($arg:tt)+) => { + $crate::internal::utils::spinner_fn(format!($($arg)+)) + } +} + pub fn log_info(msg: S) { let msg = msg.to_string(); let msg = if internal::uwu_enabled() { @@ -137,3 +144,42 @@ pub fn prompt_yn(question: S, default_true: bool) -> bool { default_true } } + +pub struct Spinner { + spinner: spinoff::Spinner, +} + +impl Spinner { + pub fn stop_bold(self, text: &str) { + let text = if internal::uwu_enabled() { + uwu!(text) + } else { + text.to_string() + }; + + let symbol = Box::new(format!("{}", OK_SYMBOL.purple())); + let text = Box::new(format!("{}", text.bold())); + + let symbol: &'static str = Box::leak(symbol); + let text: &'static str = Box::leak(text); + + self.spinner.stop_and_persist(symbol, text); + } +} + +pub fn spinner_fn(text: String) -> Spinner { + let text = if internal::uwu_enabled() { + uwu!(&text) + } else { + text + }; + Spinner { + spinner: spinoff::Spinner::new( + spinoff::Spinners::Line, + format!("{}", + text.bold()), + spinoff::Color::Magenta, + ) + } +} + diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index f8ed002..87b4729 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -67,9 +67,10 @@ pub fn aur_install(a: Vec, options: Options) { } // Sort dependencies and makedepends - log!("Sorting dependencies"); + if verbosity >= 1 { + log!("Sorting dependencies and makedepends"); + } let sorted = crate::internal::sort(&rpcres.package.as_ref().unwrap().depends, options); - log!("Sorting make dependencies"); let md_sorted = crate::internal::sort(&rpcres.package.as_ref().unwrap().make_depends, options); diff --git a/src/operations/upgrade.rs b/src/operations/upgrade.rs index 0de1221..6c5c9eb 100644 --- a/src/operations/upgrade.rs +++ b/src/operations/upgrade.rs @@ -4,7 +4,7 @@ use crate::internal::error::SilentUnwrap; use crate::internal::exit_code::AppExitCode; use crate::internal::rpc::rpcinfo; use crate::operations::aur_install::aur_install; -use crate::{info, log, prompt, Options}; +use crate::{info, log, prompt, Options, spinner}; #[derive(Debug)] struct QueriedPackage { @@ -53,6 +53,9 @@ pub fn upgrade(options: Options) { log!("Checking AUR upgrades..."); } + // Start spinner + let sp = spinner!("Checking AUR upgrades..."); + // List non-native packages using `pacman -Qm` and collect to a Vec let non_native = ShellCommand::pacman() .arg("-Qm") @@ -101,6 +104,8 @@ pub fn upgrade(options: Options) { } } + sp.stop_bold("Finished!"); + // If vector isn't empty, prompt to install AUR packages from vector, effectively upgrading if !aur_upgrades.is_empty() { let cont = prompt!(default false,