diff --git a/Cargo.toml b/Cargo.toml index 220fc0b..eda60e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,10 @@ version = "3.6.0" authors = ["michal ", "axtlos "] edition = "2021" description = "A fast and efficient AUR helper" +repository = "https://github.com/crystal-linux/amethyst" license-file = "LICENSE.md" +keywords = ["aur", "crystal-linux", "pacman", "aur-helper"] +categories = ["command-line-utilities"] default-run = "ame" [[bin]] diff --git a/src/args.rs b/src/args.rs index a22bd61..d98cdd4 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,3 +1,5 @@ +#![allow(clippy::module_name_repetitions)] + use clap::{Parser, Subcommand}; #[derive(Debug, Clone, Parser)] diff --git a/src/internal/commands.rs b/src/internal/commands.rs index f2df391..340a638 100644 --- a/src/internal/commands.rs +++ b/src/internal/commands.rs @@ -10,7 +10,7 @@ pub struct StringOutput { pub status: ExitStatus, } -/// A wrapper around [std::process::Command] with predefined +/// A wrapper around [`std::process::Command`] with predefined /// commands used in this project as well as elevated access. pub struct ShellCommand { command: String, @@ -49,7 +49,7 @@ impl ShellCommand { Self::new("sudo") } - fn new(command: S) -> Self { + fn new(command: &str) -> Self { Self { command: command.to_string(), args: Vec::new(), @@ -77,7 +77,7 @@ impl ShellCommand { } /// Runs the command with sudo - pub fn elevated(mut self) -> Self { + pub const fn elevated(mut self) -> Self { self.elevated = true; self diff --git a/src/internal/detect.rs b/src/internal/detect.rs index 972729e..7db79cc 100644 --- a/src/internal/detect.rs +++ b/src/internal/detect.rs @@ -25,12 +25,19 @@ pub fn detect() { } // If pacnew files are found, warn the user and prompt to pacdiff - if !pacnew.is_empty() { + if pacnew.is_empty() { + sp.stop_bold("No pacnew files found"); + } else { sp.stop_bold("It appears that at least one program you have installed / upgraded has installed a .pacnew 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 { - if env::var("PACDIFF_WARNING").unwrap_or_else(|_| "1".to_string()) != "0" { + if env::var("PACDIFF_WARNING").unwrap_or_else(|_| "1".to_string()) == "0" { + ShellCommand::pacdiff() + .elevated() + .wait() + .silent_unwrap(AppExitCode::PacmanError); + } else { warn!("Pacdiff uses vimdiff by default to edit files for merging. You can focus panes by mousing over them and pressing left click, and scroll up and down using your mouse's scroll wheel (or the arrow keys). To exit vimdiff, press the following key combination: ESC, :qa!, ENTER"); warn!("You can surpress this warning in the future by setting the `PACDIFF_WARNING` environment variable to `0`"); let cont = prompt!(default false, "Continue?"); @@ -40,14 +47,7 @@ pub fn detect() { .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/error.rs b/src/internal/error.rs index b29a86d..3e2c1f8 100644 --- a/src/internal/error.rs +++ b/src/internal/error.rs @@ -8,6 +8,7 @@ use crate::internal::exit_code::AppExitCode; pub type AppResult = Result; #[derive(Debug)] +#[allow(clippy::module_name_repetitions)] pub enum AppError { Io(std::io::Error), Other(String), @@ -17,9 +18,9 @@ pub enum AppError { impl Display for AppError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - AppError::Io(io) => Display::fmt(io, f), - AppError::Other(s) => Display::fmt(s, f), - AppError::NonZeroExit => Display::fmt("exited with non zero code", f), + Self::Io(io) => Display::fmt(io, f), + Self::Other(s) => Display::fmt(s, f), + Self::NonZeroExit => Display::fmt("exited with non zero code", f), } } } diff --git a/src/internal/exit_code.rs b/src/internal/exit_code.rs index e04fde3..7b67119 100644 --- a/src/internal/exit_code.rs +++ b/src/internal/exit_code.rs @@ -1,3 +1,4 @@ +#[allow(clippy::module_name_repetitions)] pub enum AppExitCode { RunAsRoot = 1, FailedCreatingPaths = 2, diff --git a/src/internal/mod.rs b/src/internal/mod.rs index 91008f5..6b7e8b3 100644 --- a/src/internal/mod.rs +++ b/src/internal/mod.rs @@ -18,7 +18,7 @@ pub mod rpc; mod sort; pub mod structs; #[macro_use] -pub(crate) mod utils; +pub mod utils; mod sudoloop; #[macro_export] diff --git a/src/internal/rpc.rs b/src/internal/rpc.rs index 323f46d..80e4168 100644 --- a/src/internal/rpc.rs +++ b/src/internal/rpc.rs @@ -33,7 +33,7 @@ pub struct InfoResults { pub const URL: &str = "https://aur.archlinux.org/"; -pub fn rpcinfo(pkg: String) -> InfoResults { +pub fn rpcinfo(pkg: &str) -> InfoResults { // Initialise TLS connector let tls_connector = Arc::new(native_tls::TlsConnector::new().unwrap()); @@ -67,7 +67,7 @@ pub fn rpcinfo(pkg: String) -> InfoResults { } } -pub fn rpcsearch(pkg: String) -> SearchResults { +pub fn rpcsearch(pkg: &str) -> SearchResults { // Initialise TLS connector let tls_connector = Arc::new(native_tls::TlsConnector::new().unwrap()); diff --git a/src/internal/sort.rs b/src/internal/sort.rs index 78ea61b..f32c671 100644 --- a/src/internal/sort.rs +++ b/src/internal/sort.rs @@ -26,13 +26,13 @@ pub fn sort(input: &[String], options: Options) -> structs::Sorted { .status() .expect("Something has gone wrong"); - if let Some(0) = rs.code() { + if rs.code() == Some(0) { // If it is, add it to the repo vector if verbosity >= 1 { log!("{} found in repos", b); } repo.push(b.to_string()); - } else if rpc::rpcinfo(b.to_string()).found { + } else if rpc::rpcinfo(&b).found { // Otherwise, check if it is in the AUR, if it is, add it to the AUR vector if verbosity >= 1 { log!("{} found in AUR", b); diff --git a/src/internal/structs.rs b/src/internal/structs.rs index 481c573..55d86d0 100644 --- a/src/internal/structs.rs +++ b/src/internal/structs.rs @@ -10,14 +10,13 @@ pub struct Sorted { impl Sorted { pub fn new(repo: Vec, aur: Vec, nf: Vec) -> Self { - let a: Sorted = Sorted { repo, aur, nf }; - a + Self { repo, aur, nf } } } #[derive(Clone, Copy)] pub struct Options { - pub verbosity: i32, + pub verbosity: usize, pub noconfirm: bool, pub asdeps: bool, pub toplevel: bool, diff --git a/src/internal/sudoloop.rs b/src/internal/sudoloop.rs index 147a503..bcefc31 100644 --- a/src/internal/sudoloop.rs +++ b/src/internal/sudoloop.rs @@ -4,11 +4,12 @@ use std::time::Duration; use crate::ShellCommand; /// Loop sudo so it doesn't time out +#[allow(clippy::module_name_repetitions)] pub fn start_sudoloop() { prompt_sudo(); std::thread::spawn(|| loop { prompt_sudo(); - thread::sleep(Duration::from_secs(3 * 60)) + thread::sleep(Duration::from_secs(3 * 60)); }); } diff --git a/src/internal/utils.rs b/src/internal/utils.rs index f3da3c7..df5d322 100644 --- a/src/internal/utils.rs +++ b/src/internal/utils.rs @@ -1,4 +1,4 @@ -use colored::*; +use colored::Colorize; use std::io; use std::io::Write; use std::process::exit; @@ -59,8 +59,7 @@ macro_rules! spinner { } } -pub fn log_info(msg: S) { - let msg = msg.to_string(); +pub fn log_info(msg: String) { let msg = if internal::uwu_enabled() { uwu!(&msg) } else { @@ -72,11 +71,10 @@ pub fn log_info(msg: S) { "{} {}", OK_SYMBOL.purple(), wrap(&msg, opts).join("\n").bold() - ) + ); } -pub fn log_warn(msg: S) { - let msg = msg.to_string(); +pub fn log_warn(msg: String) { let msg = if internal::uwu_enabled() { uwu!(&msg) } else { @@ -88,11 +86,10 @@ pub fn log_warn(msg: S) { "{} {}", WARN_SYMBOL.yellow(), wrap(&msg, opts).join("\n").yellow().bold() - ) + ); } -pub fn log_and_crash(msg: S, exit_code: AppExitCode) -> ! { - let msg = msg.to_string(); +pub fn log_and_crash(msg: String, exit_code: AppExitCode) -> ! { let msg = if internal::uwu_enabled() { uwu!(&msg) } else { @@ -108,8 +105,7 @@ pub fn log_and_crash(msg: S, exit_code: AppExitCode) -> ! { exit(exit_code as i32); } -pub fn log_debug(msg: S) { - let msg = msg.to_string(); +pub fn log_debug(msg: String) { let msg = if internal::uwu_enabled() && internal::uwu_debug_enabled() { uwu!(&msg) } else { @@ -126,9 +122,7 @@ pub fn log_debug(msg: S) { ); } -pub fn prompt_yn(question: S, default_true: bool) -> bool { - let question = question.to_string(); - +pub fn prompt_yn(question: String, default_true: bool) -> bool { let yn_prompt = if default_true { PROMPT_YN_DEFAULT_TRUE } else { @@ -153,7 +147,7 @@ pub fn prompt_yn(question: S, default_true: bool) -> bool { let mut yn: String = String::new(); io::stdout().flush().ok(); - let _ = std::io::stdin().read_line(&mut yn); + std::io::stdin().read_line(&mut yn).unwrap(); if yn.trim().to_lowercase() == "n" || yn.trim().to_lowercase() == "no" { false diff --git a/src/main.rs b/src/main.rs index ec7c453..dccbddb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,7 @@ #![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)] #![allow(clippy::too_many_lines)] +// This is only temporary until I properly split aur_install up +#![allow(clippy::cognitive_complexity)] use std::fs; use std::path::Path; @@ -32,7 +34,7 @@ fn main() { let args: Args = Args::parse(); // Initialize variables - let verbosity = args.verbose as i32; + let verbosity = args.verbose; let noconfirm = args.no_confirm; // Get options struct @@ -70,8 +72,8 @@ fn main() { match args.subcommand.unwrap_or_default() { Operation::Install(install_args) => cmd_install(install_args, options, &cachedir), Operation::Remove(remove_args) => cmd_remove(remove_args, options), - Operation::Search(search_args) => cmd_search(search_args, options), - Operation::Query(query_args) => cmd_query(query_args), + Operation::Search(search_args) => cmd_search(&search_args, options), + Operation::Query(query_args) => cmd_query(&query_args), Operation::Info(info_args) => cmd_info(info_args), Operation::Upgrade(upgrade_args) => cmd_upgrade(upgrade_args, options, &cachedir), Operation::Clean => { @@ -103,11 +105,11 @@ fn cmd_install(args: InstallArgs, options: Options, cachedir: &str) { if !sorted.repo.is_empty() { // If repo packages found, install them - operations::install(sorted.repo.clone(), options); + operations::install(&sorted.repo, options); } if !sorted.aur.is_empty() { // If AUR packages found, install them - operations::aur_install(sorted.aur.clone(), options, cachedir.to_string()); + operations::aur_install(sorted.aur.clone(), options, cachedir); } // Show optional dependencies for installed packages @@ -158,7 +160,7 @@ fn cmd_remove(args: RemoveArgs, options: Options) { operations::uninstall(packages, options); } -fn cmd_search(args: SearchArgs, options: Options) { +fn cmd_search(args: &SearchArgs, options: Options) { // Initialise variables let query_string = args.search.join(" "); if args.aur { @@ -183,7 +185,7 @@ fn cmd_search(args: SearchArgs, options: Options) { } } -fn cmd_query(args: QueryArgs) { +fn cmd_query(args: &QueryArgs) { if args.aur { // If AUR query, query AUR ShellCommand::pacman() diff --git a/src/operations/aur_install.rs b/src/operations/aur_install.rs index 1e3564f..cb3b443 100644 --- a/src/operations/aur_install.rs +++ b/src/operations/aur_install.rs @@ -14,15 +14,15 @@ fn list(dir: &str) -> Vec { let dirs = fs::read_dir(Path::new(&dir)).unwrap(); let dirs: Vec = dirs .map(|dir| { - dir.unwrap() + (*dir + .unwrap() .path() .to_str() .unwrap() - .to_string() .split('/') .collect::>() .last() - .unwrap() + .unwrap()) .to_string() }) .collect(); @@ -39,11 +39,11 @@ fn mktemp() -> String { String::from_utf8(tempdir).unwrap().trim().to_string() } -pub fn aur_install(a: Vec, options: Options, orig_cachedir: String) { +pub fn aur_install(a: Vec, options: Options, orig_cachedir: &str) { // Initialise variables let url = crate::internal::rpc::URL; let cachedir = if !options.toplevel || !orig_cachedir.is_empty() { - orig_cachedir.clone() + orig_cachedir.to_string() } else { mktemp() }; @@ -65,7 +65,7 @@ pub fn aur_install(a: Vec, options: Options, orig_cachedir: String) { } // Query AUR for package info - let rpcres = rpcinfo(package); + let rpcres = rpcinfo(&package); if !rpcres.found { // If package isn't found, break @@ -138,7 +138,7 @@ pub fn aur_install(a: Vec, options: Options, orig_cachedir: String) { .split_whitespace() .collect::>() .iter() - .map(|s| s.to_string()) + .map(|s| (*s).to_string()) .collect::>(); // Remove installed packages from sorted dependencies and makedepends @@ -233,25 +233,25 @@ pub fn aur_install(a: Vec, options: Options, orig_cachedir: String) { // Install dependencies and makedepends if !sorted.repo.is_empty() { - crate::operations::install(sorted.repo, newopts); + crate::operations::install(&sorted.repo, newopts); } if !sorted.aur.is_empty() { - crate::operations::aur_install(sorted.aur, newopts, cachedir.clone()); + crate::operations::aur_install(sorted.aur, newopts, &cachedir.clone()); } if !md_sorted.repo.is_empty() { - crate::operations::install(md_sorted.repo, newopts); + crate::operations::install(&md_sorted.repo, newopts); } if !md_sorted.aur.is_empty() { - crate::operations::aur_install(md_sorted.aur, newopts, cachedir.clone()); + crate::operations::aur_install(md_sorted.aur, newopts, &cachedir.clone()); } // Build makepkg args let mut makepkg_args = vec!["-rcd", "--skippgp", "--needed"]; if options.asdeps { - makepkg_args.push("--asdeps") + makepkg_args.push("--asdeps"); } if options.noconfirm { - makepkg_args.push("--noconfirm") + makepkg_args.push("--noconfirm"); } info!("Building time!"); diff --git a/src/operations/clean.rs b/src/operations/clean.rs index e8dfe1b..7d47203 100644 --- a/src/operations/clean.rs +++ b/src/operations/clean.rs @@ -70,10 +70,10 @@ pub fn clean(options: Options) { } // Prompt the user whether to clear cache or not - let clear_cache = if !noconfirm { - prompt!(default false, "Also clear pacman's package cache?") - } else { + let clear_cache = if noconfirm { true + } else { + prompt!(default false, "Also clear pacman's package cache?") }; if clear_cache { diff --git a/src/operations/install.rs b/src/operations/install.rs index d1b8ea2..c2fb2a0 100644 --- a/src/operations/install.rs +++ b/src/operations/install.rs @@ -3,7 +3,7 @@ use crate::internal::error::SilentUnwrap; use crate::internal::exit_code::AppExitCode; use crate::{crash, info, log, Options}; -pub fn install(packages: Vec, options: Options) { +pub fn install(packages: &[String], options: Options) { info!("Installing packages {} from repos", &packages.join(", ")); // Build pacman args @@ -25,7 +25,7 @@ pub fn install(packages: Vec, options: Options) { let status = ShellCommand::pacman() .elevated() .args(opers) - .args(&packages) + .args(packages) .wait() .silent_unwrap(AppExitCode::PacmanError); if !status.success() { diff --git a/src/operations/search.rs b/src/operations/search.rs index 1f4f786..6cb3260 100644 --- a/src/operations/search.rs +++ b/src/operations/search.rs @@ -4,12 +4,13 @@ use crate::internal::exit_code::AppExitCode; use crate::internal::rpc::rpcsearch; use crate::{log, Options}; +#[allow(clippy::module_name_repetitions)] pub fn aur_search(query: &str, options: Options) { // Initialise variables let verbosity = options.verbosity; // Query AUR for package info - let res = rpcsearch(query.to_string()); + let res = rpcsearch(query); // Format output for package in &res.results { @@ -21,7 +22,7 @@ pub fn aur_search(query: &str, options: Options) { .description .as_ref() .unwrap_or(&"No description".to_string()) - ) + ); } if verbosity >= 1 { @@ -29,6 +30,7 @@ pub fn aur_search(query: &str, options: Options) { } } +#[allow(clippy::module_name_repetitions)] pub fn repo_search(query: &str, options: Options) { // Initialise variables let verbosity = options.verbosity; @@ -49,5 +51,5 @@ pub fn repo_search(query: &str, options: Options) { ); } - println!("{}", output) + println!("{}", output); } diff --git a/src/operations/uninstall.rs b/src/operations/uninstall.rs index 1a392ff..544acd1 100644 --- a/src/operations/uninstall.rs +++ b/src/operations/uninstall.rs @@ -9,7 +9,7 @@ use crate::{log, Options}; pub fn uninstall(packages: Vec, options: Options) { // Build pacman args let mut pacman_args = vec!["-Rs"]; - pacman_args.append(&mut packages.iter().map(|s| s.as_str()).collect()); + pacman_args.append(&mut packages.iter().map(String::as_str).collect()); if options.noconfirm { pacman_args.push("--noconfirm"); } diff --git a/src/operations/upgrade.rs b/src/operations/upgrade.rs index 7d1bebb..dddae82 100644 --- a/src/operations/upgrade.rs +++ b/src/operations/upgrade.rs @@ -106,7 +106,7 @@ pub fn upgrade(options: Options, args: UpgradeArgs, cachedir: &str) { let mut aur_upgrades = vec![]; for pkg in parsed_non_native { // Query AUR - let rpc_result = rpcinfo((&*pkg.name).to_string()); + let rpc_result = rpcinfo(&pkg.name); if !rpc_result.found { // If package not found, skip @@ -122,16 +122,16 @@ pub fn upgrade(options: Options, args: UpgradeArgs, cachedir: &str) { sp.stop_bold("Finished!"); // If vector isn't empty, prompt to install AUR packages from vector, effectively upgrading - if !aur_upgrades.is_empty() { + if aur_upgrades.is_empty() { + info!("No upgrades available for installed AUR packages"); + } else { let cont = prompt!(default true, "Found AUR packages {} have new versions available, upgrade?", aur_upgrades.join(", "), ); if cont { - aur_install(aur_upgrades, options, cachedir.to_string()); + aur_install(aur_upgrades, options, cachedir); }; - } else { - info!("No upgrades available for installed AUR packages"); } }