From 0f0b0869433337ff78f927a0536e4a092a17e5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Rodrigues=20Miguel?= Date: Mon, 29 Mar 2021 01:37:01 -0300 Subject: [PATCH] Use the the -y and -n flags when decompressing .tar and .zip --- src/cli.rs | 2 +- src/decompressors/decompressor.rs | 7 +++++-- src/decompressors/tar.rs | 15 ++++++++------- src/decompressors/to_memory.rs | 8 ++++---- src/decompressors/zip.rs | 27 +++++++++++++++++---------- src/evaluator.rs | 17 +++++++++-------- src/main.rs | 5 ++--- src/utils.rs | 13 ++++++++++++- 8 files changed, 58 insertions(+), 36 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 8a46675..af6222f 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -22,7 +22,7 @@ pub enum CommandKind { ), } -#[derive(PartialEq, Eq, Debug)] +#[derive(PartialEq, Eq, Copy, Clone, Debug)] pub enum Flags { // No flags supplied None, diff --git a/src/decompressors/decompressor.rs b/src/decompressors/decompressor.rs index 5d2def1..ea9436b 100644 --- a/src/decompressors/decompressor.rs +++ b/src/decompressors/decompressor.rs @@ -1,6 +1,9 @@ use std::path::PathBuf; -use crate::file::File; +use crate::{ + cli::Flags, + file::File +}; pub enum DecompressionResult { FilesUnpacked(Vec), @@ -8,5 +11,5 @@ pub enum DecompressionResult { } pub trait Decompressor { - fn decompress(&self, from: File, into: &Option) -> crate::Result; + fn decompress(&self, from: File, into: &Option, flags: Flags) -> crate::Result; } diff --git a/src/decompressors/tar.rs b/src/decompressors/tar.rs index 13ef979..b3947e3 100644 --- a/src/decompressors/tar.rs +++ b/src/decompressors/tar.rs @@ -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> { + fn unpack_files(from: File, into: &Path, flags: Flags) -> crate::Result> { 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> = 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) -> crate::Result { + fn decompress(&self, from: File, into: &Option, flags: Flags) -> crate::Result { 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)) } diff --git a/src/decompressors/to_memory.rs b/src/decompressors/to_memory.rs index 81a0e27..e8b9fb9 100644 --- a/src/decompressors/to_memory.rs +++ b/src/decompressors/to_memory.rs @@ -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) -> crate::Result { + fn decompress(&self, from: File, into: &Option, _: Flags) -> crate::Result { DecompressorToMemory::decompress(from, CompressionFormat::Gzip, into) } } impl Decompressor for BzipDecompressor { - fn decompress(&self, from: File, into: &Option) -> crate::Result { + fn decompress(&self, from: File, into: &Option, _: Flags) -> crate::Result { DecompressorToMemory::decompress(from, CompressionFormat::Bzip, into) } } impl Decompressor for LzmaDecompressor { - fn decompress(&self, from: File, into: &Option) -> crate::Result { + fn decompress(&self, from: File, into: &Option, _: Flags) -> crate::Result { DecompressorToMemory::decompress(from, CompressionFormat::Lzma, into) } } diff --git a/src/decompressors/zip.rs b/src/decompressors/zip.rs index 40e8441..50dd278 100644 --- a/src/decompressors/zip.rs +++ b/src/decompressors/zip.rs @@ -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( archive: &mut ZipArchive, into: &Path, + flags: Flags, ) -> crate::Result> 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> { + fn unpack_files(from: File, into: &Path, flags: Flags) -> crate::Result> { 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) -> crate::Result { + fn decompress( + &self, + from: File, + into: &Option, + flags: Flags, + ) -> crate::Result { 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)) } diff --git a/src/evaluator.rs b/src/evaluator.rs index d913bea..5c73286 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -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, file_path: PathBuf, decompressor: Option>, output_file: &Option, extension: Option, + 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) -> crate::Result<()> { - // let output_file = &command.output; + fn decompress_file(file: File, output: &Option, 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)?; } } } diff --git a/src/main.rs b/src/main.rs index 3be1a77..4df4f69 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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) } diff --git a/src/utils.rs b/src/utils.rs index 60bdb2c..cc1afe5 100644 --- a/src/utils.rs +++ b/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 { + 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))?) +} \ No newline at end of file