mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-05 02:55:31 +00:00
make logger channel static
This commit is contained in:
parent
bed8ea0276
commit
28daa9e8c4
@ -4,7 +4,7 @@ use std::path::Path;
|
||||
|
||||
use unrar::Archive;
|
||||
|
||||
use crate::{error::Error, list::FileInArchive, utils::logger::Logger};
|
||||
use crate::{error::Error, list::FileInArchive, utils::logger::info};
|
||||
|
||||
/// Unpacks the archive given by `archive_path` into the folder given by `output_folder`.
|
||||
/// Assumes that output_folder is empty
|
||||
@ -18,7 +18,7 @@ pub fn unpack_archive(archive_path: &Path, output_folder: &Path, quiet: bool) ->
|
||||
let entry = header.entry();
|
||||
archive = if entry.is_file() {
|
||||
if !quiet {
|
||||
logger.info(format!(
|
||||
info(format!(
|
||||
"{} extracted. ({})",
|
||||
entry.filename.display(),
|
||||
entry.unpacked_size
|
||||
|
@ -11,7 +11,11 @@ use same_file::Handle;
|
||||
|
||||
use crate::{
|
||||
error::FinalError,
|
||||
utils::{self, cd_into_same_dir_as, Bytes, EscapedPathDisplay, FileVisibilityPolicy},
|
||||
utils::{
|
||||
self, cd_into_same_dir_as,
|
||||
logger::{info, warning},
|
||||
Bytes, EscapedPathDisplay, FileVisibilityPolicy,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn compress_sevenz<W>(
|
||||
@ -41,7 +45,7 @@ where
|
||||
// If the output_path is the same as the input file, warn the user and skip the input (in order to avoid compression recursion)
|
||||
if let Ok(handle) = &output_handle {
|
||||
if matches!(Handle::from_path(path), Ok(x) if &x == handle) {
|
||||
logger.warning(format!(
|
||||
warning(format!(
|
||||
"The output file and the input file are the same: `{}`, skipping...",
|
||||
output_path.display()
|
||||
));
|
||||
@ -55,7 +59,7 @@ where
|
||||
// spoken text for users using screen readers, braille displays
|
||||
// and so on
|
||||
if !quiet {
|
||||
logger.info(format!("Compressing '{}'.", EscapedPathDisplay::new(path)));
|
||||
info(format!("Compressing '{}'.", EscapedPathDisplay::new(path)));
|
||||
}
|
||||
|
||||
let metadata = match path.metadata() {
|
||||
@ -108,7 +112,7 @@ where
|
||||
|
||||
if entry.is_directory() {
|
||||
if !quiet {
|
||||
logger.info(format!(
|
||||
info(format!(
|
||||
"File {} extracted to \"{}\"",
|
||||
entry.name(),
|
||||
file_path.display()
|
||||
@ -119,7 +123,7 @@ where
|
||||
}
|
||||
} else {
|
||||
if !quiet {
|
||||
logger.info(format!(
|
||||
info(format!(
|
||||
"{:?} extracted. ({})",
|
||||
file_path.display(),
|
||||
Bytes::new(entry.size())
|
||||
|
@ -14,7 +14,11 @@ use same_file::Handle;
|
||||
use crate::{
|
||||
error::FinalError,
|
||||
list::FileInArchive,
|
||||
utils::{self, Bytes, EscapedPathDisplay, FileVisibilityPolicy},
|
||||
utils::{
|
||||
self,
|
||||
logger::{info, warning},
|
||||
Bytes, EscapedPathDisplay, FileVisibilityPolicy,
|
||||
},
|
||||
};
|
||||
|
||||
/// Unpacks the archive given by `archive` into the folder given by `into`.
|
||||
@ -34,7 +38,7 @@ pub fn unpack_archive(reader: Box<dyn Read>, output_folder: &Path, quiet: bool)
|
||||
// spoken text for users using screen readers, braille displays
|
||||
// and so on
|
||||
if !quiet {
|
||||
logger.info(format!(
|
||||
info(format!(
|
||||
"{:?} extracted. ({})",
|
||||
utils::strip_cur_dir(&output_folder.join(file.path()?)),
|
||||
Bytes::new(file.size()),
|
||||
@ -104,7 +108,7 @@ where
|
||||
// If the output_path is the same as the input file, warn the user and skip the input (in order to avoid compression recursion)
|
||||
if let Ok(handle) = &output_handle {
|
||||
if matches!(Handle::from_path(path), Ok(x) if &x == handle) {
|
||||
logger.warning(format!(
|
||||
warning(format!(
|
||||
"The output file and the input file are the same: `{}`, skipping...",
|
||||
output_path.display()
|
||||
));
|
||||
@ -118,7 +122,7 @@ where
|
||||
// spoken text for users using screen readers, braille displays
|
||||
// and so on
|
||||
if !quiet {
|
||||
logger.info(format!("Compressing '{}'.", EscapedPathDisplay::new(path)));
|
||||
info(format!("Compressing '{}'.", EscapedPathDisplay::new(path)));
|
||||
}
|
||||
|
||||
if path.is_dir() {
|
||||
|
@ -20,8 +20,9 @@ use crate::{
|
||||
error::FinalError,
|
||||
list::FileInArchive,
|
||||
utils::{
|
||||
self, cd_into_same_dir_as, get_invalid_utf8_paths, pretty_format_list_of_paths, strip_cur_dir, Bytes,
|
||||
EscapedPathDisplay, FileVisibilityPolicy,
|
||||
self, cd_into_same_dir_as, get_invalid_utf8_paths,
|
||||
logger::{info, info_accessible, warning},
|
||||
pretty_format_list_of_paths, strip_cur_dir, Bytes, EscapedPathDisplay, FileVisibilityPolicy,
|
||||
},
|
||||
};
|
||||
|
||||
@ -53,7 +54,7 @@ where
|
||||
// spoken text for users using screen readers, braille displays
|
||||
// and so on
|
||||
if !quiet {
|
||||
logger.info(format!("File {} extracted to \"{}\"", idx, file_path.display()));
|
||||
info(format!("File {} extracted to \"{}\"", idx, file_path.display()));
|
||||
}
|
||||
fs::create_dir_all(&file_path)?;
|
||||
}
|
||||
@ -67,7 +68,7 @@ where
|
||||
|
||||
// same reason is in _is_dir: long, often not needed text
|
||||
if !quiet {
|
||||
logger.info(format!(
|
||||
info(format!(
|
||||
"{:?} extracted. ({})",
|
||||
file_path.display(),
|
||||
Bytes::new(file.size())
|
||||
@ -175,7 +176,7 @@ where
|
||||
// If the output_path is the same as the input file, warn the user and skip the input (in order to avoid compression recursion)
|
||||
if let Ok(handle) = &output_handle {
|
||||
if matches!(Handle::from_path(path), Ok(x) if &x == handle) {
|
||||
logger.warning(format!(
|
||||
warning(format!(
|
||||
"The output file and the input file are the same: `{}`, skipping...",
|
||||
output_path.display()
|
||||
));
|
||||
@ -187,7 +188,7 @@ where
|
||||
// spoken text for users using screen readers, braille displays
|
||||
// and so on
|
||||
if !quiet {
|
||||
logger.info(format!("Compressing '{}'.", EscapedPathDisplay::new(path)));
|
||||
info(format!("Compressing '{}'.", EscapedPathDisplay::new(path)));
|
||||
}
|
||||
|
||||
let metadata = match path.metadata() {
|
||||
|
@ -11,7 +11,10 @@ use std::{
|
||||
use crate::{
|
||||
error::FinalError,
|
||||
extension::{build_archive_file_suggestion, Extension, PRETTY_SUPPORTED_ALIASES, PRETTY_SUPPORTED_EXTENSIONS},
|
||||
utils::{pretty_format_list_of_paths, try_infer_extension, user_wants_to_continue, EscapedPathDisplay},
|
||||
utils::{
|
||||
logger::{info_accessible, warning},
|
||||
pretty_format_list_of_paths, try_infer_extension, user_wants_to_continue, EscapedPathDisplay,
|
||||
},
|
||||
QuestionAction, QuestionPolicy, Result,
|
||||
};
|
||||
|
||||
@ -53,7 +56,7 @@ pub fn check_mime_type(
|
||||
.compression_formats
|
||||
.ends_with(detected_format.compression_formats)
|
||||
{
|
||||
logger.warning(format!(
|
||||
warning(format!(
|
||||
"The file extension: `{}` differ from the detected extension: `{}`",
|
||||
outer_ext, detected_format
|
||||
));
|
||||
|
@ -104,7 +104,7 @@ pub fn compress_files(
|
||||
}
|
||||
Zip => {
|
||||
if !formats.is_empty() {
|
||||
warn_user_about_loading_zip_in_memory(logger.clone());
|
||||
warn_user_about_loading_zip_in_memory();
|
||||
|
||||
if !user_wants_to_continue(output_path, question_policy, QuestionAction::Compression)? {
|
||||
return Ok(false);
|
||||
@ -132,7 +132,7 @@ pub fn compress_files(
|
||||
}
|
||||
SevenZip => {
|
||||
if !formats.is_empty() {
|
||||
warn_user_about_loading_sevenz_in_memory(logger.clone());
|
||||
warn_user_about_loading_sevenz_in_memory();
|
||||
|
||||
if !user_wants_to_continue(output_path, question_policy, QuestionAction::Compression)? {
|
||||
return Ok(false);
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
CompressionFormat::{self, *},
|
||||
Extension,
|
||||
},
|
||||
utils::{self, nice_directory_display, user_wants_to_continue},
|
||||
utils::{self, logger::info_accessible, nice_directory_display, user_wants_to_continue},
|
||||
QuestionAction, QuestionPolicy, BUFFER_CAPACITY,
|
||||
};
|
||||
|
||||
@ -122,7 +122,7 @@ pub fn decompress_file(
|
||||
}
|
||||
Zip => {
|
||||
if formats.len() > 1 {
|
||||
warn_user_about_loading_zip_in_memory(logger.clone());
|
||||
warn_user_about_loading_zip_in_memory();
|
||||
|
||||
if !user_wants_to_continue(input_file_path, question_policy, QuestionAction::Decompression)? {
|
||||
return Ok(());
|
||||
@ -150,10 +150,7 @@ pub fn decompress_file(
|
||||
let unpack_fn: Box<dyn FnOnce(&Path) -> UnpackResult> = if formats.len() > 1 {
|
||||
let mut temp_file = tempfile::NamedTempFile::new()?;
|
||||
io::copy(&mut reader, &mut temp_file)?;
|
||||
let logger_clone = logger.clone();
|
||||
Box::new(move |output_dir| {
|
||||
crate::archive::rar::unpack_archive(temp_file.path(), output_dir, quiet, logger_clone)
|
||||
})
|
||||
Box::new(move |output_dir| crate::archive::rar::unpack_archive(temp_file.path(), output_dir, quiet))
|
||||
} else {
|
||||
Box::new(|output_dir| crate::archive::rar::unpack_archive(input_file_path, output_dir, quiet))
|
||||
};
|
||||
@ -172,7 +169,7 @@ pub fn decompress_file(
|
||||
}
|
||||
SevenZip => {
|
||||
if formats.len() > 1 {
|
||||
warn_user_about_loading_sevenz_in_memory(logger.clone());
|
||||
warn_user_about_loading_sevenz_in_memory();
|
||||
|
||||
if !user_wants_to_continue(input_file_path, question_policy, QuestionAction::Decompression)? {
|
||||
return Ok(());
|
||||
|
@ -65,7 +65,7 @@ pub fn list_archive_contents(
|
||||
Tar => Box::new(crate::archive::tar::list_archive(tar::Archive::new(reader))),
|
||||
Zip => {
|
||||
if formats.len() > 1 {
|
||||
warn_user_about_loading_zip_in_memory(logger.clone());
|
||||
warn_user_about_loading_zip_in_memory();
|
||||
|
||||
if !user_wants_to_continue(archive_path, question_policy, QuestionAction::Decompression)? {
|
||||
return Ok(());
|
||||
@ -94,7 +94,7 @@ pub fn list_archive_contents(
|
||||
}
|
||||
SevenZip => {
|
||||
if formats.len() > 1 {
|
||||
warn_user_about_loading_zip_in_memory(logger.clone());
|
||||
warn_user_about_loading_zip_in_memory();
|
||||
if !user_wants_to_continue(archive_path, question_policy, QuestionAction::Decompression)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ mod list;
|
||||
use std::{
|
||||
ops::ControlFlow,
|
||||
path::PathBuf,
|
||||
sync::{mpsc, Arc, Condvar, Mutex, OnceLock},
|
||||
sync::{Arc, Condvar, Mutex},
|
||||
};
|
||||
|
||||
use rayon::prelude::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
||||
@ -22,30 +22,30 @@ use crate::{
|
||||
list::ListOptions,
|
||||
utils::{
|
||||
self,
|
||||
logger::{map_message, setup_channel, PrintMessage},
|
||||
logger::{info_accessible, map_message, setup_channel, warning},
|
||||
to_utf, EscapedPathDisplay, FileVisibilityPolicy,
|
||||
},
|
||||
CliArgs, QuestionPolicy,
|
||||
};
|
||||
|
||||
/// Warn the user that (de)compressing this .zip archive might freeze their system.
|
||||
fn warn_user_about_loading_zip_in_memory(logger: Logger) {
|
||||
fn warn_user_about_loading_zip_in_memory() {
|
||||
const ZIP_IN_MEMORY_LIMITATION_WARNING: &str = "\n\
|
||||
\tThe format '.zip' is limited and cannot be (de)compressed using encoding streams.\n\
|
||||
\tWhen using '.zip' with other formats, (de)compression must be done in-memory\n\
|
||||
\tCareful, you might run out of RAM if the archive is too large!";
|
||||
|
||||
logger.warning(ZIP_IN_MEMORY_LIMITATION_WARNING.to_string());
|
||||
warning(ZIP_IN_MEMORY_LIMITATION_WARNING.to_string());
|
||||
}
|
||||
|
||||
/// Warn the user that (de)compressing this .7z archive might freeze their system.
|
||||
fn warn_user_about_loading_sevenz_in_memory(logger: Logger) {
|
||||
fn warn_user_about_loading_sevenz_in_memory() {
|
||||
const SEVENZ_IN_MEMORY_LIMITATION_WARNING: &str = "\n\
|
||||
\tThe format '.7z' is limited and cannot be (de)compressed using encoding streams.\n\
|
||||
\tWhen using '.7z' with other formats, (de)compression must be done in-memory\n\
|
||||
\tCareful, you might run out of RAM if the archive is too large!";
|
||||
|
||||
logger.warning(SEVENZ_IN_MEMORY_LIMITATION_WARNING.to_string());
|
||||
warning(SEVENZ_IN_MEMORY_LIMITATION_WARNING.to_string());
|
||||
}
|
||||
|
||||
/// This function checks what command needs to be run and performs A LOT of ahead-of-time checks
|
||||
@ -272,7 +272,7 @@ pub fn run(
|
||||
// Drop our sender so when all threads are done, no clones are left.
|
||||
// This is needed, otherwise the logging thread will never exit since we would be keeping a
|
||||
// sender alive here.
|
||||
drop(logger);
|
||||
todo!();
|
||||
|
||||
// Prevent the main thread from exiting until the background thread handling the
|
||||
// logging has set `flushed` to true.
|
||||
|
@ -5,7 +5,7 @@ use std::{ffi::OsStr, fmt, path::Path};
|
||||
use bstr::ByteSlice;
|
||||
|
||||
use self::CompressionFormat::*;
|
||||
use crate::{error::Error, utils::logger::Logger};
|
||||
use crate::{error::Error, utils::logger::warning};
|
||||
|
||||
pub const SUPPORTED_EXTENSIONS: &[&str] = &[
|
||||
"tar",
|
||||
@ -184,7 +184,7 @@ pub fn separate_known_extensions_from_name(path: &Path) -> (&Path, Vec<Extension
|
||||
if let Ok(name) = name.to_str() {
|
||||
let file_stem = name.trim_matches('.');
|
||||
if SUPPORTED_EXTENSIONS.contains(&file_stem) || SUPPORTED_ALIASES.contains(&file_stem) {
|
||||
logger.warning(format!(
|
||||
warning(format!(
|
||||
"Received a file with name '{file_stem}', but {file_stem} was expected as the extension."
|
||||
));
|
||||
}
|
||||
@ -251,13 +251,9 @@ pub fn build_archive_file_suggestion(path: &Path, suggested_extension: &str) ->
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::utils::logger::PrintMessage;
|
||||
|
||||
#[test]
|
||||
fn test_extensions_from_path() {
|
||||
let (log_sender, _log_receiver) = std::sync::mpsc::channel::<PrintMessage>();
|
||||
let logger = Logger::new(log_sender);
|
||||
|
||||
let path = Path::new("bolovo.tar.gz");
|
||||
|
||||
let extensions: Vec<Extension> = extensions_from_path(path);
|
||||
|
@ -9,7 +9,11 @@ use std::{
|
||||
use fs_err as fs;
|
||||
|
||||
use super::user_wants_to_overwrite;
|
||||
use crate::{extension::Extension, utils::EscapedPathDisplay, QuestionPolicy};
|
||||
use crate::{
|
||||
extension::Extension,
|
||||
utils::{logger::info_accessible, EscapedPathDisplay},
|
||||
QuestionPolicy,
|
||||
};
|
||||
|
||||
/// Remove `path` asking the user to overwrite if necessary.
|
||||
///
|
||||
|
@ -1,21 +1,21 @@
|
||||
use std::sync::{
|
||||
mpsc::{channel, Receiver, Sender},
|
||||
OnceLock,
|
||||
};
|
||||
use std::sync::{mpsc, OnceLock};
|
||||
|
||||
use super::colors::{ORANGE, RESET, YELLOW};
|
||||
use crate::accessible::is_running_in_accessible_mode;
|
||||
|
||||
static SENDER: OnceLock<Sender<PrintMessage>> = OnceLock::new();
|
||||
type Receiver = mpsc::Receiver<PrintMessage>;
|
||||
type Sender = mpsc::Sender<PrintMessage>;
|
||||
|
||||
pub fn setup_channel() -> Receiver<PrintMessage> {
|
||||
let (tx, rx) = channel();
|
||||
static SENDER: OnceLock<Sender> = OnceLock::new();
|
||||
|
||||
pub fn setup_channel() -> Receiver {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
SENDER.set(tx).expect("`setup_channel` should only be called once");
|
||||
rx
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn get_sender() -> &'static Sender<PrintMessage> {
|
||||
fn get_sender() -> &'static Sender {
|
||||
SENDER.get().expect("No sender, you need to call `setup_channel` first")
|
||||
}
|
||||
|
||||
@ -75,77 +75,20 @@ pub fn info_accessible(contents: String) {
|
||||
}
|
||||
|
||||
fn info_with_accessibility(contents: String, accessible: bool) {
|
||||
get_sender()
|
||||
.send(PrintMessage {
|
||||
contents,
|
||||
accessible,
|
||||
level: MessageLevel::Info,
|
||||
})
|
||||
.unwrap();
|
||||
send_log_message(PrintMessage {
|
||||
contents,
|
||||
accessible,
|
||||
level: MessageLevel::Info,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn warning(contents: String) {
|
||||
get_sender()
|
||||
.send(PrintMessage {
|
||||
contents,
|
||||
// Warnings are important and unlikely to flood, so they should be displayed
|
||||
accessible: true,
|
||||
level: MessageLevel::Warning,
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Logger {
|
||||
log_sender: Sender<PrintMessage>,
|
||||
}
|
||||
|
||||
impl Logger {
|
||||
pub fn new(log_sender: Sender<PrintMessage>) -> Self {
|
||||
Self { log_sender }
|
||||
}
|
||||
|
||||
/// An `[INFO]` log to be displayed if we're not running accessibility mode.
|
||||
///
|
||||
/// Same as `.info_accessible()`, but only displayed if accessibility mode
|
||||
/// is turned off, which is detected by the function
|
||||
/// `is_running_in_accessible_mode`.
|
||||
///
|
||||
/// Read more about accessibility mode in `accessible.rs`.
|
||||
pub fn info(&self, contents: String) {
|
||||
self.info_with_accessibility(contents, false);
|
||||
}
|
||||
|
||||
/// An `[INFO]` log to be displayed.
|
||||
///
|
||||
/// Same as `.info()`, but also displays if `is_running_in_accessible_mode`
|
||||
/// returns `true`.
|
||||
///
|
||||
/// Read more about accessibility mode in `accessible.rs`.
|
||||
pub fn info_accessible(&self, contents: String) {
|
||||
self.info_with_accessibility(contents, true);
|
||||
}
|
||||
|
||||
fn info_with_accessibility(&self, contents: String, accessible: bool) {
|
||||
self.log_sender
|
||||
.send(PrintMessage {
|
||||
contents,
|
||||
accessible,
|
||||
level: MessageLevel::Info,
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn warning(&self, contents: String) {
|
||||
self.log_sender
|
||||
.send(PrintMessage {
|
||||
contents,
|
||||
// Warnings are important and unlikely to flood, so they should be displayed
|
||||
accessible: true,
|
||||
level: MessageLevel::Warning,
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
send_log_message(PrintMessage {
|
||||
contents,
|
||||
// Warnings are important and unlikely to flood, so they should be displayed
|
||||
accessible: true,
|
||||
level: MessageLevel::Warning,
|
||||
});
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@ -153,3 +96,7 @@ pub enum MessageLevel {
|
||||
Info,
|
||||
Warning,
|
||||
}
|
||||
|
||||
fn send_log_message(msg: PrintMessage) {
|
||||
get_sender().send(msg).expect("Failed to send internal message");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user