mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-07 12:05:46 +00:00
Merge branch 'master' into migrate-to-clap
This commit is contained in:
commit
e17eb9595e
@ -16,6 +16,7 @@
|
|||||||
2. Automatic format detection.
|
2. Automatic format detection.
|
||||||
3. Same syntax, various formats.
|
3. Same syntax, various formats.
|
||||||
4. Encoding and decoding streams, it's fast. <!-- We should post benchmarks in our wiki and link them here -->
|
4. Encoding and decoding streams, it's fast. <!-- We should post benchmarks in our wiki and link them here -->
|
||||||
|
5. No runtime dependencies (for _Linux x86_64_).
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -60,6 +61,8 @@ ouch compress * everything.tar.gz.xz.bz.zst.gz.gz.gz.gz.gz
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
[](https://repology.org/project/ouch/versions)
|
||||||
|
|
||||||
### Downloading the latest binary
|
### Downloading the latest binary
|
||||||
|
|
||||||
Compiled for `x86_64` on _Linux_, _Mac OS_ and _Windows_, run with `curl` or `wget`.
|
Compiled for `x86_64` on _Linux_, _Mac OS_ and _Windows_, run with `curl` or `wget`.
|
||||||
|
@ -11,7 +11,7 @@ use zip::{self, read::ZipFile, ZipArchive};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
info,
|
info,
|
||||||
utils::{self, dir_is_empty, Bytes},
|
utils::{self, dir_is_empty,strip_cur_dir, Bytes},
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::utf8::get_invalid_utf8_paths;
|
use self::utf8::get_invalid_utf8_paths;
|
||||||
@ -51,6 +51,7 @@ where
|
|||||||
fs::create_dir_all(&path)?;
|
fs::create_dir_all(&path)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let file_path = strip_cur_dir(file_path.as_path());
|
||||||
|
|
||||||
info!("{:?} extracted. ({})", file_path.display(), Bytes::new(file.size()));
|
info!("{:?} extracted. ({})", file_path.display(), Bytes::new(file.size()));
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ use crate::{
|
|||||||
CompressionFormat::{self, *},
|
CompressionFormat::{self, *},
|
||||||
},
|
},
|
||||||
info,
|
info,
|
||||||
|
utils::nice_directory_display,
|
||||||
utils::to_utf,
|
utils::to_utf,
|
||||||
utils::{self, dir_is_empty},
|
utils::{self, dir_is_empty},
|
||||||
Error,
|
Error,
|
||||||
@ -311,7 +312,7 @@ fn decompress_file(
|
|||||||
utils::create_dir_if_non_existent(output_folder)?;
|
utils::create_dir_if_non_existent(output_folder)?;
|
||||||
let zip_archive = zip::ZipArchive::new(reader)?;
|
let zip_archive = zip::ZipArchive::new(reader)?;
|
||||||
let _files = crate::archive::zip::unpack_archive(zip_archive, output_folder, skip_questions_positively)?;
|
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(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,31 +346,31 @@ fn decompress_file(
|
|||||||
let mut writer = fs::File::create(&output_path)?;
|
let mut writer = fs::File::create(&output_path)?;
|
||||||
|
|
||||||
io::copy(&mut reader, &mut writer)?;
|
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 => {
|
Tar => {
|
||||||
let _ = crate::archive::tar::unpack_archive(reader, output_folder, skip_questions_positively)?;
|
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 => {
|
Tgz => {
|
||||||
let reader = chain_reader_decoder(&Gzip, reader)?;
|
let reader = chain_reader_decoder(&Gzip, reader)?;
|
||||||
let _ = crate::archive::tar::unpack_archive(reader, output_folder, skip_questions_positively)?;
|
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 => {
|
Tbz => {
|
||||||
let reader = chain_reader_decoder(&Bzip, reader)?;
|
let reader = chain_reader_decoder(&Bzip, reader)?;
|
||||||
let _ = crate::archive::tar::unpack_archive(reader, output_folder, skip_questions_positively)?;
|
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 => {
|
Tlzma => {
|
||||||
let reader = chain_reader_decoder(&Lzma, reader)?;
|
let reader = chain_reader_decoder(&Lzma, reader)?;
|
||||||
let _ = crate::archive::tar::unpack_archive(reader, output_folder, skip_questions_positively)?;
|
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 => {
|
Tzst => {
|
||||||
let reader = chain_reader_decoder(&Zstd, reader)?;
|
let reader = chain_reader_decoder(&Zstd, reader)?;
|
||||||
let _ = crate::archive::tar::unpack_archive(reader, output_folder, skip_questions_positively)?;
|
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 => {
|
Zip => {
|
||||||
eprintln!("Compressing first into .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)?;
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
src/utils.rs
24
src/utils.rs
@ -2,6 +2,7 @@ use std::{
|
|||||||
cmp, env,
|
cmp, env,
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
fs::{self, ReadDir},
|
fs::{self, ReadDir},
|
||||||
|
path::Component,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,6 +23,13 @@ pub fn create_dir_if_non_existent(path: &Path) -> crate::Result<()> {
|
|||||||
Ok(())
|
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
|
/// Changes the process' current directory to the directory that contains the
|
||||||
/// file pointed to by `filename` and returns the directory that the process
|
/// file pointed to by `filename` and returns the directory that the process
|
||||||
/// was in before this function was called.
|
/// was in before this function was called.
|
||||||
@ -39,7 +47,12 @@ pub fn user_wants_to_overwrite(path: &Path, skip_questions_positively: Option<bo
|
|||||||
match skip_questions_positively {
|
match skip_questions_positively {
|
||||||
Some(true) => Ok(true),
|
Some(true) => Ok(true),
|
||||||
Some(false) => Ok(false),
|
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<OsStr>) -> String {
|
|||||||
text.trim_matches('"').to_string()
|
text.trim_matches('"').to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn nice_directory_display(os_str: impl AsRef<OsStr>) -> String {
|
||||||
|
let text = to_utf(os_str);
|
||||||
|
if text == "." {
|
||||||
|
"current directory".to_string()
|
||||||
|
} else {
|
||||||
|
format!("'{}'", text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Bytes {
|
pub struct Bytes {
|
||||||
bytes: f64,
|
bytes: f64,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user