diff --git a/README.md b/README.md index cba6af6..4ab33f7 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ 2. Automatic format detection. 3. Same syntax, various formats. 4. Encoding and decoding streams, it's fast. +5. No runtime dependencies (for _Linux x86_64_). ## Usage @@ -60,6 +61,8 @@ ouch compress * everything.tar.gz.xz.bz.zst.gz.gz.gz.gz.gz ## Installation +[![Packaging status](https://repology.org/badge/vertical-allrepos/ouch.svg)](https://repology.org/project/ouch/versions) + ### Downloading the latest binary Compiled for `x86_64` on _Linux_, _Mac OS_ and _Windows_, run with `curl` or `wget`. diff --git a/src/archive/zip.rs b/src/archive/zip.rs index eb2187e..db35727 100644 --- a/src/archive/zip.rs +++ b/src/archive/zip.rs @@ -11,7 +11,7 @@ use zip::{self, read::ZipFile, ZipArchive}; use crate::{ info, - utils::{self, dir_is_empty, Bytes}, + utils::{self, dir_is_empty,strip_cur_dir, Bytes}, }; use self::utf8::get_invalid_utf8_paths; @@ -51,6 +51,7 @@ where fs::create_dir_all(&path)?; } } + let file_path = strip_cur_dir(file_path.as_path()); info!("{:?} extracted. ({})", file_path.display(), Bytes::new(file.size())); diff --git a/src/commands.rs b/src/commands.rs index 7960804..6d41347 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -19,6 +19,7 @@ use crate::{ CompressionFormat::{self, *}, }, info, + utils::nice_directory_display, utils::to_utf, utils::{self, dir_is_empty}, Error, @@ -311,7 +312,7 @@ fn decompress_file( utils::create_dir_if_non_existent(output_folder)?; let zip_archive = zip::ZipArchive::new(reader)?; let _files = crate::archive::zip::unpack_archive(zip_archive, output_folder, skip_questions_positively)?; - info!("Successfully uncompressed archive in '{}'.", to_utf(output_folder)); + info!("Successfully decompressed archive in {}.", nice_directory_display(output_folder)); return Ok(()); } @@ -345,31 +346,31 @@ fn decompress_file( let mut writer = fs::File::create(&output_path)?; io::copy(&mut reader, &mut writer)?; - info!("Successfully uncompressed archive in '{}'.", to_utf(output_path)); + info!("Successfully decompressed archive in {}.", nice_directory_display(output_path)); } Tar => { let _ = crate::archive::tar::unpack_archive(reader, output_folder, skip_questions_positively)?; - info!("Successfully uncompressed archive in '{}'.", to_utf(output_folder)); + info!("Successfully decompressed archive in {}.", nice_directory_display(output_folder)); } Tgz => { let reader = chain_reader_decoder(&Gzip, reader)?; let _ = crate::archive::tar::unpack_archive(reader, output_folder, skip_questions_positively)?; - info!("Successfully uncompressed archive in '{}'.", to_utf(output_folder)); + info!("Successfully decompressed archive in {}.", nice_directory_display(output_folder)); } Tbz => { let reader = chain_reader_decoder(&Bzip, reader)?; let _ = crate::archive::tar::unpack_archive(reader, output_folder, skip_questions_positively)?; - info!("Successfully uncompressed archive in '{}'.", to_utf(output_folder)); + info!("Successfully decompressed archive in {}.", nice_directory_display(output_folder)); } Tlzma => { let reader = chain_reader_decoder(&Lzma, reader)?; let _ = crate::archive::tar::unpack_archive(reader, output_folder, skip_questions_positively)?; - info!("Successfully uncompressed archive in '{}'.", to_utf(output_folder)); + info!("Successfully decompressed archive in {}.", nice_directory_display(output_folder)); } Tzst => { let reader = chain_reader_decoder(&Zstd, reader)?; let _ = crate::archive::tar::unpack_archive(reader, output_folder, skip_questions_positively)?; - info!("Successfully uncompressed archive in '{}'.", to_utf(output_folder)); + info!("Successfully decompressed archive in {}.", nice_directory_display(output_folder)); } Zip => { eprintln!("Compressing first into .zip."); @@ -385,7 +386,7 @@ fn decompress_file( let _ = crate::archive::zip::unpack_archive(zip_archive, output_folder, skip_questions_positively)?; - info!("Successfully uncompressed archive in '{}'.", to_utf(output_folder)); + info!("Successfully decompressed archive in {}.", nice_directory_display(output_folder)); } } diff --git a/src/utils.rs b/src/utils.rs index 6e282fa..4e69ab0 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,6 +2,7 @@ use std::{ cmp, env, ffi::OsStr, fs::{self, ReadDir}, + path::Component, path::{Path, PathBuf}, }; @@ -22,6 +23,13 @@ pub fn create_dir_if_non_existent(path: &Path) -> crate::Result<()> { Ok(()) } +pub fn strip_cur_dir(source_path: &Path) -> PathBuf { + source_path + .strip_prefix(Component::CurDir) + .map(|path| path.to_path_buf()) + .unwrap_or_else(|_| source_path.to_path_buf()) +} + /// Changes the process' current directory to the directory that contains the /// file pointed to by `filename` and returns the directory that the process /// was in before this function was called. @@ -39,7 +47,12 @@ pub fn user_wants_to_overwrite(path: &Path, skip_questions_positively: Option Ok(true), Some(false) => Ok(false), - None => Confirmation::new("Do you want to overwrite 'FILE'?", Some("FILE")).ask(Some(&to_utf(path))), + None => { + let path = to_utf(strip_cur_dir(path)); + let path = Some(path.as_str()); + let placeholder = Some("FILE"); + Confirmation::new("Do you want to overwrite 'FILE'?", placeholder).ask(path) + } } } @@ -48,6 +61,15 @@ pub fn to_utf(os_str: impl AsRef) -> String { text.trim_matches('"').to_string() } +pub fn nice_directory_display(os_str: impl AsRef) -> String { + let text = to_utf(os_str); + if text == "." { + "current directory".to_string() + } else { + format!("'{}'", text) + } +} + pub struct Bytes { bytes: f64, }