Make fs and command operations asynchronous

Signed-off-by: trivernis <trivernis@protonmail.com>
i18n
trivernis 2 years ago
parent 33a68d654a
commit 21e4d66968
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

97
Cargo.lock generated

@ -4,8 +4,9 @@ version = 3
[[package]] [[package]]
name = "Amethyst" name = "Amethyst"
version = "3.3.0" version = "4.0.0"
dependencies = [ dependencies = [
"async-recursion",
"clap", "clap",
"colored", "colored",
"libc", "libc",
@ -14,6 +15,7 @@ dependencies = [
"regex", "regex",
"rusqlite", "rusqlite",
"serde", "serde",
"tokio",
"ureq", "ureq",
] ]
@ -28,6 +30,17 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "async-recursion"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cda8f4bcc10624c4e85bc66b3f452cca98cfa5ca002dc83a16aad2367641bea"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@ -57,6 +70,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bytes"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.73" version = "1.0.73"
@ -335,6 +354,18 @@ dependencies = [
"libmimalloc-sys", "libmimalloc-sys",
] ]
[[package]]
name = "mio"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys",
]
[[package]] [[package]]
name = "native-tls" name = "native-tls"
version = "0.2.10" version = "0.2.10"
@ -416,6 +447,12 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.25" version = "0.3.25"
@ -582,6 +619,15 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "signal-hook-registry"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.9.0" version = "1.9.0"
@ -662,6 +708,55 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439"
dependencies = [
"bytes",
"libc",
"memchr",
"mio",
"once_cell",
"pin-project-lite",
"signal-hook-registry",
"tokio-macros",
"tracing",
"winapi",
]
[[package]]
name = "tokio-macros"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing"
version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
dependencies = [
"cfg-if",
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
dependencies = [
"once_cell",
]
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.8" version = "0.3.8"

@ -1,6 +1,6 @@
[package] [package]
name = "Amethyst" name = "Amethyst"
version = "3.3.0" version = "4.0.0"
authors = ["michal <michal@tar.black>", "axtlos <axtlos@tar.black>"] authors = ["michal <michal@tar.black>", "axtlos <axtlos@tar.black>"]
edition = "2021" edition = "2021"
description = "A fast and efficient AUR helper" description = "A fast and efficient AUR helper"
@ -60,3 +60,8 @@ ureq = { version = "2.4.0", default-features = false, features = [ "native-tls",
serde = { version = "1.0.138", default-features = false, features = [ "derive", "serde_derive" ] } serde = { version = "1.0.138", default-features = false, features = [ "derive", "serde_derive" ] }
native-tls = { version = "0.2.10", default-features = false } native-tls = { version = "0.2.10", default-features = false }
libc = { version = "0.2.126", default-features = false } libc = { version = "0.2.126", default-features = false }
async-recursion = "1.0.0"
[dependencies.tokio]
version = "1.19.2"
features = ["rt", "io-std", "io-util", "process", "time", "macros", "tracing", "fs"]

@ -1,5 +1,6 @@
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
use std::process::{Child, Command, ExitStatus, Stdio}; use std::process::{ExitStatus, Stdio};
use tokio::process::{Child, Command};
use crate::internal::error::{AppError, AppResult}; use crate::internal::error::{AppError, AppResult};
use crate::internal::is_tty; use crate::internal::is_tty;
@ -84,8 +85,8 @@ impl ShellCommand {
} }
/// Waits for the child to exit but returns an error when it exists with a non-zero status code /// Waits for the child to exit but returns an error when it exists with a non-zero status code
pub fn wait_success(self) -> AppResult<()> { pub async fn wait_success(self) -> AppResult<()> {
let status = self.wait()?; let status = self.wait().await?;
if status.success() { if status.success() {
Ok(()) Ok(())
} else { } else {
@ -94,17 +95,17 @@ impl ShellCommand {
} }
/// Waits for the child to exit and returns the output status /// Waits for the child to exit and returns the output status
pub fn wait(self) -> AppResult<ExitStatus> { pub async fn wait(self) -> AppResult<ExitStatus> {
let mut child = self.spawn(false)?; let mut child = self.spawn(false)?;
child.wait().map_err(AppError::from) child.wait().await.map_err(AppError::from)
} }
/// Waits with output until the program completed and /// Waits with output until the program completed and
/// returns the string output object /// returns the string output object
pub fn wait_with_output(self) -> AppResult<StringOutput> { pub async fn wait_with_output(self) -> AppResult<StringOutput> {
let child = self.spawn(true)?; let child = self.spawn(true)?;
let output = child.wait_with_output()?; let output = child.wait_with_output().await?;
let stdout = String::from_utf8(output.stdout).map_err(|e| AppError::from(e.to_string()))?; let stdout = String::from_utf8(output.stdout).map_err(|e| AppError::from(e.to_string()))?;
let stderr = String::from_utf8(output.stderr).map_err(|e| AppError::from(e.to_string()))?; let stderr = String::from_utf8(output.stderr).map_err(|e| AppError::from(e.to_string()))?;

@ -3,7 +3,7 @@ use crate::internal::error::SilentUnwrap;
use crate::internal::exit_code::AppExitCode; use crate::internal::exit_code::AppExitCode;
use crate::{prompt, warn}; use crate::{prompt, warn};
pub fn detect() { pub async fn detect() {
let mut pacnew = vec![]; let mut pacnew = vec![];
for entry in std::fs::read_dir("/etc").unwrap() { for entry in std::fs::read_dir("/etc").unwrap() {
@ -24,6 +24,7 @@ pub fn detect() {
ShellCommand::pacdiff() ShellCommand::pacdiff()
.elevated() .elevated()
.wait() .wait()
.await
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
} }
} }

@ -30,7 +30,7 @@ pub struct InfoResults {
pub const URL: &str = "https://aur.archlinux.org/"; pub const URL: &str = "https://aur.archlinux.org/";
pub fn rpcinfo(pkg: String) -> InfoResults { pub fn rpcinfo(pkg: &String) -> InfoResults {
let tls_connector = Arc::new(native_tls::TlsConnector::new().unwrap()); let tls_connector = Arc::new(native_tls::TlsConnector::new().unwrap());
let agent = ureq::AgentBuilder::new() let agent = ureq::AgentBuilder::new()
.tls_connector(tls_connector) .tls_connector(tls_connector)

@ -4,42 +4,42 @@ use crate::internal::{clean, rpc, structs};
use crate::{log, Options}; use crate::{log, Options};
pub fn sort(input: &[String], options: Options) -> structs::Sorted { pub fn sort(input: &[String], options: Options) -> structs::Sorted {
let mut repo: Vec<String> = vec![]; let mut repo_packages: Vec<String> = vec![];
let mut aur: Vec<String> = vec![]; let mut aur_packages: Vec<String> = vec![];
let mut nf: Vec<String> = vec![]; let mut missing_packages: Vec<String> = vec![];
let verbosity = options.verbosity; let verbosity = options.verbosity;
let a = clean(input, options); let packages = clean(input, options);
if verbosity >= 1 { if verbosity >= 1 {
log!("Sorting: {:?}", a.join(" ")); log!("Sorting: {:?}", packages.join(" "));
} }
for b in a { for package in packages {
let rs = Command::new("pacman") let rs = Command::new("pacman")
.arg("-Ss") .arg("-Ss")
.arg(format!("^{}$", &b)) .arg(format!("^{}$", &package))
.stdout(Stdio::null()) .stdout(Stdio::null())
.status() .status()
.expect("Something has gone wrong"); .expect("Something has gone wrong");
if let Some(0) = rs.code() { if let Some(0) = rs.code() {
if verbosity >= 1 { if verbosity >= 1 {
log!("{} found in repos", b); log!("{} found in repos", package);
} }
repo.push(b.to_string()); repo_packages.push(package.to_string());
} else if rpc::rpcinfo(b.to_string()).found { } else if rpc::rpcinfo(&package).found {
if verbosity >= 1 { if verbosity >= 1 {
log!("{} found in AUR", b); log!("{} found in AUR", package);
} }
aur.push(b.to_string()); aur_packages.push(package.to_string());
} else { } else {
if verbosity >= 1 { if verbosity >= 1 {
log!("{} not found", b); log!("{} not found", package);
} }
nf.push(b.to_string()); missing_packages.push(package.to_string());
} }
} }
structs::Sorted::new(repo, aur, nf) structs::Sorted::new(repo_packages, aur_packages, missing_packages)
} }

@ -1,16 +1,18 @@
use crate::ShellCommand;
use std::thread;
use std::time::Duration; use std::time::Duration;
use crate::ShellCommand;
/// Loop sudo so it doesn't time out /// Loop sudo so it doesn't time out
pub fn start_sudoloop() { pub async fn start_sudoloop() {
prompt_sudo(); prompt_sudo().await;
std::thread::spawn(|| loop { tokio::task::spawn(async move {
prompt_sudo(); loop {
thread::sleep(Duration::from_secs(3 * 60)) prompt_sudo().await;
tokio::time::sleep(Duration::from_secs(3 * 60)).await;
}
}); });
} }
fn prompt_sudo() { async fn prompt_sudo() {
while ShellCommand::sudo().arg("-v").wait_success().is_err() {} while ShellCommand::sudo().arg("-v").wait_success().await.is_err() {}
} }

@ -16,7 +16,8 @@ mod database;
mod internal; mod internal;
mod operations; mod operations;
fn main() { #[tokio::main(flavor = "current_thread")]
async fn main() {
if unsafe { libc::geteuid() } == 0 { if unsafe { libc::geteuid() } == 0 {
crash!( AppExitCode::RunAsRoot, "Running amethyst as root is disallowed as it can lead to system breakage. Instead, amethyst will prompt you when it needs superuser permissions"); crash!( AppExitCode::RunAsRoot, "Running amethyst as root is disallowed as it can lead to system breakage. Instead, amethyst will prompt you when it needs superuser permissions");
} }
@ -35,38 +36,38 @@ fn main() {
init(options); init(options);
if args.sudoloop { if args.sudoloop {
start_sudoloop(); start_sudoloop().await;
} }
match args.subcommand.unwrap_or_default() { match args.subcommand.unwrap_or_default() {
Operation::Install(install_args) => cmd_install(install_args, options), Operation::Install(install_args) => cmd_install(install_args, options).await,
Operation::Remove(remove_args) => cmd_remove(remove_args, options), Operation::Remove(remove_args) => cmd_remove(remove_args, options).await,
Operation::Search(search_args) => cmd_search(search_args, options), Operation::Search(search_args) => cmd_search(search_args, options).await,
Operation::Query(query_args) => cmd_query(query_args), Operation::Query(query_args) => cmd_query(query_args).await,
Operation::Upgrade => { Operation::Upgrade => {
info!("Performing system upgrade"); info!("Performing system upgrade");
operations::upgrade(options); operations::upgrade(options).await;
} }
Operation::Clean => { Operation::Clean => {
info!("Removing orphaned packages"); info!("Removing orphaned packages");
operations::clean(options); operations::clean(options).await;
} }
} }
detect(); detect().await;
} }
fn cmd_install(args: InstallArgs, options: Options) { async fn cmd_install(args: InstallArgs, options: Options) {
let packages = args.packages; let packages = args.packages;
let sorted = sort(&packages, options); let sorted = sort(&packages, options);
info!("Attempting to install packages: {}", packages.join(", ")); info!("Attempting to install packages: {}", packages.join(", "));
if !sorted.repo.is_empty() { if !sorted.repo.is_empty() {
operations::install(sorted.repo, options); operations::install(sorted.repo, options).await;
} }
if !sorted.aur.is_empty() { if !sorted.aur.is_empty() {
operations::aur_install(sorted.aur, options); operations::aur_install(sorted.aur, options).await;
} }
if !sorted.nf.is_empty() { if !sorted.nf.is_empty() {
crash!( crash!(
@ -80,6 +81,7 @@ fn cmd_install(args: InstallArgs, options: Options) {
.arg("-c") .arg("-c")
.arg("sudo find /etc -name *.pacnew") .arg("sudo find /etc -name *.pacnew")
.wait_with_output() .wait_with_output()
.await
.silent_unwrap(AppExitCode::Other) .silent_unwrap(AppExitCode::Other)
.stdout; .stdout;
@ -92,51 +94,55 @@ fn cmd_install(args: InstallArgs, options: Options) {
} }
} }
fn cmd_remove(args: RemoveArgs, options: Options) { async fn cmd_remove(args: RemoveArgs, options: Options) {
let packages = args.packages; let packages = args.packages;
info!("Uninstalling packages: {}", &packages.join(", ")); info!("Uninstalling packages: {}", &packages.join(", "));
operations::uninstall(packages, options); operations::uninstall(packages, options).await;
} }
fn cmd_search(args: SearchArgs, options: Options) { async fn cmd_search(args: SearchArgs, options: Options) {
let query_string = args.search.join(" "); let query_string = args.search.join(" ");
if args.aur { if args.aur {
info!("Searching AUR for {}", &query_string); info!("Searching AUR for {}", &query_string);
operations::aur_search(&query_string, options); operations::aur_search(&query_string, options).await;
} }
if args.repo { if args.repo {
info!("Searching repos for {}", &query_string); info!("Searching repos for {}", &query_string);
operations::search(&query_string, options); operations::search(&query_string, options).await;
} }
if !args.aur && !args.repo { if !args.aur && !args.repo {
info!("Searching AUR and repos for {}", &query_string); info!("Searching AUR and repos for {}", &query_string);
operations::search(&query_string, options); operations::search(&query_string, options).await;
operations::aur_search(&query_string, options); operations::aur_search(&query_string, options).await;
} }
} }
fn cmd_query(args: QueryArgs) { async fn cmd_query(args: QueryArgs) {
if args.aur { if args.aur {
ShellCommand::pacman() ShellCommand::pacman()
.arg("-Qm") .arg("-Qm")
.wait_success() .wait_success()
.await
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
} }
if args.repo { if args.repo {
ShellCommand::pacman() ShellCommand::pacman()
.arg("-Qn") .arg("-Qn")
.wait_success() .wait_success()
.await
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
} }
if !args.repo && !args.aur { if !args.repo && !args.aur {
ShellCommand::pacman() ShellCommand::pacman()
.arg("-Qn") .arg("-Qn")
.wait_success() .wait_success()
.await
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
ShellCommand::pacman() ShellCommand::pacman()
.arg("-Qm") .arg("-Qm")
.wait_success() .wait_success()
.await
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
} }
} }

@ -1,8 +1,9 @@
use async_recursion::async_recursion;
use std::env;
use std::env::set_current_dir; use std::env::set_current_dir;
use std::fs::remove_dir_all;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use std::{env, fs}; use tokio::fs;
use crate::internal::commands::ShellCommand; use crate::internal::commands::ShellCommand;
use crate::internal::error::SilentUnwrap; use crate::internal::error::SilentUnwrap;
@ -10,20 +11,22 @@ use crate::internal::exit_code::AppExitCode;
use crate::internal::rpc::rpcinfo; use crate::internal::rpc::rpcinfo;
use crate::{crash, info, log, prompt, Options}; use crate::{crash, info, log, prompt, Options};
pub fn aur_install(a: Vec<String>, options: Options) { /// Installs a given list of packages from the aur
#[async_recursion]
pub async fn aur_install(packages: Vec<String>, options: Options) {
let url = crate::internal::rpc::URL; let url = crate::internal::rpc::URL;
let cachedir = format!("{}/.cache/ame/", env::var("HOME").unwrap()); let cachedir = format!("{}/.cache/ame/", env::var("HOME").unwrap());
let verbosity = options.verbosity; let verbosity = options.verbosity;
let noconfirm = options.noconfirm; let noconfirm = options.noconfirm;
if verbosity >= 1 { if verbosity >= 1 {
log!("Installing from AUR: {:?}", &a); log!("Installing from AUR: {:?}", &packages);
} }
info!("Installing packages {} from the AUR", a.join(", ")); info!("Installing packages {} from the AUR", packages.join(", "));
for package in a { for package in packages {
let rpcres = rpcinfo(package); let rpcres = rpcinfo(&package);
if !rpcres.found { if !rpcres.found {
break; break;
@ -42,6 +45,7 @@ pub fn aur_install(a: Vec<String>, options: Options) {
.arg("clone") .arg("clone")
.arg(format!("{}/{}", url, pkg)) .arg(format!("{}/{}", url, pkg))
.wait() .wait()
.await
.silent_unwrap(AppExitCode::GitError); .silent_unwrap(AppExitCode::GitError);
if verbosity >= 1 { if verbosity >= 1 {
@ -107,6 +111,7 @@ pub fn aur_install(a: Vec<String>, options: Options) {
.arg("-c") .arg("-c")
.arg(format!("ls {}/*.install &> /dev/null", pkg)) .arg(format!("ls {}/*.install &> /dev/null", pkg))
.wait() .wait()
.await
.silent_unwrap(AppExitCode::Other); .silent_unwrap(AppExitCode::Other);
if status.success() { if status.success() {
@ -114,12 +119,15 @@ pub fn aur_install(a: Vec<String>, options: Options) {
.arg("-c") .arg("-c")
.arg(format!("{} {}/*.install", editor, pkg)) .arg(format!("{} {}/*.install", editor, pkg))
.wait() .wait()
.await
.silent_unwrap(AppExitCode::Other); .silent_unwrap(AppExitCode::Other);
} }
let p2 = prompt!(default true, "Would you still like to install {}?", pkg); let p2 = prompt!(default true, "Would you still like to install {}?", pkg);
if !p2 { if !p2 {
fs::remove_dir_all(format!("{}/{}", cachedir, pkg)).unwrap(); fs::remove_dir_all(format!("{}/{}", cachedir, pkg))
.await
.unwrap();
crash!(AppExitCode::UserCancellation, "Not proceeding"); crash!(AppExitCode::UserCancellation, "Not proceeding");
} }
} }
@ -129,12 +137,12 @@ pub fn aur_install(a: Vec<String>, options: Options) {
info!("Moving on to install dependencies"); info!("Moving on to install dependencies");
if !sorted.repo.is_empty() { if !sorted.repo.is_empty() {
crate::operations::install(sorted.repo, newopts); crate::operations::install(sorted.repo, newopts).await;
crate::operations::install(md_sorted.repo, newopts); crate::operations::install(md_sorted.repo, newopts).await;
} }
if !sorted.aur.is_empty() { if !sorted.aur.is_empty() {
crate::operations::aur_install(sorted.aur, newopts); crate::operations::aur_install(sorted.aur, newopts).await;
crate::operations::aur_install(md_sorted.aur, newopts); crate::operations::aur_install(md_sorted.aur, newopts).await;
} }
let mut makepkg_args = vec!["-rsci", "--skippgp"]; let mut makepkg_args = vec!["-rsci", "--skippgp"];
@ -151,10 +159,13 @@ pub fn aur_install(a: Vec<String>, options: Options) {
let status = ShellCommand::makepkg() let status = ShellCommand::makepkg()
.args(makepkg_args) .args(makepkg_args)
.wait() .wait()
.await
.silent_unwrap(AppExitCode::MakePkgError); .silent_unwrap(AppExitCode::MakePkgError);
if !status.success() { if !status.success() {
fs::remove_dir_all(format!("{}/{}", cachedir, pkg)).unwrap(); fs::remove_dir_all(format!("{}/{}", cachedir, pkg))
.await
.unwrap();
crash!( crash!(
AppExitCode::PacmanError, AppExitCode::PacmanError,
"Error encountered while installing {}, aborting", "Error encountered while installing {}, aborting",
@ -163,7 +174,9 @@ pub fn aur_install(a: Vec<String>, options: Options) {
} }
set_current_dir(&cachedir).unwrap(); set_current_dir(&cachedir).unwrap();
remove_dir_all(format!("{}/{}", cachedir, &pkg)).unwrap(); fs::remove_dir_all(format!("{}/{}", cachedir, &pkg))
.await
.unwrap();
// pushes package to database // pushes package to database
crate::database::add(rpcres.package.unwrap(), options); crate::database::add(rpcres.package.unwrap(), options);

@ -1,4 +1,4 @@
use std::process::Command; use tokio::process::Command;
use crate::crash; use crate::crash;
use crate::info; use crate::info;
@ -9,13 +9,15 @@ use crate::log;
use crate::prompt; use crate::prompt;
use crate::Options; use crate::Options;
pub fn clean(options: Options) { /// Removes orphaned packages and cache
pub async fn clean(options: Options) {
let verbosity = options.verbosity; let verbosity = options.verbosity;
let noconfirm = options.noconfirm; let noconfirm = options.noconfirm;
let orphaned_packages = ShellCommand::pacman() let orphaned_packages = ShellCommand::pacman()
.arg("-Qdtq") .arg("-Qdtq")
.wait_with_output() .wait_with_output()
.await
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
if orphaned_packages.stdout.as_str() == "" { if orphaned_packages.stdout.as_str() == "" {
@ -51,6 +53,7 @@ pub fn clean(options: Options) {
.elevated() .elevated()
.args(pacman_args) .args(pacman_args)
.wait() .wait()
.await
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
if pacman_result.success() { if pacman_result.success() {
@ -92,6 +95,7 @@ pub fn clean(options: Options) {
) )
}) })
.wait() .wait()
.await
.unwrap(); .unwrap();
if verbosity >= 1 { if verbosity >= 1 {
@ -102,6 +106,7 @@ pub fn clean(options: Options) {
.elevated() .elevated()
.args(pacman_args) .args(pacman_args)
.wait() .wait()
.await
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
if pacman_result.success() { if pacman_result.success() {

@ -3,7 +3,7 @@ use crate::internal::error::SilentUnwrap;
use crate::internal::exit_code::AppExitCode; use crate::internal::exit_code::AppExitCode;
use crate::{crash, info, log, Options}; use crate::{crash, info, log, Options};
pub fn install(packages: Vec<String>, options: Options) { pub async fn install(packages: Vec<String>, options: Options) {
info!("Installing packages {} from repos", &packages.join(", ")); info!("Installing packages {} from repos", &packages.join(", "));
let mut opers = vec!["-S", "--needed"]; let mut opers = vec!["-S", "--needed"];
if options.noconfirm { if options.noconfirm {
@ -24,6 +24,7 @@ pub fn install(packages: Vec<String>, options: Options) {
.args(opers) .args(opers)
.args(&packages) .args(&packages)
.wait() .wait()
.await
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
if !status.success() { if !status.success() {
crash!( crash!(

@ -4,7 +4,7 @@ use crate::internal::exit_code::AppExitCode;
use crate::internal::rpc::rpcsearch; use crate::internal::rpc::rpcsearch;
use crate::{log, Options}; use crate::{log, Options};
pub fn aur_search(query: &str, options: Options) { pub async fn aur_search(query: &str, options: Options) {
let verbosity = options.verbosity; let verbosity = options.verbosity;
let res = rpcsearch(query.to_string()); let res = rpcsearch(query.to_string());
@ -25,12 +25,13 @@ pub fn aur_search(query: &str, options: Options) {
} }
} }
pub fn repo_search(query: &str, options: Options) { pub async fn repo_search(query: &str, options: Options) {
let verbosity = options.verbosity; let verbosity = options.verbosity;
let output = ShellCommand::pacman() let output = ShellCommand::pacman()
.arg("-Ss") .arg("-Ss")
.arg(query) .arg(query)
.wait_with_output() .wait_with_output()
.await
.silent_unwrap(AppExitCode::PacmanError) .silent_unwrap(AppExitCode::PacmanError)
.stdout; .stdout;

@ -1,12 +1,13 @@
use std::env;
use std::path::Path; use std::path::Path;
use std::{env, fs}; use tokio::fs;
use crate::internal::commands::ShellCommand; use crate::internal::commands::ShellCommand;
use crate::internal::error::SilentUnwrap; use crate::internal::error::SilentUnwrap;
use crate::internal::exit_code::AppExitCode; use crate::internal::exit_code::AppExitCode;
use crate::{log, Options}; use crate::{log, Options};
pub fn uninstall(packages: Vec<String>, options: Options) { pub async fn uninstall(packages: Vec<String>, options: Options) {
let mut pacman_args = vec!["-Rs"]; 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(|s| s.as_str()).collect());
@ -22,6 +23,7 @@ pub fn uninstall(packages: Vec<String>, options: Options) {
.elevated() .elevated()
.args(pacman_args) .args(pacman_args)
.wait_success() .wait_success()
.await
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
if verbosity >= 1 { if verbosity >= 1 {
@ -45,6 +47,7 @@ pub fn uninstall(packages: Vec<String>, options: Options) {
env::var("HOME").unwrap(), env::var("HOME").unwrap(),
package package
))) )))
.await
.unwrap(); .unwrap();
} }
} }

@ -5,7 +5,8 @@ use crate::internal::rpc::rpcinfo;
use crate::operations::aur_install::aur_install; use crate::operations::aur_install::aur_install;
use crate::{info, log, prompt, Options}; use crate::{info, log, prompt, Options};
pub fn upgrade(options: Options) { /// Upgrades all installed packages
pub async fn upgrade(options: Options) {
let verbosity = options.verbosity; let verbosity = options.verbosity;
let noconfirm = options.noconfirm; let noconfirm = options.noconfirm;
@ -22,15 +23,16 @@ pub fn upgrade(options: Options) {
.elevated() .elevated()
.args(pacman_args) .args(pacman_args)
.wait() .wait()
.await
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
if pacman_result.success() { if pacman_result.success() {
info!("Successfully upgraded repo packages"); info!("Successfully upgraded repo packages");
} else { } else {
let cont = prompt!(default false, let continue_upgrading = prompt!(default false,
"Failed to upgrade repo packages, continue to upgrading AUR packages?", "Failed to upgrade repo packages, continue to upgrading AUR packages?",
); );
if !cont { if !continue_upgrading {
info!("Exiting"); info!("Exiting");
std::process::exit(AppExitCode::PacmanError as i32); std::process::exit(AppExitCode::PacmanError as i32);
} }
@ -40,23 +42,23 @@ pub fn upgrade(options: Options) {
log!("Upgrading AUR packages"); log!("Upgrading AUR packages");
} }
let res = crate::database::query(options); let packages = crate::database::query(options);
if verbosity >= 1 { if verbosity >= 1 {
log!("{:?}", &res); log!("{:?}", &packages);
} }
let mut aur_upgrades = vec![]; let mut aur_upgrades = vec![];
for r in res {
let re = r.clone(); for package in packages {
let ver = rpcinfo(r.name); let remote_package = rpcinfo(&package.name);
if ver.package.unwrap().version != r.version {
aur_upgrades.push(re.name); if remote_package.package.unwrap().version != package.version {
aur_upgrades.push(package.name);
} }
} }
if !aur_upgrades.is_empty() { if !aur_upgrades.is_empty() {
aur_install(aur_upgrades, options); aur_install(aur_upgrades, options).await;
} else { } else {
info!("No upgrades available for installed AUR packages"); info!("No upgrades available for installed AUR packages");
} }

Loading…
Cancel
Save