Merge pull request #17 from crystal-linux/development

v3.5.0 Development -> Main
i18n
Michal 2 years ago committed by GitHub
commit 683fc6bf3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

49
Cargo.lock generated

@ -4,7 +4,7 @@ version = 3
[[package]] [[package]]
name = "Amethyst" name = "Amethyst"
version = "3.4.0" version = "3.5.0"
dependencies = [ dependencies = [
"clap", "clap",
"colored", "colored",
@ -14,6 +14,7 @@ dependencies = [
"regex", "regex",
"rm_rf", "rm_rf",
"serde", "serde",
"spinoff",
"ureq", "ureq",
] ]
@ -252,6 +253,12 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "maplit"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]] [[package]]
name = "matches" name = "matches"
version = "0.1.9" version = "0.1.9"
@ -447,6 +454,12 @@ dependencies = [
"stacker", "stacker",
] ]
[[package]]
name = "rustversion"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.11" version = "1.0.11"
@ -517,6 +530,18 @@ dependencies = [
"serde", "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]] [[package]]
name = "stacker" name = "stacker"
version = "0.1.15" version = "0.1.15"
@ -536,6 +561,28 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 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]] [[package]]
name = "syn" name = "syn"
version = "1.0.99" version = "1.0.99"

@ -1,6 +1,6 @@
[package] [package]
name = "Amethyst" name = "Amethyst"
version = "3.4.0" version = "3.5.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"
@ -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" ] } 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 }
rm_rf = { version = "0.6.2", default-features = false } rm_rf = { version = "0.6.2", default-features = false }
spinoff = { version = "0.5.3", default-features = false }

@ -3,7 +3,7 @@
# Developer: Michal S <michal[at]tar[dot]black> # Developer: Michal S <michal[at]tar[dot]black>
pkgname=amethyst pkgname=amethyst
pkgver=3.4.0 pkgver=3.5.0
pkgrel=1 pkgrel=1
pkgdesc="A fast and efficient AUR helper" pkgdesc="A fast and efficient AUR helper"
arch=('x86_64') arch=('x86_64')

@ -66,21 +66,8 @@ Tested on latest Cargo (1.60.0-nightly)
### TODO: ### TODO:
#### v3.3.0 #### v3.6.0
- ~~Add clean function~~
- ~~Make flags global~~
- ~~Add pacdiff function~~
- ~~Squash any remaining bugs~~
#### v3.4.0
- ~~New AUR upgrade checker~~
- ~~Bugfixes, bugfixes, bugfixes!~~~
#### v3.5.0
- Implement some sort of spinner for longer operations
- Allow editing of PKGBUILDs before install - Allow editing of PKGBUILDs before install
- Allow to choose provider of package
- Highlight optdepends at the end of an install operation
<!-- <!--

@ -15,7 +15,7 @@ pub struct Args {
pub no_confirm: bool, pub no_confirm: bool,
/// Loops sudo in the background to ensure it doesn't time out during long builds /// Loops sudo in the background to ensure it doesn't time out during long builds
#[clap(long = "sudoloop")] #[clap(long = "sudoloop", global = true)]
pub sudoloop: bool, pub sudoloop: bool,
} }
@ -37,18 +37,26 @@ pub enum Operation {
#[clap(name = "query", aliases = & ["q", "qu", "l", "ls", "-Q"])] #[clap(name = "query", aliases = & ["q", "qu", "l", "ls", "-Q"])]
Query(QueryArgs), Query(QueryArgs),
/// Gets info about a package
#[clap(name = "info", aliases = & ["inf", "in", "i", "-Qi"])]
Info(InfoArgs),
/// Upgrades locally installed packages to their latest versions /// Upgrades locally installed packages to their latest versions
#[clap(name = "upgrade", aliases = & ["upg", "up", "u", "-Syu"])] #[clap(name = "upgrade", aliases = & ["upg", "up", "u", "-Syu"])]
Upgrade, Upgrade(UpgradeArgs),
/// Removes all orphaned packages /// Removes all orphaned packages
#[clap(name = "clean", aliases = & ["cln", "cl", "-Sc"])] #[clap(name = "clean", aliases = & ["cln", "cl", "-Sc"])]
Clean, Clean,
/// Runs pacdiff
#[clap(name = "diff", aliases = & ["dif", "di", "-d"])]
Diff,
} }
impl Default for Operation { impl Default for Operation {
fn default() -> Self { fn default() -> Self {
Self::Upgrade Self::Upgrade(UpgradeArgs::default())
} }
} }
@ -59,9 +67,11 @@ pub struct InstallArgs {
pub packages: Vec<String>, pub packages: Vec<String>,
/// Installs only from the AUR /// Installs only from the AUR
#[clap(long, short)]
pub aur: bool, pub aur: bool,
/// Install the packages from the pacman-defined repositories /// Install the packages from the pacman-defined repositories
#[clap(long, short)]
pub repo: bool, pub repo: bool,
} }
@ -97,3 +107,21 @@ pub struct QueryArgs {
#[clap(long, short, from_global)] #[clap(long, short, from_global)]
pub repo: bool, pub repo: bool,
} }
#[derive(Default, Debug, Clone, Parser)]
pub struct InfoArgs {
/// The name of the package(s) to get info on
#[clap(required = true)]
pub package: String,
}
#[derive(Default, Debug, Clone, Parser)]
pub struct UpgradeArgs {
/// Upgrades only repo/native packages
#[clap(long, short)]
pub repo: bool,
/// Upgrades only from the AUR
#[clap(long, short)]
pub aur: bool,
}

@ -1,20 +1,23 @@
use std::env;
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::{info, prompt, warn}; use crate::{prompt, spinner, warn};
pub fn detect() { pub fn detect() {
info!("Scanning for pacnew files"); // Start spinner
let sp = spinner!("Scanning for pacnew files");
let mut pacnew = vec![]; let mut pacnew = vec![];
// Run `find` to find pacnew files and split by lines into a vec // Run `find` to find pacnew files and split by lines into a vec
let find = std::process::Command::new("sudo") let find = ShellCommand::pacdiff()
.arg("pacdiff") .args(&["-o", "-f"])
.arg("-f") .elevated()
.output() .wait_with_output()
.unwrap(); .silent_unwrap(AppExitCode::PacmanError);
let find_lines = std::str::from_utf8(&find.stdout).unwrap().split('\n'); let find_lines = find.stdout.split('\n');
for line in find_lines { for line in find_lines {
if !line.is_empty() { if !line.is_empty() {
pacnew.push(line.to_string()); pacnew.push(line.to_string());
@ -23,16 +26,28 @@ pub fn detect() {
// If pacnew files are found, warn the user and prompt to pacdiff // If pacnew files are found, warn the user and prompt to pacdiff
if !pacnew.is_empty() { 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 { 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"); if env::var("PACDIFF_WARNING").unwrap_or_else(|_| "1".to_string()) != "0" {
let cont = prompt!(default false, "Continue?"); 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");
if cont { 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() ShellCommand::pacdiff()
.elevated() .elevated()
.wait() .wait()
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
} }
} }
} else {
sp.stop_bold("No pacnew files found");
} }
} }

@ -8,20 +8,6 @@ pub fn init(options: Options) {
let verbosity = options.verbosity; let verbosity = options.verbosity;
let homedir = env::var("HOME").unwrap(); let homedir = env::var("HOME").unwrap();
// Initialise stateful directory
if !Path::new(&format!("{}/.local/share/ame", homedir)).exists() {
if verbosity >= 1 {
log!("Initialising stateful directory");
}
std::fs::create_dir_all(format!("{}/.local/share/ame", homedir)).unwrap_or_else(|e| {
crash!(
AppExitCode::FailedCreatingPaths,
"Failed to create stateful directory: {}",
e
);
});
}
// If cache path doesn't exist, create it, if it does, delete it and recreate it // If cache path doesn't exist, create it, if it does, delete it and recreate it
if !Path::new(&format!("{}/.cache/ame/", homedir)).exists() { if !Path::new(&format!("{}/.cache/ame/", homedir)).exists() {
if verbosity >= 1 { if verbosity >= 1 {

@ -14,6 +14,9 @@ pub struct Package {
#[serde(rename = "MakeDepends")] #[serde(rename = "MakeDepends")]
#[serde(default)] #[serde(default)]
pub make_depends: Vec<String>, pub make_depends: Vec<String>,
#[serde(rename = "OptDepends")]
#[serde(default)]
pub opt_depends: Vec<String>,
} }
#[derive(serde::Deserialize)] #[derive(serde::Deserialize)]

@ -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<S: ToString>(msg: S) { pub fn log_info<S: ToString>(msg: S) {
let msg = msg.to_string(); let msg = msg.to_string();
let msg = if internal::uwu_enabled() { let msg = if internal::uwu_enabled() {
@ -137,3 +144,40 @@ pub fn prompt_yn<S: ToString>(question: S, default_true: bool) -> bool {
default_true 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,
),
}
}

@ -6,9 +6,11 @@ use clap::Parser;
use internal::commands::ShellCommand; use internal::commands::ShellCommand;
use internal::error::SilentUnwrap; use internal::error::SilentUnwrap;
use crate::args::{InstallArgs, Operation, QueryArgs, RemoveArgs, SearchArgs}; use crate::args::{
InfoArgs, InstallArgs, Operation, QueryArgs, RemoveArgs, SearchArgs, UpgradeArgs,
};
use crate::internal::exit_code::AppExitCode; use crate::internal::exit_code::AppExitCode;
use crate::internal::{init, sort, start_sudoloop, structs::Options}; use crate::internal::{detect, init, sort, start_sudoloop, structs::Options};
#[global_allocator] #[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
@ -51,14 +53,16 @@ fn main() {
Operation::Remove(remove_args) => cmd_remove(remove_args, options), Operation::Remove(remove_args) => cmd_remove(remove_args, options),
Operation::Search(search_args) => cmd_search(search_args, options), Operation::Search(search_args) => cmd_search(search_args, options),
Operation::Query(query_args) => cmd_query(query_args), Operation::Query(query_args) => cmd_query(query_args),
Operation::Upgrade => { Operation::Info(info_args) => cmd_info(info_args),
info!("Performing system upgrade"); Operation::Upgrade(upgrade_args) => cmd_upgrade(upgrade_args, options),
operations::upgrade(options);
}
Operation::Clean => { Operation::Clean => {
info!("Removing orphaned packages"); info!("Removing orphaned packages");
operations::clean(options); operations::clean(options);
} }
Operation::Diff => {
info!("Running pacdiff");
detect();
}
} }
} }
@ -80,11 +84,45 @@ fn cmd_install(args: InstallArgs, options: Options) {
if !sorted.repo.is_empty() { if !sorted.repo.is_empty() {
// If repo packages found, install them // If repo packages found, install them
operations::install(sorted.repo, options); operations::install(sorted.repo.clone(), options);
} }
if !sorted.aur.is_empty() { if !sorted.aur.is_empty() {
// If AUR packages found, install them // If AUR packages found, install them
operations::aur_install(sorted.aur, options); operations::aur_install(sorted.aur.clone(), options);
}
// Show optional dependencies for installed packages
info!("Showing optional dependencies for installed packages");
for r in sorted.repo {
info!("{}:", r);
std::process::Command::new("expac")
.args(&["-S", "-l", "\n ", " %O", &r])
.spawn()
.unwrap()
.wait()
.unwrap();
}
for a in sorted.aur {
info!("{}:", a);
let dir_bytes = std::process::Command::new("mktemp")
.arg("-d")
.output()
.unwrap()
.stdout;
let dir = String::from_utf8(dir_bytes).unwrap();
std::process::Command::new("bash")
.arg("-c")
.arg(format!("\
cd {}
curl -L https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h={} -o PKGBUILD -s
source PKGBUILD
printf ' %s\\n' \"${{optdepends[@]}}\"
", dir, a))
.spawn()
.unwrap()
.wait()
.unwrap();
std::fs::remove_dir_all(&std::path::Path::new(&dir.trim())).unwrap();
} }
} }
@ -150,3 +188,16 @@ fn cmd_query(args: QueryArgs) {
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
} }
} }
fn cmd_info(args: InfoArgs) {
ShellCommand::pacman()
.arg("-Qi")
.arg(args.package)
.wait()
.silent_unwrap(AppExitCode::PacmanError);
}
fn cmd_upgrade(args: UpgradeArgs, options: Options) {
info!("Performing system upgrade");
operations::upgrade(options, args);
}

@ -8,7 +8,7 @@ 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::internal::rpc::rpcinfo; use crate::internal::rpc::rpcinfo;
use crate::{crash, info, log, prompt, Options}; use crate::{crash, info, log, prompt, warn, Options};
pub fn aur_install(a: Vec<String>, options: Options) { pub fn aur_install(a: Vec<String>, options: Options) {
// Initialise variables // Initialise variables
@ -23,6 +23,8 @@ pub fn aur_install(a: Vec<String>, options: Options) {
info!("Installing packages {} from the AUR", a.join(", ")); info!("Installing packages {} from the AUR", a.join(", "));
let mut failed = vec![];
for package in a { for package in a {
// Query AUR for package info // Query AUR for package info
let rpcres = rpcinfo(package); let rpcres = rpcinfo(package);
@ -67,10 +69,11 @@ pub fn aur_install(a: Vec<String>, options: Options) {
} }
// Sort dependencies and makedepends // Sort dependencies and makedepends
log!("Sorting dependencies"); if verbosity >= 1 {
let sorted = crate::internal::sort(&rpcres.package.as_ref().unwrap().depends, options); log!("Sorting dependencies and makedepends");
log!("Sorting make dependencies"); }
let md_sorted = let mut sorted = crate::internal::sort(&rpcres.package.as_ref().unwrap().depends, options);
let mut md_sorted =
crate::internal::sort(&rpcres.package.as_ref().unwrap().make_depends, options); crate::internal::sort(&rpcres.package.as_ref().unwrap().make_depends, options);
if verbosity >= 1 { if verbosity >= 1 {
@ -85,6 +88,29 @@ pub fn aur_install(a: Vec<String>, options: Options) {
asdeps: true, asdeps: true,
}; };
// Get a list of installed packages
let installed = ShellCommand::pacman()
.elevated()
.args(&["-Qq"])
.wait_with_output()
.silent_unwrap(AppExitCode::PacmanError)
.stdout
.split_whitespace()
.collect::<Vec<&str>>()
.iter()
.map(|s| s.to_string())
.collect::<Vec<String>>();
// Remove installed packages from sorted dependencies and makedepends
if verbosity >= 1 {
log!("Removing installed packages from sorted dependencies and makedepends");
}
sorted.aur.retain(|x| !installed.contains(x));
sorted.repo.retain(|x| !installed.contains(x));
md_sorted.aur.retain(|x| !installed.contains(x));
md_sorted.repo.retain(|x| !installed.contains(x));
// If dependencies are not found in AUR or repos, crash // If dependencies are not found in AUR or repos, crash
if !sorted.nf.is_empty() || !md_sorted.nf.is_empty() { if !sorted.nf.is_empty() || !md_sorted.nf.is_empty() {
crash!( crash!(
@ -143,15 +169,19 @@ pub fn aur_install(a: Vec<String>, options: Options) {
// Install dependencies and makedepends // Install dependencies and makedepends
if !sorted.repo.is_empty() { if !sorted.repo.is_empty() {
crate::operations::install(sorted.repo, newopts); crate::operations::install(sorted.repo, newopts);
crate::operations::install(md_sorted.repo, newopts);
} }
if !sorted.aur.is_empty() { if !sorted.aur.is_empty() {
crate::operations::aur_install(sorted.aur, newopts); crate::operations::aur_install(sorted.aur, newopts);
}
if !md_sorted.repo.is_empty() {
crate::operations::install(md_sorted.repo, newopts);
}
if !md_sorted.aur.is_empty() {
crate::operations::aur_install(md_sorted.aur, newopts); crate::operations::aur_install(md_sorted.aur, newopts);
} }
// Build makepkg args // Build makepkg args
let mut makepkg_args = vec!["-rsci", "--skippgp"]; let mut makepkg_args = vec!["-rsci", "--skippgp", "--needed"];
if options.asdeps { if options.asdeps {
makepkg_args.push("--asdeps") makepkg_args.push("--asdeps")
} }
@ -169,13 +199,10 @@ pub fn aur_install(a: Vec<String>, options: Options) {
.silent_unwrap(AppExitCode::MakePkgError); .silent_unwrap(AppExitCode::MakePkgError);
if !status.success() { if !status.success() {
// If build failed, crash // If build failed, push to failed vec
fs::remove_dir_all(format!("{}/{}", cachedir, pkg)).unwrap(); fs::remove_dir_all(format!("{}/{}", cachedir, pkg)).unwrap();
crash!( failed.push(pkg.clone());
AppExitCode::PacmanError, return;
"Error encountered while installing {}, aborting",
pkg,
);
} }
// Return to cachedir // Return to cachedir
@ -184,4 +211,9 @@ pub fn aur_install(a: Vec<String>, options: Options) {
// Remove package from cache // Remove package from cache
remove_dir_all(format!("{}/{}", cachedir, &pkg)).unwrap(); remove_dir_all(format!("{}/{}", cachedir, &pkg)).unwrap();
} }
// If any packages failed to build, warn user with failed packages
if !failed.is_empty() {
warn!("Failed to build packages {}", failed.join(", "));
}
} }

@ -1,10 +1,11 @@
use crate::args::UpgradeArgs;
use crate::internal::commands::ShellCommand; use crate::internal::commands::ShellCommand;
use crate::internal::detect; use crate::internal::detect;
use crate::internal::error::SilentUnwrap; use crate::internal::error::SilentUnwrap;
use crate::internal::exit_code::AppExitCode; use crate::internal::exit_code::AppExitCode;
use crate::internal::rpc::rpcinfo; 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, spinner, warn, Options};
#[derive(Debug)] #[derive(Debug)]
struct QueriedPackage { struct QueriedPackage {
@ -12,36 +13,49 @@ struct QueriedPackage {
pub version: String, pub version: String,
} }
pub fn upgrade(options: Options) { pub fn upgrade(options: Options, args: UpgradeArgs) {
// Initialise variables // Initialise variables
let verbosity = options.verbosity; let verbosity = options.verbosity;
let noconfirm = options.noconfirm; let noconfirm = options.noconfirm;
// Build pacman args let args = if !args.aur && !args.repo {
let mut pacman_args = vec!["-Syu"]; UpgradeArgs {
if noconfirm { aur: true,
pacman_args.push("--noconfirm"); repo: true,
} }
} else {
args
};
if args.repo {
// Build pacman args
let mut pacman_args = vec!["-Syu"];
if noconfirm {
pacman_args.push("--noconfirm");
}
if verbosity >= 1 { if verbosity >= 1 {
log!("Upgrading repo packages"); log!("Upgrading repo packages");
} }
// Upgrade repo packages // Upgrade repo packages
let pacman_result = ShellCommand::pacman() let pacman_result = ShellCommand::pacman()
.elevated() .elevated()
.args(pacman_args) .args(pacman_args)
.wait() .wait()
.silent_unwrap(AppExitCode::PacmanError); .silent_unwrap(AppExitCode::PacmanError);
if pacman_result.success() {
// If pacman was successful, notify user
info!("Successfully upgraded repo packages");
} else {
// Otherwise warn user
warn!("Failed to upgrade repo packages.",);
}
}
if pacman_result.success() { if args.repo && args.aur {
// If pacman was successful, notify user let cont = prompt!(default false, "Continue to upgrade AUR packages?");
info!("Successfully upgraded repo packages");
} else {
// Otherwise, prompt user whether to continue
let cont = prompt!(default false,
"Failed to upgrade repo packages, continue to upgrading AUR packages?",
);
if !cont { if !cont {
// If user doesn't want to continue, break // If user doesn't want to continue, break
info!("Exiting"); info!("Exiting");
@ -49,69 +63,76 @@ pub fn upgrade(options: Options) {
} }
} }
if verbosity >= 1 { if args.aur {
log!("Checking AUR upgrades...");
}
// List non-native packages using `pacman -Qm` and collect to a Vec<String>
let non_native = ShellCommand::pacman()
.arg("-Qm")
.args(&["--color", "never"])
.wait_with_output()
.silent_unwrap(AppExitCode::PacmanError);
// Collect by lines to a Vec<String>
let mut non_native = non_native.stdout.split('\n').collect::<Vec<&str>>();
// Remove last element, which is an empty line
non_native.pop();
// Parse non-native packages into a Vec<QueriedPackage>
let mut parsed_non_native: Vec<QueriedPackage> = vec![];
for pkg in non_native {
// Split by space
let split = pkg.split(' ').collect::<Vec<&str>>();
if verbosity >= 1 { if verbosity >= 1 {
log!("{:?}", split); log!("Checking AUR upgrades...");
} }
// Create QueriedPackage and push it to parsed_non_native
let name = split[0].to_string();
let version = split[1].to_string();
parsed_non_native.push(QueriedPackage { name, version });
}
if verbosity >= 1 {
log!("{:?}", &parsed_non_native);
}
// Check if AUR package versions are the same as installed // Start spinner
let mut aur_upgrades = vec![]; let sp = spinner!("Checking AUR upgrades...");
for pkg in parsed_non_native {
// Query AUR // List non-native packages using `pacman -Qm` and collect to a Vec<String>
let rpc_result = rpcinfo((&*pkg.name).to_string()); let non_native = ShellCommand::pacman()
.arg("-Qm")
.args(&["--color", "never"])
.wait_with_output()
.silent_unwrap(AppExitCode::PacmanError);
// Collect by lines to a Vec<String>
let mut non_native = non_native.stdout.split('\n').collect::<Vec<&str>>();
// Remove last element, which is an empty line
non_native.pop();
// Parse non-native packages into a Vec<QueriedPackage>
let mut parsed_non_native: Vec<QueriedPackage> = vec![];
for pkg in non_native {
// Split by space
let split = pkg.split(' ').collect::<Vec<&str>>();
if verbosity >= 1 {
log!("{:?}", split);
}
// Create QueriedPackage and push it to parsed_non_native
let name = split[0].to_string();
let version = split[1].to_string();
parsed_non_native.push(QueriedPackage { name, version });
}
if !rpc_result.found { if verbosity >= 1 {
// If package not found, skip log!("{:?}", &parsed_non_native);
continue;
} }
// If versions differ, push to a vector // Check if AUR package versions are the same as installed
if rpc_result.package.unwrap().version != pkg.version { let mut aur_upgrades = vec![];
aur_upgrades.push(pkg.name); for pkg in parsed_non_native {
// Query AUR
let rpc_result = rpcinfo((&*pkg.name).to_string());
if !rpc_result.found {
// If package not found, skip
continue;
}
// If versions differ, push to a vector
if rpc_result.package.unwrap().version != pkg.version {
aur_upgrades.push(pkg.name);
}
} }
}
// If vector isn't empty, prompt to install AUR packages from vector, effectively upgrading sp.stop_bold("Finished!");
if !aur_upgrades.is_empty() {
let cont = prompt!(default false, // If vector isn't empty, prompt to install AUR packages from vector, effectively upgrading
"Found AUR packages {} have new versions available, upgrade?", if !aur_upgrades.is_empty() {
aur_upgrades.join(", "), let cont = prompt!(default true,
); "Found AUR packages {} have new versions available, upgrade?",
if cont { aur_upgrades.join(", "),
aur_install(aur_upgrades, options); );
}; if cont {
} else { aur_install(aur_upgrades, options);
info!("No upgrades available for installed AUR packages"); };
} else {
info!("No upgrades available for installed AUR packages");
}
} }
// Check for .pacnew files // Check for .pacnew files

Loading…
Cancel
Save