mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-03 10:00:19 +00:00
feat: Add flag '--no-smart-unpack' to disable smart unpack (#809)
This commit is contained in:
parent
2b9da1e441
commit
c97bb6a2d6
@ -21,6 +21,7 @@ Categories Used:
|
||||
## [Unreleased](https://github.com/ouch-org/ouch/compare/0.6.1...HEAD)
|
||||
|
||||
### New Features
|
||||
- Add `--no-smart-unpack` flag to decompression command to disable smart unpack [\#809](https://github.com/ouch-org/ouch/pull/809) ([talis-fb](https://github.com/talis-fb))
|
||||
### Improvements
|
||||
### Bug Fixes
|
||||
### Tweaks
|
||||
|
@ -100,6 +100,10 @@ pub enum Subcommand {
|
||||
/// Remove the source file after successful decompression
|
||||
#[arg(short = 'r', long)]
|
||||
remove: bool,
|
||||
|
||||
/// Disable Smart Unpack
|
||||
#[arg(long)]
|
||||
no_smart_unpack: bool,
|
||||
},
|
||||
/// List contents of an archive
|
||||
#[command(visible_aliases = ["l", "ls"])]
|
||||
@ -156,6 +160,7 @@ mod tests {
|
||||
files: vec!["\x00\x11\x22".into()],
|
||||
output_dir: None,
|
||||
remove: false,
|
||||
no_smart_unpack: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -169,6 +174,7 @@ mod tests {
|
||||
files: to_paths(["file.tar.gz"]),
|
||||
output_dir: None,
|
||||
remove: false,
|
||||
no_smart_unpack: false,
|
||||
},
|
||||
..mock_cli_args()
|
||||
}
|
||||
@ -180,6 +186,7 @@ mod tests {
|
||||
files: to_paths(["file.tar.gz"]),
|
||||
output_dir: None,
|
||||
remove: false,
|
||||
no_smart_unpack: false,
|
||||
},
|
||||
..mock_cli_args()
|
||||
}
|
||||
@ -191,6 +198,7 @@ mod tests {
|
||||
files: to_paths(["a", "b", "c"]),
|
||||
output_dir: None,
|
||||
remove: false,
|
||||
no_smart_unpack: false,
|
||||
},
|
||||
..mock_cli_args()
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ pub struct DecompressOptions<'a> {
|
||||
pub output_dir: &'a Path,
|
||||
pub output_file_path: PathBuf,
|
||||
pub is_output_dir_provided: bool,
|
||||
pub is_smart_unpack: bool,
|
||||
pub question_policy: QuestionPolicy,
|
||||
pub quiet: bool,
|
||||
pub password: Option<&'a [u8]>,
|
||||
@ -75,6 +76,7 @@ pub fn decompress_file(options: DecompressOptions) -> crate::Result<()> {
|
||||
&options.output_file_path,
|
||||
options.question_policy,
|
||||
options.is_output_dir_provided,
|
||||
options.is_smart_unpack,
|
||||
)? {
|
||||
files
|
||||
} else {
|
||||
@ -153,6 +155,7 @@ pub fn decompress_file(options: DecompressOptions) -> crate::Result<()> {
|
||||
&options.output_file_path,
|
||||
options.question_policy,
|
||||
options.is_output_dir_provided,
|
||||
options.is_smart_unpack,
|
||||
)? {
|
||||
files
|
||||
} else {
|
||||
@ -187,6 +190,7 @@ pub fn decompress_file(options: DecompressOptions) -> crate::Result<()> {
|
||||
&options.output_file_path,
|
||||
options.question_policy,
|
||||
options.is_output_dir_provided,
|
||||
options.is_smart_unpack,
|
||||
)? {
|
||||
files
|
||||
} else {
|
||||
@ -219,6 +223,7 @@ pub fn decompress_file(options: DecompressOptions) -> crate::Result<()> {
|
||||
&options.output_file_path,
|
||||
options.question_policy,
|
||||
options.is_output_dir_provided,
|
||||
options.is_smart_unpack,
|
||||
)? {
|
||||
files
|
||||
} else {
|
||||
@ -261,6 +266,7 @@ pub fn decompress_file(options: DecompressOptions) -> crate::Result<()> {
|
||||
&options.output_file_path,
|
||||
options.question_policy,
|
||||
options.is_output_dir_provided,
|
||||
options.is_smart_unpack,
|
||||
)? {
|
||||
files
|
||||
} else {
|
||||
@ -296,12 +302,19 @@ fn execute_decompression(
|
||||
output_file_path: &Path,
|
||||
question_policy: QuestionPolicy,
|
||||
is_output_dir_provided: bool,
|
||||
is_smart_unpack: bool,
|
||||
) -> crate::Result<ControlFlow<(), usize>> {
|
||||
if is_output_dir_provided {
|
||||
unpack(unpack_fn, output_dir, question_policy)
|
||||
} else {
|
||||
smart_unpack(unpack_fn, output_dir, output_file_path, question_policy)
|
||||
if is_smart_unpack {
|
||||
return smart_unpack(unpack_fn, output_dir, output_file_path, question_policy);
|
||||
}
|
||||
|
||||
let target_output_dir = if is_output_dir_provided {
|
||||
output_dir
|
||||
} else {
|
||||
output_file_path
|
||||
};
|
||||
|
||||
unpack(unpack_fn, target_output_dir, question_policy)
|
||||
}
|
||||
|
||||
/// Unpacks an archive creating the output directory, this function will create the output_dir
|
||||
|
@ -148,6 +148,7 @@ pub fn run(
|
||||
files,
|
||||
output_dir,
|
||||
remove,
|
||||
no_smart_unpack,
|
||||
} => {
|
||||
let mut output_paths = vec![];
|
||||
let mut formats = vec![];
|
||||
@ -176,9 +177,11 @@ pub fn run(
|
||||
|
||||
check::check_missing_formats_when_decompressing(&files, &formats)?;
|
||||
|
||||
let is_output_dir_provided = output_dir.is_some();
|
||||
let is_smart_unpack = !is_output_dir_provided && !no_smart_unpack;
|
||||
|
||||
// The directory that will contain the output files
|
||||
// We default to the current directory if the user didn't specify an output directory with --dir
|
||||
let is_output_dir_provided = output_dir.is_some();
|
||||
let output_dir = if let Some(dir) = output_dir {
|
||||
utils::create_dir_if_non_existent(&dir)?;
|
||||
dir
|
||||
@ -200,9 +203,10 @@ pub fn run(
|
||||
decompress_file(DecompressOptions {
|
||||
input_file_path: input_path,
|
||||
formats,
|
||||
is_output_dir_provided,
|
||||
output_dir: &output_dir,
|
||||
output_file_path,
|
||||
is_output_dir_provided,
|
||||
is_smart_unpack,
|
||||
question_policy,
|
||||
quiet: args.quiet,
|
||||
password: args.password.as_deref().map(|str| {
|
||||
|
@ -367,6 +367,201 @@ fn multiple_files_with_conflict_and_choice_to_rename_with_already_a_renamed(
|
||||
assert_same_directory(src_files_path, dest_files_path_renamed.join("src_files"), false);
|
||||
}
|
||||
|
||||
#[proptest(cases = 25)]
|
||||
fn smart_unpack_with_single_file(
|
||||
ext: DirectoryExtension,
|
||||
#[any(size_range(0..1).lift())] extra_extensions: Vec<FileExtension>,
|
||||
) {
|
||||
let temp_dir = tempdir().unwrap();
|
||||
let root_path = temp_dir.path();
|
||||
|
||||
let src_files_path = root_path.join("src_files");
|
||||
fs::create_dir_all(&src_files_path).unwrap();
|
||||
|
||||
let files_path = ["file1.txt"]
|
||||
.into_iter()
|
||||
.map(|f| src_files_path.join(f))
|
||||
.inspect(|path| {
|
||||
let mut file = fs::File::create(path).unwrap();
|
||||
file.write_all("Some content".as_bytes()).unwrap();
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let archive = &root_path.join(format!("archive.{}", merge_extensions(&ext, extra_extensions)));
|
||||
|
||||
crate::utils::cargo_bin()
|
||||
.arg("compress")
|
||||
.args(files_path)
|
||||
.arg(archive)
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
let output_file = root_path.join("file1.txt");
|
||||
assert!(!output_file.exists());
|
||||
|
||||
// Decompress the archive with Smart Unpack
|
||||
crate::utils::cargo_bin()
|
||||
.current_dir(root_path)
|
||||
.arg("decompress")
|
||||
.arg(archive)
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
assert!(output_file.exists());
|
||||
|
||||
let output_content = fs::read_to_string(&output_file).unwrap();
|
||||
assert_eq!(output_content, "Some content");
|
||||
}
|
||||
|
||||
#[proptest(cases = 25)]
|
||||
fn smart_unpack_with_multiple_files(
|
||||
ext: DirectoryExtension,
|
||||
#[any(size_range(0..1).lift())] extra_extensions: Vec<FileExtension>,
|
||||
) {
|
||||
let temp_dir = tempdir().unwrap();
|
||||
let root_path = temp_dir.path();
|
||||
|
||||
let src_files_path = root_path.join("src_files");
|
||||
fs::create_dir_all(&src_files_path).unwrap();
|
||||
|
||||
["file1.txt", "file2.txt", "file3.txt", "file4.txt", "file5.txt"]
|
||||
.into_iter()
|
||||
.map(|f| src_files_path.join(f))
|
||||
.for_each(|path| {
|
||||
let mut file = fs::File::create(&path).unwrap();
|
||||
file.write_all("Some content".as_bytes()).unwrap();
|
||||
});
|
||||
|
||||
let input_files = src_files_path
|
||||
.read_dir()
|
||||
.unwrap()
|
||||
.map(|entry| entry.unwrap().path())
|
||||
.collect::<Vec<PathBuf>>();
|
||||
|
||||
let archive = &root_path.join(format!("archive.{}", merge_extensions(&ext, extra_extensions)));
|
||||
|
||||
let output_path = root_path.join("archive");
|
||||
assert!(!output_path.exists());
|
||||
|
||||
crate::utils::cargo_bin()
|
||||
.arg("compress")
|
||||
.args(input_files)
|
||||
.arg(archive)
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
crate::utils::cargo_bin()
|
||||
.current_dir(root_path)
|
||||
.arg("decompress")
|
||||
.arg(archive)
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
assert!(output_path.exists(), "Output directory does not exist");
|
||||
|
||||
assert_same_directory(src_files_path, output_path, false);
|
||||
}
|
||||
|
||||
#[proptest(cases = 25)]
|
||||
fn no_smart_unpack_with_single_file(
|
||||
ext: DirectoryExtension,
|
||||
#[any(size_range(0..1).lift())] extra_extensions: Vec<FileExtension>,
|
||||
) {
|
||||
let temp_dir = tempdir().unwrap();
|
||||
let root_path = temp_dir.path();
|
||||
|
||||
let src_files_path = root_path.join("src_files");
|
||||
fs::create_dir_all(&src_files_path).unwrap();
|
||||
|
||||
["file1.txt"]
|
||||
.into_iter()
|
||||
.map(|f| src_files_path.join(f))
|
||||
.for_each(|path| {
|
||||
let mut file = fs::File::create(&path).unwrap();
|
||||
file.write_all("Some content".as_bytes()).unwrap();
|
||||
});
|
||||
|
||||
let input_files = src_files_path
|
||||
.read_dir()
|
||||
.unwrap()
|
||||
.map(|entry| entry.unwrap().path())
|
||||
.collect::<Vec<PathBuf>>();
|
||||
|
||||
let archive = &root_path.join(format!("archive.{}", merge_extensions(&ext, extra_extensions)));
|
||||
|
||||
let output_path = root_path.join("archive");
|
||||
assert!(!output_path.exists());
|
||||
|
||||
crate::utils::cargo_bin()
|
||||
.arg("compress")
|
||||
.args(input_files)
|
||||
.arg(archive)
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
crate::utils::cargo_bin()
|
||||
.current_dir(root_path)
|
||||
.arg("decompress")
|
||||
.arg("--no-smart-unpack")
|
||||
.arg(archive)
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
assert!(output_path.exists(), "Output directory does not exist");
|
||||
|
||||
assert_same_directory(src_files_path, output_path, false);
|
||||
}
|
||||
|
||||
#[proptest(cases = 25)]
|
||||
fn no_smart_unpack_with_multiple_files(
|
||||
ext: DirectoryExtension,
|
||||
#[any(size_range(0..1).lift())] extra_extensions: Vec<FileExtension>,
|
||||
) {
|
||||
let temp_dir = tempdir().unwrap();
|
||||
let root_path = temp_dir.path();
|
||||
|
||||
let src_files_path = root_path.join("src_files");
|
||||
fs::create_dir_all(&src_files_path).unwrap();
|
||||
|
||||
["file1.txt", "file2.txt", "file3.txt", "file4.txt", "file5.txt"]
|
||||
.into_iter()
|
||||
.map(|f| src_files_path.join(f))
|
||||
.for_each(|path| {
|
||||
let mut file = fs::File::create(&path).unwrap();
|
||||
file.write_all("Some content".as_bytes()).unwrap();
|
||||
});
|
||||
|
||||
let input_files = src_files_path
|
||||
.read_dir()
|
||||
.unwrap()
|
||||
.map(|entry| entry.unwrap().path())
|
||||
.collect::<Vec<PathBuf>>();
|
||||
|
||||
let archive = &root_path.join(format!("archive.{}", merge_extensions(&ext, extra_extensions)));
|
||||
|
||||
let output_path = root_path.join("archive");
|
||||
assert!(!output_path.exists());
|
||||
|
||||
crate::utils::cargo_bin()
|
||||
.arg("compress")
|
||||
.args(input_files)
|
||||
.arg(archive)
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
crate::utils::cargo_bin()
|
||||
.current_dir(root_path)
|
||||
.arg("decompress")
|
||||
.arg("--no-smart-unpack")
|
||||
.arg(archive)
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
assert!(output_path.exists(), "Output directory does not exist");
|
||||
|
||||
assert_same_directory(src_files_path, output_path, false);
|
||||
}
|
||||
|
||||
#[proptest(cases = 25)]
|
||||
fn multiple_files_with_disabled_smart_unpack_by_dir(
|
||||
ext: DirectoryExtension,
|
||||
@ -490,10 +685,9 @@ fn symlink_pack_and_unpack(
|
||||
let mut files_path = ["file1.txt", "file2.txt", "file3.txt", "file4.txt", "file5.txt"]
|
||||
.into_iter()
|
||||
.map(|f| src_files_path.join(f))
|
||||
.map(|path| {
|
||||
let mut file = fs::File::create(&path).unwrap();
|
||||
.inspect(|path| {
|
||||
let mut file = fs::File::create(path).unwrap();
|
||||
file.write_all("Some content".as_bytes()).unwrap();
|
||||
path
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user