Skip to content

Commit

Permalink
Merge pull request #124 from AntonHermann/introduce_question_policy
Browse files Browse the repository at this point in the history
Introduce new type for policy on how to handle overwrite questions
  • Loading branch information
marcospb19 authored Oct 21, 2021
2 parents a46fa1f + 10f7462 commit 4cfc7b9
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 32 deletions.
6 changes: 3 additions & 3 deletions src/archive/tar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ use walkdir::WalkDir;

use crate::{
info,
utils::{self, Bytes},
utils::{self, Bytes, QuestionPolicy},
};

pub fn unpack_archive(
reader: Box<dyn Read>,
output_folder: &Path,
skip_questions_positively: Option<bool>,
question_policy: QuestionPolicy,
) -> crate::Result<Vec<PathBuf>> {
let mut archive = tar::Archive::new(reader);

Expand All @@ -26,7 +26,7 @@ pub fn unpack_archive(
let mut file = file?;

let file_path = output_folder.join(file.path()?);
if file_path.exists() && !utils::user_wants_to_overwrite(&file_path, skip_questions_positively)? {
if file_path.exists() && !utils::user_wants_to_overwrite(&file_path, question_policy)? {
continue;
}

Expand Down
6 changes: 3 additions & 3 deletions src/archive/zip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use zip::{self, read::ZipFile, ZipArchive};

use crate::{
info,
utils::{self, dir_is_empty,strip_cur_dir, Bytes},
utils::{self, dir_is_empty, strip_cur_dir, Bytes, QuestionPolicy},
};

use self::utf8::get_invalid_utf8_paths;
Expand All @@ -20,7 +20,7 @@ use self::utf8::get_invalid_utf8_paths;
pub fn unpack_archive<R>(
mut archive: ZipArchive<R>,
into: &Path,
skip_questions_positively: Option<bool>,
question_policy: QuestionPolicy,
) -> crate::Result<Vec<PathBuf>>
where
R: Read + Seek,
Expand All @@ -34,7 +34,7 @@ where
};

let file_path = into.join(file_path);
if file_path.exists() && !utils::user_wants_to_overwrite(&file_path, skip_questions_positively)? {
if file_path.exists() && !utils::user_wants_to_overwrite(&file_path, question_policy)? {
continue;
}

Expand Down
9 changes: 5 additions & 4 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::{

use clap::{Parser, ValueHint};

pub use crate::utils::QuestionPolicy;
use crate::Error;

#[derive(Parser, Debug)]
Expand Down Expand Up @@ -53,18 +54,18 @@ pub enum Subcommand {
impl Opts {
/// A helper method that calls `clap::Parser::parse` and then translates relative paths to absolute.
/// Also determines if the user wants to skip questions or not
pub fn parse_args() -> crate::Result<(Self, Option<bool>)> {
pub fn parse_args() -> crate::Result<(Self, QuestionPolicy)> {
let mut opts: Self = Self::parse();

let (Subcommand::Compress { files, .. } | Subcommand::Decompress { files, .. }) = &mut opts.cmd;
*files = canonicalize_files(files)?;

let skip_questions_positively = if opts.yes {
Some(true)
QuestionPolicy::AlwaysYes
} else if opts.no {
Some(false)
QuestionPolicy::AlwaysNo
} else {
None
QuestionPolicy::Ask
};

Ok((opts, skip_questions_positively))
Expand Down
24 changes: 12 additions & 12 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
info,
utils::nice_directory_display,
utils::to_utf,
utils::{self, dir_is_empty},
utils::{self, dir_is_empty, QuestionPolicy},
Error,
};

Expand All @@ -38,7 +38,7 @@ fn represents_several_files(files: &[PathBuf]) -> bool {
files.iter().any(is_non_empty_dir) || files.len() > 1
}

pub fn run(args: Opts, skip_questions_positively: Option<bool>) -> crate::Result<()> {
pub fn run(args: Opts, question_policy: QuestionPolicy) -> crate::Result<()> {
match args.cmd {
Subcommand::Compress { files, output: output_path } => {
// Formats from path extension, like "file.tar.gz.xz" -> vec![Tar, Gzip, Lzma]
Expand Down Expand Up @@ -94,7 +94,7 @@ pub fn run(args: Opts, skip_questions_positively: Option<bool>) -> crate::Result
return Err(Error::with_reason(reason));
}

if output_path.exists() && !utils::user_wants_to_overwrite(&output_path, skip_questions_positively)? {
if output_path.exists() && !utils::user_wants_to_overwrite(&output_path, question_policy)? {
// User does not want to overwrite this file
return Ok(());
}
Expand Down Expand Up @@ -176,7 +176,7 @@ pub fn run(args: Opts, skip_questions_positively: Option<bool>) -> crate::Result
let output_folder = output_folder.as_ref().map(|path| path.as_ref());

for ((input_path, formats), file_name) in files.iter().zip(formats).zip(output_paths) {
decompress_file(input_path, formats, output_folder, file_name, skip_questions_positively)?;
decompress_file(input_path, formats, output_folder, file_name, question_policy)?;
}
}
}
Expand Down Expand Up @@ -289,7 +289,7 @@ fn decompress_file(
formats: Vec<extension::CompressionFormat>,
output_folder: Option<&Path>,
file_name: &Path,
skip_questions_positively: Option<bool>,
question_policy: QuestionPolicy,
) -> crate::Result<()> {
// TODO: improve error message
let reader = fs::File::open(&input_file_path)?;
Expand All @@ -311,7 +311,7 @@ fn decompress_file(
if let [Zip] = *formats.as_slice() {
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)?;
let _files = crate::archive::zip::unpack_archive(zip_archive, output_folder, question_policy)?;
info!("Successfully decompressed archive in {}.", nice_directory_display(output_folder));
return Ok(());
}
Expand Down Expand Up @@ -349,27 +349,27 @@ fn decompress_file(
info!("Successfully decompressed archive in {}.", nice_directory_display(output_path));
}
Tar => {
let _ = crate::archive::tar::unpack_archive(reader, output_folder, skip_questions_positively)?;
let _ = crate::archive::tar::unpack_archive(reader, output_folder, question_policy)?;
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)?;
let _ = crate::archive::tar::unpack_archive(reader, output_folder, question_policy)?;
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)?;
let _ = crate::archive::tar::unpack_archive(reader, output_folder, question_policy)?;
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)?;
let _ = crate::archive::tar::unpack_archive(reader, output_folder, question_policy)?;
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)?;
let _ = crate::archive::tar::unpack_archive(reader, output_folder, question_policy)?;
info!("Successfully decompressed archive in {}.", nice_directory_display(output_folder));
}
Zip => {
Expand All @@ -384,7 +384,7 @@ fn decompress_file(
io::copy(&mut reader, &mut vec)?;
let zip_archive = zip::ZipArchive::new(io::Cursor::new(vec))?;

let _ = crate::archive::zip::unpack_archive(zip_archive, output_folder, skip_questions_positively)?;
let _ = crate::archive::zip::unpack_archive(zip_archive, output_folder, question_policy)?;

info!("Successfully decompressed archive in {}.", nice_directory_display(output_folder));
}
Expand Down
21 changes: 16 additions & 5 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ pub fn cd_into_same_dir_as(filename: &Path) -> crate::Result<PathBuf> {
Ok(previous_location)
}

pub fn user_wants_to_overwrite(path: &Path, skip_questions_positively: Option<bool>) -> crate::Result<bool> {
match skip_questions_positively {
Some(true) => Ok(true),
Some(false) => Ok(false),
None => {
pub fn user_wants_to_overwrite(path: &Path, question_policy: QuestionPolicy) -> crate::Result<bool> {
match question_policy {
QuestionPolicy::AlwaysYes => Ok(true),
QuestionPolicy::AlwaysNo => Ok(false),
QuestionPolicy::Ask => {
let path = to_utf(strip_cur_dir(path));
let path = Some(path.as_str());
let placeholder = Some("FILE");
Expand Down Expand Up @@ -126,6 +126,17 @@ impl std::fmt::Display for Bytes {
}
}

#[derive(Debug, PartialEq, Clone, Copy)]
/// How overwrite questions should be handled
pub enum QuestionPolicy {
/// Ask ever time
Ask,
/// Skip overwrite questions positively
AlwaysYes,
/// Skip overwrite questions negatively
AlwaysNo,
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 2 additions & 2 deletions tests/compress_and_decompress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{
};

use ouch::{
cli::{Opts, Subcommand},
cli::{Opts, QuestionPolicy, Subcommand},
commands::run,
};
use rand::{rngs::SmallRng, RngCore, SeedableRng};
Expand Down Expand Up @@ -183,7 +183,7 @@ fn extract_files(archive_path: &Path) -> Vec<PathBuf> {
output: Some(extraction_output_folder.clone()),
},
};
run(command, None).expect("Failed to extract");
run(command, QuestionPolicy::Ask).expect("Failed to extract");

fs::read_dir(extraction_output_folder).unwrap().map(Result::unwrap).map(|entry| entry.path()).collect()
}
Expand Down
6 changes: 3 additions & 3 deletions tests/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{
};

use ouch::{
cli::{Opts, Subcommand},
cli::{Opts, QuestionPolicy, Subcommand},
commands::run,
};

Expand All @@ -30,7 +30,7 @@ pub fn compress_files(at: &Path, paths_to_compress: &[PathBuf], format: &str) ->
no: false,
cmd: Subcommand::Compress { files: paths_to_compress.to_vec(), output: archive_path.clone() },
};
run(command, None).expect("Failed to compress test dummy files");
run(command, QuestionPolicy::Ask).expect("Failed to compress test dummy files");

archive_path
}
Expand All @@ -55,7 +55,7 @@ pub fn extract_files(archive_path: &Path) -> Vec<PathBuf> {
output: Some(extraction_output_folder.clone()),
},
};
run(command, None).expect("Failed to extract");
run(command, QuestionPolicy::Ask).expect("Failed to extract");

fs::read_dir(extraction_output_folder).unwrap().map(Result::unwrap).map(|entry| entry.path()).collect()
}
Expand Down

0 comments on commit 4cfc7b9

Please sign in to comment.