mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-06 11:35:45 +00:00
Use the the -y and -n flags when decompressing .tar and .zip
This commit is contained in:
parent
c7cf1112b6
commit
0f0b086943
@ -22,7 +22,7 @@ pub enum CommandKind {
|
||||
),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
pub enum Flags {
|
||||
// No flags supplied
|
||||
None,
|
||||
|
@ -1,6 +1,9 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::file::File;
|
||||
use crate::{
|
||||
cli::Flags,
|
||||
file::File
|
||||
};
|
||||
|
||||
pub enum DecompressionResult {
|
||||
FilesUnpacked(Vec<PathBuf>),
|
||||
@ -8,5 +11,5 @@ pub enum DecompressionResult {
|
||||
}
|
||||
|
||||
pub trait Decompressor {
|
||||
fn decompress(&self, from: File, into: &Option<File>) -> crate::Result<DecompressionResult>;
|
||||
fn decompress(&self, from: File, into: &Option<File>, flags: Flags) -> crate::Result<DecompressionResult>;
|
||||
}
|
||||
|
@ -8,13 +8,13 @@ use colored::Colorize;
|
||||
use tar::{self, Archive};
|
||||
|
||||
use super::decompressor::{DecompressionResult, Decompressor};
|
||||
use crate::{file::File, utils, dialogs::Confirmation};
|
||||
use crate::{cli::Flags, dialogs::Confirmation, file::File, utils};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TarDecompressor {}
|
||||
|
||||
impl TarDecompressor {
|
||||
fn unpack_files(from: File, into: &Path) -> crate::Result<Vec<PathBuf>> {
|
||||
fn unpack_files(from: File, into: &Path, flags: Flags) -> crate::Result<Vec<PathBuf>> {
|
||||
println!(
|
||||
"{}: attempting to decompress {:?}",
|
||||
"ouch".bright_blue(),
|
||||
@ -24,7 +24,9 @@ impl TarDecompressor {
|
||||
let confirm = Confirmation::new("Do you want to overwrite 'FILE'?", Some("FILE"));
|
||||
|
||||
let mut archive: Archive<Box<dyn Read>> = match from.contents_in_memory {
|
||||
Some(bytes) => tar::Archive::new(Box::new(Cursor::new(bytes))),
|
||||
Some(bytes) => {
|
||||
tar::Archive::new(Box::new(Cursor::new(bytes)))
|
||||
},
|
||||
None => {
|
||||
let file = fs::File::open(&from.path)?;
|
||||
tar::Archive::new(Box::new(file))
|
||||
@ -36,8 +38,7 @@ impl TarDecompressor {
|
||||
|
||||
let file_path = PathBuf::from(into).join(file.path()?);
|
||||
if file_path.exists() {
|
||||
let file_path_str = &*file_path.to_string_lossy();
|
||||
if !confirm.ask(Some(file_path_str))? {
|
||||
if !utils::permission_for_overwriting(&file_path, flags, &confirm)? {
|
||||
// The user does not want to overwrite the file
|
||||
continue;
|
||||
}
|
||||
@ -61,12 +62,12 @@ impl TarDecompressor {
|
||||
}
|
||||
|
||||
impl Decompressor for TarDecompressor {
|
||||
fn decompress(&self, from: File, into: &Option<File>) -> crate::Result<DecompressionResult> {
|
||||
fn decompress(&self, from: File, into: &Option<File>, flags: Flags) -> crate::Result<DecompressionResult> {
|
||||
let destination_path = utils::get_destination_path(into);
|
||||
|
||||
utils::create_path_if_non_existent(destination_path)?;
|
||||
|
||||
let files_unpacked = Self::unpack_files(from, destination_path)?;
|
||||
let files_unpacked = Self::unpack_files(from, destination_path, flags)?;
|
||||
|
||||
Ok(DecompressionResult::FilesUnpacked(files_unpacked))
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use std::{
|
||||
use colored::Colorize;
|
||||
|
||||
use super::decompressor::{DecompressionResult, Decompressor};
|
||||
use crate::utils;
|
||||
use crate::{cli::Flags, utils};
|
||||
// use niffler;
|
||||
use crate::{extension::CompressionFormat, file::File};
|
||||
|
||||
@ -62,19 +62,19 @@ impl DecompressorToMemory {
|
||||
}
|
||||
|
||||
impl Decompressor for GzipDecompressor {
|
||||
fn decompress(&self, from: File, into: &Option<File>) -> crate::Result<DecompressionResult> {
|
||||
fn decompress(&self, from: File, into: &Option<File>, _: Flags) -> crate::Result<DecompressionResult> {
|
||||
DecompressorToMemory::decompress(from, CompressionFormat::Gzip, into)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decompressor for BzipDecompressor {
|
||||
fn decompress(&self, from: File, into: &Option<File>) -> crate::Result<DecompressionResult> {
|
||||
fn decompress(&self, from: File, into: &Option<File>, _: Flags) -> crate::Result<DecompressionResult> {
|
||||
DecompressorToMemory::decompress(from, CompressionFormat::Bzip, into)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decompressor for LzmaDecompressor {
|
||||
fn decompress(&self, from: File, into: &Option<File>) -> crate::Result<DecompressionResult> {
|
||||
fn decompress(&self, from: File, into: &Option<File>, _: Flags) -> crate::Result<DecompressionResult> {
|
||||
DecompressorToMemory::decompress(from, CompressionFormat::Lzma, into)
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use colored::Colorize;
|
||||
use zip::{self, read::ZipFile, ZipArchive};
|
||||
|
||||
use super::decompressor::{DecompressionResult, Decompressor};
|
||||
use crate::{dialogs::Confirmation, file::File, utils};
|
||||
use crate::{cli::Flags, dialogs::Confirmation, file::File, utils};
|
||||
|
||||
#[cfg(unix)]
|
||||
fn __unix_set_permissions(file_path: &PathBuf, file: &ZipFile) {
|
||||
@ -37,6 +37,7 @@ impl ZipDecompressor {
|
||||
pub fn zip_decompress<T>(
|
||||
archive: &mut ZipArchive<T>,
|
||||
into: &Path,
|
||||
flags: Flags,
|
||||
) -> crate::Result<Vec<PathBuf>>
|
||||
where
|
||||
T: Read + Seek,
|
||||
@ -52,8 +53,7 @@ impl ZipDecompressor {
|
||||
|
||||
let file_path = into.join(file_path);
|
||||
if file_path.exists() {
|
||||
let file_path_str = &*file_path.as_path().to_string_lossy();
|
||||
if !confirm.ask(Some(file_path_str))? {
|
||||
if !utils::permission_for_overwriting(&file_path, flags, &confirm)? {
|
||||
// The user does not want to overwrite the file
|
||||
continue;
|
||||
}
|
||||
@ -94,35 +94,42 @@ impl ZipDecompressor {
|
||||
Ok(unpacked_files)
|
||||
}
|
||||
|
||||
fn unpack_files(from: File, into: &Path) -> crate::Result<Vec<PathBuf>> {
|
||||
fn unpack_files(from: File, into: &Path, flags: Flags) -> crate::Result<Vec<PathBuf>> {
|
||||
println!(
|
||||
"{}: attempting to decompress {:?}",
|
||||
"ouch".bright_blue(),
|
||||
"{} decompressing {:?}",
|
||||
"[OUCH]".bright_blue(),
|
||||
&from.path
|
||||
);
|
||||
|
||||
match from.contents_in_memory {
|
||||
Some(bytes) => {
|
||||
// Decompressing a .zip archive loaded up in memory
|
||||
let mut archive = zip::ZipArchive::new(Cursor::new(bytes))?;
|
||||
Ok(Self::zip_decompress(&mut archive, into)?)
|
||||
Ok(Self::zip_decompress(&mut archive, into, flags)?)
|
||||
}
|
||||
None => {
|
||||
// Decompressing a .zip archive from the file system
|
||||
let file = fs::File::open(&from.path)?;
|
||||
let mut archive = zip::ZipArchive::new(file)?;
|
||||
|
||||
Ok(Self::zip_decompress(&mut archive, into)?)
|
||||
Ok(Self::zip_decompress(&mut archive, into, flags)?)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decompressor for ZipDecompressor {
|
||||
fn decompress(&self, from: File, into: &Option<File>) -> crate::Result<DecompressionResult> {
|
||||
fn decompress(
|
||||
&self,
|
||||
from: File,
|
||||
into: &Option<File>,
|
||||
flags: Flags,
|
||||
) -> crate::Result<DecompressionResult> {
|
||||
let destination_path = utils::get_destination_path(into);
|
||||
|
||||
utils::create_path_if_non_existent(destination_path)?;
|
||||
|
||||
let files_unpacked = Self::unpack_files(from, destination_path)?;
|
||||
let files_unpacked = Self::unpack_files(from, destination_path, flags)?;
|
||||
|
||||
Ok(DecompressionResult::FilesUnpacked(files_unpacked))
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use std::{ffi::OsStr, fs, io::Write, path::PathBuf};
|
||||
use colored::Colorize;
|
||||
|
||||
use crate::{
|
||||
cli::{Command, CommandKind},
|
||||
cli::{Flags, Command, CommandKind},
|
||||
compressors::{
|
||||
BzipCompressor, Compressor, Entry, GzipCompressor, LzmaCompressor, TarCompressor,
|
||||
ZipCompressor,
|
||||
@ -98,13 +98,13 @@ impl Evaluator {
|
||||
Ok((first_decompressor, second_decompressor))
|
||||
}
|
||||
|
||||
// todo: move this folder into decompressors/ later on
|
||||
fn decompress_file_in_memory(
|
||||
bytes: Vec<u8>,
|
||||
file_path: PathBuf,
|
||||
decompressor: Option<Box<dyn Decompressor>>,
|
||||
output_file: &Option<File>,
|
||||
extension: Option<Extension>,
|
||||
flags: Flags
|
||||
) -> crate::Result<()> {
|
||||
let output_file_path = utils::get_destination_path(output_file);
|
||||
|
||||
@ -139,7 +139,7 @@ impl Evaluator {
|
||||
extension,
|
||||
};
|
||||
|
||||
let decompression_result = decompressor.decompress(file, output_file)?;
|
||||
let decompression_result = decompressor.decompress(file, output_file, flags)?;
|
||||
if let DecompressionResult::FileInMemory(_) = decompression_result {
|
||||
// Should not be reachable.
|
||||
unreachable!();
|
||||
@ -152,6 +152,7 @@ impl Evaluator {
|
||||
let confirm = Confirmation::new("Do you want to overwrite 'FILE'?", Some("FILE"));
|
||||
let (first_compressor, second_compressor) = Self::get_compressor(&output)?;
|
||||
|
||||
// TODO: use -y and -n here
|
||||
let output_path = output.path.clone();
|
||||
if output_path.exists() {
|
||||
let output_path_str = &*output_path.to_string_lossy();
|
||||
@ -188,14 +189,13 @@ impl Evaluator {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn decompress_file(file: File, output: &Option<File>) -> crate::Result<()> {
|
||||
// let output_file = &command.output;
|
||||
fn decompress_file(file: File, output: &Option<File>, flags: Flags) -> crate::Result<()> {
|
||||
let (first_decompressor, second_decompressor) = Self::get_decompressor(&file)?;
|
||||
|
||||
let file_path = file.path.clone();
|
||||
let extension = file.extension.clone();
|
||||
|
||||
let decompression_result = second_decompressor.decompress(file, output)?;
|
||||
let decompression_result = second_decompressor.decompress(file, output, flags)?;
|
||||
|
||||
match decompression_result {
|
||||
DecompressionResult::FileInMemory(bytes) => {
|
||||
@ -207,6 +207,7 @@ impl Evaluator {
|
||||
first_decompressor,
|
||||
output,
|
||||
extension,
|
||||
flags
|
||||
)?;
|
||||
}
|
||||
DecompressionResult::FilesUnpacked(_files) => {
|
||||
@ -223,7 +224,7 @@ impl Evaluator {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn evaluate(command: Command) -> crate::Result<()> {
|
||||
pub fn evaluate(command: Command, flags: Flags) -> crate::Result<()> {
|
||||
let output = command.output.clone();
|
||||
|
||||
match command.kind {
|
||||
@ -234,7 +235,7 @@ impl Evaluator {
|
||||
}
|
||||
CommandKind::Decompression(files_to_decompress) => {
|
||||
for file in files_to_decompress {
|
||||
Self::decompress_file(file, &output)?;
|
||||
Self::decompress_file(file, &output, flags)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ use evaluator::Evaluator;
|
||||
|
||||
fn main() -> crate::Result<()> {
|
||||
let matches = cli::get_matches();
|
||||
// let command = cli::Command::try_from(matches)?;
|
||||
let (command, _flags) = cli::parse_matches(matches)?;
|
||||
Evaluator::evaluate(command)
|
||||
let (command, flags) = cli::parse_matches(matches)?;
|
||||
Evaluator::evaluate(command, flags)
|
||||
}
|
||||
|
13
src/utils.rs
13
src/utils.rs
@ -5,7 +5,7 @@ use std::{
|
||||
|
||||
use colored::Colorize;
|
||||
|
||||
use crate::{extension::CompressionFormat, file::File};
|
||||
use crate::{cli::Flags, dialogs::Confirmation, extension::CompressionFormat, file::File};
|
||||
|
||||
pub(crate) fn ensure_exists<'a, P>(path: P) -> crate::Result<()>
|
||||
where
|
||||
@ -90,3 +90,14 @@ pub(crate) fn change_dir_and_return_parent(filename: &PathBuf) -> crate::Result<
|
||||
env::set_current_dir(parent)?;
|
||||
Ok(previous_location)
|
||||
}
|
||||
|
||||
pub fn permission_for_overwriting(path: &PathBuf, flags: Flags, confirm: &Confirmation) -> crate::Result<bool> {
|
||||
match flags {
|
||||
Flags::AlwaysYes => return Ok(true),
|
||||
Flags::AlwaysNo => return Ok(false),
|
||||
Flags::None => {}
|
||||
}
|
||||
|
||||
let file_path_str = &*path.as_path().to_string_lossy();
|
||||
Ok(confirm.ask(Some(file_path_str))?)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user