Reimplement logging by utilizing the tracing crate

Signed-off-by: trivernis <trivernis@protonmail.com>
i18n
trivernis 2 years ago
parent f1bbb2626c
commit 052d176f4a
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

147
Cargo.lock generated

@ -13,13 +13,16 @@ dependencies = [
"color-eyre",
"colored",
"crossterm",
"dialoguer",
"futures",
"indicatif",
"lazy_static",
"libc",
"native-tls",
"parking_lot",
"regex",
"rusqlite",
"serde",
"spinoff",
"textwrap",
"tokio",
"toml",
@ -257,6 +260,20 @@ dependencies = [
"winapi",
]
[[package]]
name = "console"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"terminal_size",
"unicode-width",
"winapi",
]
[[package]]
name = "core-foundation"
version = "0.9.3"
@ -298,6 +315,23 @@ dependencies = [
"winapi",
]
[[package]]
name = "dialoguer"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92e7e37ecef6857fdc0c0c5d42fd5b0938e46590c2183cc92dd310a6d078eb1"
dependencies = [
"console",
"tempfile",
"zeroize",
]
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "encoding_rs"
version = "0.8.31"
@ -338,6 +372,12 @@ dependencies = [
"instant",
]
[[package]]
name = "fixedbitset"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "fnv"
version = "1.0.7"
@ -625,6 +665,18 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "indicatif"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc42b206e70d86ec03285b123e65a5458c92027d1fb2ae3555878b8113b3ddf"
dependencies = [
"console",
"number_prefix",
"tokio",
"unicode-width",
]
[[package]]
name = "instant"
version = "0.1.12"
@ -696,12 +748,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "maplit"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "matchers"
version = "0.1.0"
@ -768,6 +814,22 @@ dependencies = [
"tempfile",
]
[[package]]
name = "num_cpus"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "number_prefix"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "object"
version = "0.29.0"
@ -856,10 +918,13 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
dependencies = [
"backtrace",
"cfg-if",
"libc",
"petgraph",
"redox_syscall",
"smallvec",
"thread-id",
"windows-sys",
]
@ -869,6 +934,16 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "petgraph"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143"
dependencies = [
"fixedbitset",
"indexmap",
]
[[package]]
name = "pin-project-lite"
version = "0.2.9"
@ -1030,12 +1105,6 @@ version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[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"
@ -1194,46 +1263,12 @@ dependencies = [
"winapi",
]
[[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 = "strsim"
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"
@ -1310,6 +1345,17 @@ dependencies = [
"syn",
]
[[package]]
name = "thread-id"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fdfe0627923f7411a43ec9ec9c39c3a9b4151be313e0922042581fb6c9b717f"
dependencies = [
"libc",
"redox_syscall",
"winapi",
]
[[package]]
name = "thread_local"
version = "1.1.4"
@ -1345,6 +1391,7 @@ dependencies = [
"libc",
"memchr",
"mio",
"num_cpus",
"once_cell",
"pin-project-lite",
"signal-hook-registry",
@ -1738,3 +1785,9 @@ checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
dependencies = [
"winapi",
]
[[package]]
name = "zeroize"
version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"

@ -39,12 +39,15 @@ futures = "0.3.23"
tracing = "0.1.36"
tracing-subscriber = { version = "0.3.15", features = ["env-filter"] }
textwrap = "0.15.0"
spinoff = "0.5.3"
crossterm = "0.25.0"
toml = "0.5.9"
clap_complete = "3.2.4"
color-eyre = { version = "0.6.2", features = ["issue-url", "url"] }
indicatif = { version = "0.17.0", features = ["tokio"] }
lazy_static = "1.4.0"
parking_lot = { version = "0.12.1", features = ["deadlock_detection"] }
dialoguer = "0.10.2"
[dependencies.tokio]
version = "1.20.1"
features = ["rt", "io-std", "io-util", "process", "time", "macros", "tracing", "fs"]
features = ["rt", "rt-multi-thread", "io-std", "io-util", "process", "time", "macros", "tracing", "fs"]

@ -1,13 +1,10 @@
use regex::Regex;
use crate::{log, Options};
/// Strips packages from versioning and other extraneous information.
pub fn clean(a: &[String], options: Options) -> Vec<String> {
pub fn clean(a: &[String]) -> Vec<String> {
// Strip versioning from package names
let r = Regex::new(r"(\S+)((?:>=|<=|>|<|=\W)\S+$)").unwrap();
let mut cleaned: Vec<String> = vec![];
let verbosity = options.verbosity;
// Push cleaned package names to vector
for b in a {
@ -19,9 +16,7 @@ pub fn clean(a: &[String], options: Options) -> Vec<String> {
}
}
if verbosity >= 1 {
log!("Cleaned: {:?}\nInto: {:?}", a, cleaned);
}
tracing::debug!("Cleaned: {:?}\nInto: {:?}", a, cleaned);
cleaned
}

@ -2,12 +2,16 @@ use crate::internal::commands::ShellCommand;
use crate::internal::config;
use crate::internal::error::SilentUnwrap;
use crate::internal::exit_code::AppExitCode;
use crate::{prompt, spinner, warn};
use crate::logging::get_logger;
use crate::prompt;
use super::prompt_sudo_single;
/// Searches the filesystem for .pacnew files and helps the user deal with them.
pub async fn detect() {
// Start spinner
let sp = spinner!("Scanning for pacnew files");
prompt_sudo_single().await.expect("Sudo prompt failed");
let pb = get_logger().new_progress_spinner();
pb.set_message("Scanning for pacnew files");
let mut pacnew = vec![];
@ -27,11 +31,13 @@ pub async fn detect() {
// If pacnew files are found, warn the user and prompt to pacdiff
if pacnew.is_empty() {
sp.stop_bold("No pacnew files found");
pb.finish_with_message("No pacnew files found");
get_logger().reset_output_type();
} 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.");
pb.finish_with_message("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.");
get_logger().reset_output_type();
let choice = prompt!(default false, "Would you like Amethyst to run pacdiff to deal with this? You can always deal with this later by running `sudo pacdiff`");
let choice = prompt!(default no, "Would you like Amethyst to run pacdiff to deal with this? You can always deal with this later by running `sudo pacdiff`");
if choice {
let config = config::read();
if config.base.pacdiff_warn {
@ -41,9 +47,9 @@ pub async fn detect() {
.await
.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 `pacdiff_warn` to \"false\" in ~/.config/ame/config.toml");
let cont = prompt!(default false, "Continue?");
tracing::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");
tracing::warn!("You can surpress this warning in the future by setting `pacdiff_warn` to \"false\" in ~/.config/ame/config.toml");
let cont = prompt!(default no, "Continue?");
if cont {
ShellCommand::pacdiff()
.elevated()

@ -2,19 +2,16 @@ use std::env;
use std::path::Path;
use std::process::Command;
use crate::{crash, internal::exit_code::AppExitCode, log, Options};
use crate::{crash, internal::exit_code::AppExitCode};
pub fn init(options: Options) {
let verbosity = options.verbosity;
pub fn init() {
let homedir = env::var("HOME").unwrap();
if !Path::new(&format!("{}/.local/share/ame", homedir)).exists() {
let r = std::fs::create_dir_all(format!("{}/.local/share/ame", homedir));
match r {
Ok(_) => {
if verbosity >= 1 {
log!("Created path: {}/.local/share/ame", homedir);
}
tracing::debug!("Created path: {}/.local/share/ame", homedir);
}
Err(e) => {
crash!(
@ -31,9 +28,7 @@ pub fn init(options: Options) {
let r = std::fs::create_dir_all(format!("{}/.cache/ame", homedir));
match r {
Ok(_) => {
if verbosity >= 1 {
log!("Created path: {}/.cache/ame", homedir);
}
tracing::debug!("Created path: {}/.cache/ame", homedir);
}
Err(e) => {
crash!(
@ -48,9 +43,7 @@ pub fn init(options: Options) {
let r = std::fs::remove_dir_all(format!("{}/.cache/ame", homedir));
match r {
Ok(_) => {
if verbosity >= 1 {
log!("Removing cache: {}/.cache/ame", homedir);
}
tracing::debug!("Removing cache: {}/.cache/ame", homedir);
}
Err(e) => {
crash!(
@ -64,9 +57,7 @@ pub fn init(options: Options) {
let r2 = std::fs::create_dir_all(format!("{}/.cache/ame", homedir));
match r2 {
Ok(_) => {
if verbosity >= 1 {
log!("Created path: {}/.cache/ame", homedir);
}
tracing::debug!("Created path: {}/.cache/ame", homedir);
}
Err(e2) => {
crash!(
@ -86,9 +77,7 @@ pub fn init(options: Options) {
.status();
match r {
Ok(_) => {
if verbosity >= 1 {
log!("Set correct permissions for path: {}/.cache/ame", homedir);
}
tracing::debug!("Set correct permissions for path: {}/.cache/ame", homedir);
}
Err(e) => {
crash!(
@ -106,12 +95,10 @@ pub fn init(options: Options) {
.status();
match r {
Ok(_) => {
if verbosity >= 1 {
log!(
"Set correct permissions for path: {}/.local/share/ame",
homedir
);
}
tracing::debug!(
"Set correct permissions for path: {}/.local/share/ame",
homedir
);
}
Err(e) => {
crash!(

@ -45,11 +45,6 @@ pub fn uwu_enabled() -> bool {
config.extra.uwu.unwrap_or(false)
}
pub fn uwu_debug_enabled() -> bool {
let config = config::read();
config.extra.uwu_debug.unwrap_or(false)
}
/// Checks if we're running in a tty. If we do we can assume that
/// the output can safely be colorized.
pub fn is_tty() -> bool {

@ -1,7 +1,7 @@
use std::process::{Command, Stdio};
use crate::internal::{clean, rpc, structs};
use crate::{log, Options};
use crate::Options;
use super::error::SilentUnwrap;
use super::exit_code::AppExitCode;
@ -11,13 +11,10 @@ pub async fn sort(input: &[String], options: Options) -> structs::Sorted {
let mut repo_packages: Vec<String> = vec![];
let mut aur_packages: Vec<String> = vec![];
let mut missing_packages: Vec<String> = vec![];
let verbosity = options.verbosity;
let packages = clean(input, options);
let packages = clean(input);
if verbosity >= 1 {
log!("Sorting: {:?}", packages.join(" "));
}
tracing::debug!("Sorting: {:?}", packages.join(" "));
for package in packages {
let rs = Command::new("pacman")
@ -28,23 +25,17 @@ pub async fn sort(input: &[String], options: Options) -> structs::Sorted {
.expect("Something has gone wrong");
if let Some(0) = rs.code() {
if verbosity >= 1 {
log!("{} found in repos", package);
}
tracing::debug!("{} found in repos", package);
repo_packages.push(package.to_string());
} else if rpc::rpcinfo(&package)
.await
.silent_unwrap(AppExitCode::RpcError)
.is_some()
{
if verbosity >= 1 {
log!("{} found in AUR", package);
}
tracing::debug!("{} found in AUR", package);
aur_packages.push(package.to_string());
} else {
if verbosity >= 1 {
log!("{} not found", package);
}
tracing::debug!("{} not found", package);
missing_packages.push(package.to_string());
}
}

@ -18,7 +18,6 @@ impl Sorted {
#[derive(Clone, Debug, Copy)]
/// Options to be passed down to internal functions
pub struct Options {
pub verbosity: usize,
pub noconfirm: bool,
pub asdeps: bool,
}

@ -2,6 +2,8 @@ use std::time::Duration;
use crate::ShellCommand;
use super::error::AppResult;
/// Loop sudo so it doesn't time out
#[tracing::instrument(level = "trace")]
pub async fn start_sudoloop() {
@ -16,5 +18,10 @@ pub async fn start_sudoloop() {
#[tracing::instrument(level = "trace")]
async fn prompt_sudo() {
while ShellCommand::sudo().arg("-v").wait_success().await.is_err() {}
while prompt_sudo_single().await.is_err() {}
}
#[tracing::instrument(level = "trace")]
pub async fn prompt_sudo_single() -> AppResult<()> {
ShellCommand::sudo().arg("-v").wait_success().await
}

@ -1,36 +1,8 @@
use colored::Colorize;
use std::io;
use std::io::Write;
use std::process::exit;
use std::time::UNIX_EPOCH;
use textwrap::wrap;
use crate::internal::exit_code::AppExitCode;
use crate::{internal, uwu};
const OK_SYMBOL: &str = "❖";
const ERR_SYMBOL: &str = "X";
const WARN_SYMBOL: &str = "!";
const PROMPT_SYMBOL: &str = "?";
const PROMPT_YN_DEFAULT_TRUE: &str = "[Y/n]";
const PROMPT_YN_DEFAULT_FALSE: &str = "[y/N]";
#[macro_export]
/// Macro for printing a message to stdout.
macro_rules! info {
($($arg:tt)+) => {
$crate::internal::utils::log_info(format!($($arg)+))
}
}
#[macro_export]
/// Macro for printing a warning message non-destructively.
macro_rules! warn {
($($arg:tt)+) => {
$crate::internal::utils::log_warn(format!($($arg)+))
}
}
use crate::logging::get_logger;
use crate::logging::handler::PromptDefault;
#[macro_export]
/// Macro for printing a message and destructively exiting
@ -40,179 +12,27 @@ macro_rules! crash {
}
}
#[macro_export]
/// Macro for logging to stderr
macro_rules! log {
($($arg:tt)+) => {
$crate::internal::utils::log_debug(format!($($arg)+))
}
}
#[macro_export]
/// Macro for prompting the user with a yes/no question.
macro_rules! prompt {
(default $default:expr, $($arg:tt)+) => {
$crate::internal::utils::prompt_yn(format!($($arg)+), $default)
}
}
#[macro_export]
/// Macro for creating a spinner.
macro_rules! spinner {
($($arg:tt)+) => {
$crate::internal::utils::spinner_fn(format!($($arg)+))
}
}
/// Print a formatted message to stdout.
pub fn log_info(msg: String) {
let msg = if internal::uwu_enabled() {
uwu!(&msg)
} else {
msg
(default yes, $($arg:tt)+) => {
$crate::internal::utils::prompt_yn(format!($($arg)+), $crate::logging::handler::PromptDefault::Yes)
};
let opts = textwrap::Options::new(crossterm::terminal::size().unwrap().0 as usize - 2)
.subsequent_indent(" ");
println!(
"{} {}",
OK_SYMBOL.purple(),
wrap(&msg, opts).join("\n").bold()
);
}
/// Print a non-destructive warning message
pub fn log_warn(msg: String) {
let msg = if internal::uwu_enabled() {
uwu!(&msg)
} else {
msg
(default no, $($arg:tt)+) => {
$crate::internal::utils::prompt_yn(format!($($arg)+), $crate::logging::handler::PromptDefault::No)
};
let opts = textwrap::Options::new(crossterm::terminal::size().unwrap().0 as usize - 2)
.subsequent_indent(" ");
println!(
"{} {}",
WARN_SYMBOL.yellow(),
wrap(&msg, opts).join("\n").yellow().bold()
);
(no default, $($arg:tt)+) => {
$crate::internal::utils::prompt_yn(format!($($arg)+), $crate::logging::handler::PromptDefault::None)
}
}
/// Logs a message and exits the program with the given exit code.
pub fn log_and_crash(msg: String, exit_code: AppExitCode) -> ! {
let msg = if internal::uwu_enabled() {
uwu!(&msg)
} else {
msg
};
let opts = textwrap::Options::new(crossterm::terminal::size().unwrap().0 as usize - 2)
.subsequent_indent(" ");
println!(
"{} {}",
ERR_SYMBOL.red().bold(),
wrap(&msg, opts).join("\n").red().bold()
);
tracing::error!(msg);
exit(exit_code as i32);
}
/// Logs a message to stderr with timestamp
pub fn log_debug(msg: String) {
let msg = if internal::uwu_enabled() && internal::uwu_debug_enabled() {
uwu!(&msg)
} else {
msg
};
eprintln!(
"{} {}",
std::time::SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs(),
msg
);
}
/// Prompts the user for a yes/no answer.
pub fn prompt_yn(question: String, default_true: bool) -> bool {
let yn_prompt = if default_true {
PROMPT_YN_DEFAULT_TRUE
} else {
PROMPT_YN_DEFAULT_FALSE
};
let question = if internal::uwu_enabled() {
uwu!(&question)
} else {
question
};
let opts = textwrap::Options::new(crossterm::terminal::size().unwrap().0 as usize - 2)
.subsequent_indent(" ");
print!(
"{} {} {}: ",
PROMPT_SYMBOL.purple(),
wrap(&question, opts).join("\n").bold(),
yn_prompt
);
let mut yn: String = String::new();
io::stdout().flush().ok();
io::stdin().read_line(&mut yn).unwrap();
if yn.trim().to_lowercase() == "n" || yn.trim().to_lowercase() == "no" {
false
} else if yn.trim().to_lowercase() == "y" || yn.trim().to_lowercase() == "yes" {
true
} else {
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 opts = textwrap::Options::new(crossterm::terminal::size().unwrap().0 as usize - 2)
.subsequent_indent(" ");
let symbol = format!("{}", OK_SYMBOL.purple());
let text = format!("{}", wrap(&text, opts).join("\n").bold());
self.spinner.stop_and_persist(&symbol, &text);
}
}
/// Returns a spinner that can be used to display progress.
pub fn spinner_fn(text: String) -> Spinner {
let text = if internal::uwu_enabled() {
uwu!(&text)
} else {
text
};
let opts = textwrap::Options::new(crossterm::terminal::size().unwrap().0 as usize - 2)
.subsequent_indent(" ");
Spinner {
spinner: spinoff::Spinner::new(
spinoff::Spinners::Line,
format!("{}", wrap(&text, opts).join("\n").bold()),
spinoff::Color::Magenta,
),
}
pub fn prompt_yn(question: String, prompt_default: PromptDefault) -> bool {
get_logger().prompt(question, prompt_default)
}

@ -0,0 +1,146 @@
use colored::Colorize;
use std::collections::HashMap;
use std::sync::Arc;
use tracing_subscriber::registry::LookupSpan;
use tracing::field::Visit;
use tracing::{span, Level, Metadata, Subscriber};
use tracing_subscriber::Layer;
use super::handler::LogHandler;
use super::Verbosity;
const ENABLED_MODULES: &[&str] = &["ame"];
pub struct AmeFormatLayer {
logger: Arc<LogHandler>,
}
impl AmeFormatLayer {
pub fn new(logger: Arc<LogHandler>) -> Self {
Self { logger }
}
fn is_level_loggable(&self, level: &Level) -> bool {
self.logger.is_loggable(Verbosity::from_level(level))
}
fn is_enabled(&self, metadata: &Metadata) -> bool {
let level = metadata.level();
if !self.is_level_loggable(level) {
false
} else if let Some(module_path) = metadata.module_path() {
ENABLED_MODULES.iter().any(|m| module_path.starts_with(m))
} else {
false
}
}
fn log(&self, msg: String, level: &Level) {
match Verbosity::from_level(level) {
Verbosity::Error => self.logger.log_error(msg),
Verbosity::Warning => self.logger.log_warning(msg),
Verbosity::Info => self.logger.log_info(msg),
Verbosity::Debug => self.logger.log_debug(msg),
Verbosity::Trace => self.logger.log_trace(msg),
}
}
}
impl<S: Subscriber + for<'a> LookupSpan<'a>> Layer<S> for AmeFormatLayer {
/// When entering a span
fn on_new_span(
&self,
attrs: &span::Attributes<'_>,
_id: &span::Id,
_ctx: tracing_subscriber::layer::Context<'_, S>,
) {
let metadata = attrs.metadata();
if self.is_enabled(metadata) {
let mut visitor = ValueDebugStorage::default();
attrs.record(&mut visitor);
let fields: Vec<String> = visitor
.values
.into_iter()
.map(|(k, v)| format!("{k} = {v}"))
.collect();
let mut fields_str = fields.join("\n ");
if !fields_str.is_empty() {
fields_str = format!("\n {fields_str}");
}
if let Some(module) = metadata.module_path() {
self.log(
format!(
"{} {}::{} {}",
"ENTER".italic(),
module,
metadata.name(),
fields_str.dimmed()
),
metadata.level(),
)
} else {
self.log(
format!(
"{} {} {}",
"ENTER".italic(),
metadata.name(),
fields_str.dimmed()
),
metadata.level(),
)
}
}
}
fn on_exit(&self, id: &span::Id, ctx: tracing_subscriber::layer::Context<'_, S>) {
let span = ctx.span(id).unwrap();
let metadata = span.metadata();
if self.is_enabled(metadata) {
if let Some(module) = metadata.module_path() {
self.log(
format!("{} {}::{}", "EXIT".italic(), module, metadata.name(),),
metadata.level(),
);
} else {
self.log(
format!("{} {}", "EXIT".italic(), metadata.name()),
metadata.level(),
);
}
}
}
fn on_event(
&self,
event: &tracing::Event<'_>,
_ctx: tracing_subscriber::layer::Context<'_, S>,
) {
let metadata = event.metadata();
if self.is_enabled(metadata) {
let mut visitor = ValueDebugStorage::default();
event.record(&mut visitor);
let mut values = visitor.values;
if let Some(msg) = values.remove("message") {
self.log(msg, metadata.level())
}
}
}
}
#[derive(Default)]
pub struct ValueDebugStorage {
pub values: HashMap<String, String>,
}
impl Visit for ValueDebugStorage {
fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug) {
self.values
.insert(field.name().to_string(), format!("{:?}", value));
}
}

@ -0,0 +1,177 @@
use colored::Colorize;
use indicatif::{MultiProgress, ProgressBar};
use std::{
sync::{atomic::AtomicBool, Arc},
time::Duration,
};
use crate::uwu;
use dialoguer::Confirm;
use super::Verbosity;
use parking_lot::RwLock;
const OK_SYMBOL: &str = "❖";
const ERR_SYMBOL: &str = "X";
const WARN_SYMBOL: &str = "!";
const DEBUG_SYMBOL: &str = "⌘";
const TRACE_SYMBOL: &str = "🗲";
const PROMPT_SYMBOL: &str = "?";
pub struct LogHandler {
level: Arc<RwLock<Verbosity>>,
output_type: Arc<RwLock<OutputType>>,
uwu_enabled: Arc<AtomicBool>,
}
impl Default for LogHandler {
fn default() -> Self {
Self {
level: Arc::new(RwLock::new(Verbosity::Info)),
output_type: Arc::new(RwLock::new(OutputType::Stderr)),
uwu_enabled: Arc::new(AtomicBool::new(false)),
}
}
}
#[allow(unused)]
pub enum OutputType {
Stdout,
Stderr,
MultiProgress(Arc<MultiProgress>),
Progress(Arc<ProgressBar>),
}
#[allow(unused)]
pub enum PromptDefault {
Yes,
No,
None,
}
impl LogHandler {
pub fn log_error(&self, msg: String) {
if self.is_loggable(Verbosity::Error) {
let msg = self.preformat_msg(msg);
let msg = format!("{} {}", ERR_SYMBOL.red().bold(), msg.bold().red());
self.log(msg);
}
}
pub fn log_warning(&self, msg: String) {
if self.is_loggable(Verbosity::Warning) {
let msg = self.preformat_msg(msg);
let msg = format!("{} {}", WARN_SYMBOL.yellow(), msg.yellow().bold());
self.log(msg);
}
}
pub fn log_info(&self, msg: String) {
if self.is_loggable(Verbosity::Info) {
let msg = self.preformat_msg(msg);
let msg = format!("{} {}", OK_SYMBOL.purple(), msg.bold());
self.log(msg);
}
}
pub fn log_debug(&self, msg: String) {
if self.is_loggable(Verbosity::Debug) {
let msg = self.preformat_msg(msg);
let msg = format!("{} {}", DEBUG_SYMBOL.blue(), msg);
self.log(msg);
}
}
pub fn log_trace(&self, msg: String) {
if self.is_loggable(Verbosity::Trace) {
let msg = self.preformat_msg(msg);
let msg = format!("{} {}", TRACE_SYMBOL.cyan(), msg.dimmed());
self.log(msg);
}
}
/// Prompts the user with a question and a default selection
pub fn prompt(&self, question: String, p_default: PromptDefault) -> bool {
let question = self.preformat_msg(question);
let question = format!("{} {}", PROMPT_SYMBOL.purple(), question.bold());
let mut confirm = Confirm::new();
confirm.with_prompt(question);
match p_default {
PromptDefault::Yes => {
confirm.default(true);
}
PromptDefault::No => {
confirm.default(false);
}
PromptDefault::None => {}
}
confirm.interact().unwrap()
}
pub fn set_verbosity(&self, level: Verbosity) {
(*self.level.write()) = level;
}
pub fn reset_output_type(&self) {
self.set_output_type(OutputType::Stdout);
}
/// Creates a new progress spinner and registers it on the log handler
pub fn new_progress_spinner(&self) -> Arc<ProgressBar> {
let progress_bar = ProgressBar::new_spinner().with_message("Scanning for pacnew files");
progress_bar.enable_steady_tick(Duration::from_millis(250));
let pb = Arc::new(progress_bar);
self.set_progress_bar(pb.clone());
pb
}
/// Registeres a progress bar on the log handler
pub fn set_progress_bar(&self, pb: Arc<ProgressBar>) {
self.set_output_type(OutputType::Progress(pb))
}
/// Sets the output type of the log handler to either stdout/stderr or a progress bar
pub fn set_output_type(&self, output: OutputType) {
(*self.output_type.write()) = output;
}
pub fn set_uwu_enabled(&self, enabled: bool) {
self.uwu_enabled
.store(enabled, std::sync::atomic::Ordering::Relaxed);
}
pub(crate) fn is_loggable(&self, level: Verbosity) -> bool {
(*self.level.read()) >= level
}
fn preformat_msg(&self, msg: String) -> String {
let msg = self.apply_uwu(msg);
let opts = textwrap::Options::new(crossterm::terminal::size().unwrap().0 as usize - 2)
.subsequent_indent(" ");
textwrap::wrap(&msg, opts).join("\n")
}
fn apply_uwu(&self, msg: String) -> String {
if self.uwu_enabled.load(std::sync::atomic::Ordering::Relaxed) {
uwu!(msg)
} else {
msg
}
}
fn log(&self, msg: String) {
let output_type = self.output_type.read();
match &*output_type {
OutputType::Stdout => println!("{}", msg),
OutputType::Stderr => eprintln!("{}", msg),
OutputType::MultiProgress(m) => {
let _ = m.println(msg);
}
OutputType::Progress(p) => p.println(msg),
};
}
}

@ -0,0 +1,69 @@
use std::sync::Arc;
use lazy_static::lazy_static;
use tracing::Level;
use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
use tracing_subscriber::Registry;
mod fmt_layer;
use fmt_layer::AmeFormatLayer;
use crate::internal::uwu_enabled;
use self::handler::LogHandler;
pub mod handler;
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Verbosity {
#[allow(dead_code)]
Error = 0,
#[allow(dead_code)]
Warning = 1,
Info = 2,
Debug = 3,
Trace = 4,
}
impl From<usize> for Verbosity {
fn from(num_verbosity: usize) -> Self {
match num_verbosity {
0 => Self::Info,
1 => Self::Debug,
2 => Self::Trace,
_ => Self::Info,
}
}
}
impl Verbosity {
fn from_level(l: &Level) -> Self {
match *l {
Level::ERROR => Self::Error,
Level::WARN => Self::Warning,
Level::INFO => Self::Info,
Level::DEBUG => Self::Debug,
Level::TRACE => Self::Trace,
}
}
}
/// Initializes the tracing logger
/// Can be used for debug purposes _or_ verbose output
pub fn init_logger(verbosity: Verbosity) {
let logger = get_logger();
logger.set_verbosity(verbosity);
logger.set_uwu_enabled(uwu_enabled());
let ame_layer = AmeFormatLayer::new(logger);
let subscriber = Registry::default().with(ame_layer);
tracing::subscriber::set_global_default(subscriber).unwrap();
}
/// Returns the global logger instance
pub fn get_logger() -> Arc<LogHandler> {
lazy_static! {
static ref LOGGER: Arc<LogHandler> = Arc::new(LogHandler::default());
}
Arc::clone(&LOGGER)
}

@ -10,34 +10,32 @@ use crate::internal::exit_code::AppExitCode;
use crate::internal::{init, sort, start_sudoloop, structs::Options};
use clap_complete::{Generator, Shell};
use std::str::FromStr;
use tracing_subscriber::fmt::format::FmtSpan;
use tracing_subscriber::EnvFilter;
mod args;
mod builder;
mod internal;
mod logging;
mod operations;
use logging::init_logger;
#[tokio::main(flavor = "current_thread")]
#[tokio::main]
async fn main() {
color_eyre::install().unwrap();
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");
}
init_logger();
let args: Args = Args::parse();
init_logger(args.verbose.into());
let verbosity = args.verbose;
let noconfirm = args.no_confirm;
let options = Options {
verbosity,
noconfirm,
asdeps: false,
};
init(options);
init();
if args.sudoloop {
start_sudoloop().await;
@ -49,11 +47,11 @@ async fn main() {
Operation::Search(search_args) => cmd_search(search_args, options).await,
Operation::Query(query_args) => cmd_query(query_args).await,
Operation::Upgrade(upgrade_args) => {
info!("Performing system upgrade");
tracing::info!("Performing system upgrade");
operations::upgrade(upgrade_args, options).await;
}
Operation::Clean => {
info!("Removing orphaned packages");
tracing::info!("Removing orphaned packages");
operations::clean(options).await;
}
Operation::Info(info_args) => cmd_info(info_args).await,
@ -64,21 +62,6 @@ async fn main() {
detect().await;
}
/// Initializes the tracing logger
/// Can be used for debug purposes _or_ verbose output
fn init_logger() {
const DEFAULT_ENV_FILTER: &str = "warn";
let filter_string = std::env::var("AME_LOG").unwrap_or_else(|_| DEFAULT_ENV_FILTER.to_string());
let env_filter =
EnvFilter::from_str(&*filter_string).expect("failed to parse env filter string");
tracing_subscriber::fmt::SubscriberBuilder::default()
.with_env_filter(env_filter)
.with_writer(std::io::stdout)
.with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
.compact()
.init();
}
#[tracing::instrument(level = "trace")]
async fn cmd_install(args: InstallArgs, options: Options) {
let packages = args.packages;
@ -113,14 +96,14 @@ async fn cmd_install(args: InstallArgs, options: Options) {
.split_whitespace()
.collect::<Vec<&str>>()
.join(", ");
info!("You have .pacnew files in /etc ({pacnew_files}) that you haven't removed or acted upon, it is recommended you do that now" );
tracing::info!("You have .pacnew files in /etc ({pacnew_files}) that you haven't removed or acted upon, it is recommended you do that now" );
}
}
#[tracing::instrument(level = "trace")]
async fn cmd_remove(args: RemoveArgs, options: Options) {
let packages = args.packages;
info!("Uninstalling packages: {}", &packages.join(", "));
tracing::info!("Uninstalling packages: {}", &packages.join(", "));
operations::uninstall(packages, options).await;
}
@ -129,16 +112,16 @@ async fn cmd_search(args: SearchArgs, options: Options) {
let query_string = args.search;
if args.aur {
info!("Searching AUR for {}", &query_string);
tracing::info!("Searching AUR for {}", &query_string);
operations::aur_search(&query_string, args.by, options).await;
}
if args.repo {
info!("Searching repos for {}", &query_string);
tracing::info!("Searching repos for {}", &query_string);
operations::search(&query_string, options).await;
}
if !args.aur && !args.repo {
info!("Searching AUR and repos for {}", &query_string);
tracing::info!("Searching AUR and repos for {}", &query_string);
operations::search(&query_string, options).await;
operations::aur_search(&query_string, args.by, options).await;
}

@ -9,7 +9,7 @@ use crate::internal::commands::ShellCommand;
use crate::internal::error::SilentUnwrap;
use crate::internal::exit_code::AppExitCode;
use crate::internal::rpc::rpcinfo;
use crate::{crash, info, internal::fs_utils::rmdir_recursive, log, prompt, Options};
use crate::{crash, internal::fs_utils::rmdir_recursive, prompt, Options};
/// Installs a given list of packages from the aur
#[tracing::instrument(level = "trace")]
@ -17,14 +17,11 @@ use crate::{crash, info, internal::fs_utils::rmdir_recursive, log, prompt, Optio
pub async fn aur_install(packages: Vec<String>, options: Options) {
let url = crate::internal::rpc::URL;
let cachedir = format!("{}/.cache/ame/", env::var("HOME").unwrap());
let verbosity = options.verbosity;
let noconfirm = options.noconfirm;
if verbosity >= 1 {
log!("Installing from AUR: {:?}", &packages);
}
tracing::debug!("Installing from AUR: {:?}", &packages);
info!("Installing packages {} from the AUR", packages.join(", "));
tracing::info!("Installing packages {} from the AUR", packages.join(", "));
for package_name in packages {
let rpcres = rpcinfo(&package_name)
@ -38,11 +35,9 @@ pub async fn aur_install(packages: Vec<String>, options: Options) {
let package = rpcres.unwrap();
let pkg_name = package.metadata.name;
if verbosity >= 1 {
log!("Cloning {} into cachedir", pkg_name);
}
tracing::debug!("Cloning {} into cachedir", pkg_name);
info!("Cloning package source");
tracing::info!("Cloning package source");
set_current_dir(Path::new(&cachedir)).unwrap();
ShellCommand::git()
@ -52,36 +47,31 @@ pub async fn aur_install(packages: Vec<String>, options: Options) {
.await
.silent_unwrap(AppExitCode::GitError);
if verbosity >= 1 {
log!(
"Cloned {} into cachedir, moving on to resolving dependencies",
pkg_name
);
log!(
"Raw dependencies for package {} are:\n{:?}",
pkg_name,
package.depends,
);
log!(
"Raw makedepends for package {} are:\n{:?}",
pkg_name,
package.make_depends.join(", "),
);
}
tracing::debug!(
"Cloned {} into cachedir, moving on to resolving dependencies",
pkg_name
);
tracing::debug!(
"Raw dependencies for package {} are:\n{:?}",
pkg_name,
package.depends,
);
tracing::debug!(
"Raw makedepends for package {} are:\n{:?}",
pkg_name,
package.make_depends.join(", "),
);
// dep sorting
log!("Sorting dependencies");
tracing::debug!("Sorting dependencies");
let sorted = crate::internal::sort(&package.depends, options).await;
log!("Sorting make dependencies");
tracing::debug!("Sorting make dependencies");
let md_sorted = crate::internal::sort(&package.make_depends, options).await;
if verbosity >= 1 {
log!("Sorted dependencies for {} are:\n{:?}", pkg_name, &sorted);
log!("Sorted makedepends for {} are:\n{:?}", pkg_name, &md_sorted);
}
tracing::debug!("Sorted dependencies for {} are:\n{:?}", pkg_name, &sorted);
tracing::debug!("Sorted makedepends for {} are:\n{:?}", pkg_name, &md_sorted);
let newopts = Options {
verbosity,
noconfirm,
asdeps: true,
};
@ -96,7 +86,7 @@ pub async fn aur_install(packages: Vec<String>, options: Options) {
}
if !noconfirm {
let p1 = prompt!(default false,
let p1 = prompt!(default no,
"Would you like to review {}'s PKGBUILD (and any .install files if present)?",
pkg_name,
);
@ -126,7 +116,7 @@ pub async fn aur_install(packages: Vec<String>, options: Options) {
.silent_unwrap(AppExitCode::Other);
}
let p2 = prompt!(default true, "Would you still like to install {}?", pkg_name);
let p2 = prompt!(default yes, "Would you still like to install {}?", pkg_name);
if !p2 {
fs::remove_dir_all(format!("{}/{}", cachedir, pkg_name))
.await
@ -137,7 +127,7 @@ pub async fn aur_install(packages: Vec<String>, options: Options) {
}
// dep installing
info!("Moving on to install dependencies");
tracing::info!("Moving on to install dependencies");
if !sorted.repo.is_empty() {
crate::operations::install(sorted.repo, newopts).await;
@ -157,7 +147,7 @@ pub async fn aur_install(packages: Vec<String>, options: Options) {
}
// package building and installing
info!("Building time!");
tracing::info!("Building time!");
set_current_dir(format!("{}/{}", cachedir, pkg_name)).unwrap();
let status = ShellCommand::makepkg()
.args(makepkg_args)

@ -1,18 +1,15 @@
use tokio::process::Command;
use crate::crash;
use crate::info;
use crate::internal::commands::ShellCommand;
use crate::internal::error::SilentUnwrap;
use crate::internal::exit_code::AppExitCode;
use crate::log;
use crate::prompt;
use crate::Options;
/// Removes orphaned packages and cache
#[tracing::instrument(level = "trace")]
pub async fn clean(options: Options) {
let verbosity = options.verbosity;
let noconfirm = options.noconfirm;
// Check for orphaned packages
@ -24,17 +21,17 @@ pub async fn clean(options: Options) {
if orphaned_packages.stdout.as_str().is_empty() {
// If no orphaned packages found, do nothing
info!("No orphaned packages found");
tracing::info!("No orphaned packages found");
} else {
// Prompt users whether to remove orphaned packages
info!(
tracing::info!(
"Removing orphans would uninstall the following packages: \n{}",
&orphaned_packages.stdout
);
let cont = prompt!(default false, "Continue?");
let cont = prompt!(default no, "Continue?");
if !cont {
// If user doesn't want to continue, break
info!("Exiting");
tracing::info!("Exiting");
std::process::exit(AppExitCode::PacmanError as i32);
}
@ -52,9 +49,7 @@ pub async fn clean(options: Options) {
}
}
if verbosity >= 1 {
log!("Removing orphans: {:?}", orphaned_packages_vec);
}
tracing::debug!("Removing orphans: {:?}", orphaned_packages_vec);
// Remove orphaned packages
let pacman_result = ShellCommand::pacman()
@ -66,7 +61,7 @@ pub async fn clean(options: Options) {
if pacman_result.success() {
// If pacman succeeded, notify user
info!("Successfully removed orphans");
tracing::info!("Successfully removed orphans");
} else {
// If pacman failed, crash
crash!(AppExitCode::PacmanError, "Failed to remove orphans",);
@ -74,7 +69,7 @@ pub async fn clean(options: Options) {
}
// Prompt the user whether to clear the Amethyst cache
let clear_ame_cache = prompt!(default false, "Clear Amethyst's internal PKGBUILD cache?");
let clear_ame_cache = prompt!(default no, "Clear Amethyst's internal PKGBUILD cache?");
if clear_ame_cache {
// Remove ~/.cache/ame
Command::new("rm")
@ -91,7 +86,7 @@ pub async fn clean(options: Options) {
let clear_pacman_cache = if noconfirm {
true
} else {
prompt!(default false, "Also clear pacman's package cache?")
prompt!(default no, "Also clear pacman's package cache?")
};
if clear_pacman_cache {
@ -107,9 +102,7 @@ pub async fn clean(options: Options) {
paccache_args.push("--noconfirm");
}
if verbosity >= 1 {
log!("Clearing using `paccache -r`");
}
tracing::debug!("Clearing using `paccache -r`");
// Clear pacman's cache (keeping latest 3 versions of installed packages)
Command::new("sudo")
@ -127,9 +120,7 @@ pub async fn clean(options: Options) {
.await
.unwrap();
if verbosity >= 1 {
log!("Clearing using `pacman -Sc`");
}
tracing::debug!("Clearing using `pacman -Sc`");
// Clear pacman's cache (keeping only installed packages)
let pacman_result = ShellCommand::pacman()
@ -141,7 +132,7 @@ pub async fn clean(options: Options) {
if pacman_result.success() {
// If pacman succeeded, notify user
info!("Successfully cleared package cache");
tracing::info!("Successfully cleared package cache");
} else {
// If pacman failed, crash
crash!(AppExitCode::PacmanError, "Failed to clear package cache",);

@ -1,16 +1,13 @@
use crate::builder::pacman::PacmanInstallBuilder;
use crate::internal::exit_code::AppExitCode;
use crate::{crash, info, log, Options};
use crate::{crash, Options};
#[tracing::instrument(level = "trace")]
pub async fn install(packages: Vec<String>, options: Options) {
info!("Installing packages {} from repos", &packages.join(", "));
let verbosity = options.verbosity;
tracing::info!("Installing packages {} from repos", &packages.join(", "));
if !packages.is_empty() {
if verbosity >= 1 {
log!("Installing from repos: {:?}", &packages);
}
tracing::debug!("Installing from repos: {:?}", &packages);
let result = PacmanInstallBuilder::from_options(options)
.packages(packages.clone())
@ -25,8 +22,6 @@ pub async fn install(packages: Vec<String>, options: Options) {
);
}
if verbosity >= 1 {
log!("Installing packages: {:?} was successful", &packages);
}
tracing::debug!("Installing packages: {:?} was successful", &packages);
}
}

@ -4,12 +4,11 @@ use crate::internal::commands::ShellCommand;
use crate::internal::error::SilentUnwrap;
use crate::internal::exit_code::AppExitCode;
use crate::internal::rpc::rpcsearch;
use crate::{log, Options};
use crate::Options;
use aur_rpc::SearchField;
#[tracing::instrument(level = "trace")]
pub async fn aur_search(query: &str, by_field: Option<SearchBy>, options: Options) {
let verbosity = options.verbosity;
let packages = rpcsearch(query.to_string(), by_field.map(SearchBy::into))
.await
.silent_unwrap(AppExitCode::RpcError);
@ -22,14 +21,11 @@ pub async fn aur_search(query: &str, by_field: Option<SearchBy>, options: Option
)
}
if verbosity >= 1 {
log!("Found {total_results} resuls for \"{query}\" in AUR",);
}
tracing::debug!("Found {total_results} resuls for \"{query}\" in AUR",);
}
#[tracing::instrument(level = "trace")]
pub async fn repo_search(query: &str, options: Options) {
let verbosity = options.verbosity;
let output = ShellCommand::pacman()
.arg("-Ss")
.arg(query)
@ -38,13 +34,11 @@ pub async fn repo_search(query: &str, options: Options) {
.silent_unwrap(AppExitCode::PacmanError)
.stdout;
if verbosity >= 1 {
log!(
"Found {} results for \"{}\" in repos",
&output.split('\n').count() / 2,
&query
);
}
tracing::debug!(
"Found {} results for \"{}\" in repos",
&output.split('\n').count() / 2,
&query
);
println!("{}", output)
}

@ -5,7 +5,7 @@ use tokio::fs;
use crate::internal::commands::ShellCommand;
use crate::internal::error::SilentUnwrap;
use crate::internal::exit_code::AppExitCode;
use crate::{log, Options};
use crate::Options;
#[tracing::instrument(level = "trace")]
pub async fn uninstall(packages: Vec<String>, options: Options) {
@ -15,10 +15,7 @@ pub async fn uninstall(packages: Vec<String>, options: Options) {
if options.noconfirm {
pacman_args.push("--noconfirm");
}
let verbosity = options.verbosity;
if verbosity >= 1 {
log!("Uninstalling: {:?}", &packages);
}
tracing::debug!("Uninstalling: {:?}", &packages);
ShellCommand::pacman()
.elevated()
@ -27,9 +24,7 @@ pub async fn uninstall(packages: Vec<String>, options: Options) {
.await
.silent_unwrap(AppExitCode::PacmanError);
if verbosity >= 1 {
log!("Uninstalling packages: {:?} exited with code 0", &packages);
}
tracing::debug!("Uninstalling packages: {:?} exited with code 0", &packages);
for package in packages {
if Path::new(&format!(
@ -39,9 +34,7 @@ pub async fn uninstall(packages: Vec<String>, options: Options) {
))
.exists()
{
if verbosity >= 1 {
log!("Old cache directory found, deleting");
}
tracing::debug!("Old cache directory found, deleting");
fs::remove_dir_all(Path::new(&format!(
"{}/.cache/ame/{}",
env::var("HOME").unwrap(),

@ -5,7 +5,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, warn, Options};
use crate::{prompt, Options};
/// Upgrades all installed packages
#[tracing::instrument(level = "trace")]
@ -16,11 +16,14 @@ pub async fn upgrade(args: UpgradeArgs, options: Options) {
if args.aur {
upgrade_aur(options).await;
}
if !args.aur && !args.repo {
upgrade_repo(options).await;
upgrade_aur(options).await;
}
}
#[tracing::instrument(level = "trace")]
async fn upgrade_repo(options: Options) {
let verbosity = options.verbosity;
let noconfirm = options.noconfirm;
let mut pacman_args = vec!["-Syu"];
@ -28,9 +31,7 @@ async fn upgrade_repo(options: Options) {
pacman_args.push("--noconfirm");
}
if verbosity >= 1 {
log!("Upgrading repo packages");
}
tracing::debug!("Upgrading repo packages");
let pacman_result = ShellCommand::pacman()
.elevated()
@ -40,13 +41,13 @@ async fn upgrade_repo(options: Options) {
.silent_unwrap(AppExitCode::PacmanError);
if pacman_result.success() {
info!("Successfully upgraded repo packages");
tracing::info!("Successfully upgraded repo packages");
} else {
let continue_upgrading = prompt!(default false,
let continue_upgrading = prompt!(default no,
"Failed to upgrade repo packages, continue to upgrading AUR packages?",
);
if !continue_upgrading {
info!("Exiting");
tracing::info!("Exiting");
std::process::exit(AppExitCode::PacmanError as i32);
}
}
@ -54,11 +55,7 @@ async fn upgrade_repo(options: Options) {
#[tracing::instrument(level = "trace")]
async fn upgrade_aur(options: Options) {
let verbosity = options.verbosity;
if verbosity >= 1 {
log!("Upgrading AUR packages");
}
tracing::debug!("Upgrading AUR packages");
let non_native_pkgs = PacmanQueryBuilder::foreign()
.color(PacmanColor::Never)
@ -84,13 +81,13 @@ async fn upgrade_aur(options: Options) {
aur_upgrades.push(pkg.name);
}
} else {
warn!("Could not find the remote package for {}", pkg.name);
tracing::warn!("Could not find the remote package for {}", pkg.name);
}
}
if !aur_upgrades.is_empty() {
aur_install(aur_upgrades, options).await;
} else {
info!("No upgrades available for installed AUR packages");
tracing::info!("No upgrades available for installed AUR packages");
}
}

Loading…
Cancel
Save