From a7fe78fc68b1907bf513fe73317953044a94a3c2 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Wed, 31 Jul 2024 06:37:29 -0400 Subject: [PATCH] Write decompressed stdin to stdin-output. --- src/commands/decompress.rs | 37 +++++++++++++++++-------------------- src/commands/mod.rs | 11 +++++++++-- tests/integration.rs | 10 +++++++++- tests/utils.rs | 5 +---- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/commands/decompress.rs b/src/commands/decompress.rs index 5d4e8c7..267a585 100644 --- a/src/commands/decompress.rs +++ b/src/commands/decompress.rs @@ -253,28 +253,25 @@ fn smart_unpack( let files = unpack_fn(temp_dir_path)?; let root_contains_only_one_element = fs::read_dir(temp_dir_path)?.count() == 1; - if is_path_stdin(output_file_path) || root_contains_only_one_element { + if root_contains_only_one_element { // Only one file in the root directory, so we can just move it to the output directory - // If we're decompressing an archive from stdin, we can also put the files directly in the output directory. - let files = fs::read_dir(temp_dir_path)?; - for file in files { - let file_path = file?.path(); - let file_name = file_path - .file_name() - .expect("Should be safe because paths in archives should not end with '..'"); - let correct_path = output_dir.join(file_name); - // Before moving, need to check if a file with the same name already exists - if !utils::clear_path(&correct_path, question_policy)? { - return Ok(ControlFlow::Break(())); - } - fs::rename(&file_path, &correct_path)?; - - info_accessible(format!( - "Successfully moved {} to {}.", - nice_directory_display(&file_path), - nice_directory_display(&correct_path) - )); + let file = fs::read_dir(temp_dir_path)?.next().expect("item exists")?; + let file_path = file.path(); + let file_name = file_path + .file_name() + .expect("Should be safe because paths in archives should not end with '..'"); + let correct_path = output_dir.join(file_name); + // Before moving, need to check if a file with the same name already exists + if !utils::clear_path(&correct_path, question_policy)? { + return Ok(ControlFlow::Break(())); } + fs::rename(&file_path, &correct_path)?; + + info_accessible(format!( + "Successfully moved {} to {}.", + nice_directory_display(&file_path), + nice_directory_display(&correct_path) + )); } else { // Multiple files in the root directory, so: // Rename the temporary directory to the archive name, which is output_file_path diff --git a/src/commands/mod.rs b/src/commands/mod.rs index a868f4d..6e5e9db 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -16,7 +16,9 @@ use crate::{ error::{Error, FinalError}, extension::{self, parse_format}, list::ListOptions, - utils::{self, colors::*, logger::info_accessible, to_utf, EscapedPathDisplay, FileVisibilityPolicy}, + utils::{ + self, colors::*, is_path_stdin, logger::info_accessible, to_utf, EscapedPathDisplay, FileVisibilityPolicy, + }, CliArgs, QuestionPolicy, }; @@ -173,7 +175,12 @@ pub fn run( .zip(formats) .zip(output_paths) .try_for_each(|((input_path, formats), file_name)| { - let output_file_path = output_dir.join(file_name); // Path used by single file format archives + // Path used by single file format archives + let output_file_path = if is_path_stdin(file_name) { + output_dir.join("stdin-output") + } else { + output_dir.join(file_name) + }; decompress_file( input_path, formats, diff --git a/tests/integration.rs b/tests/integration.rs index 04adc55..3801465 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -144,7 +144,7 @@ fn single_file_stdin( let before = &dir.join("before"); fs::create_dir(before).unwrap(); let before_file = &before.join("file"); - let format = merge_extensions(ext, exts); + let format = merge_extensions(&ext, exts); let archive = &dir.join(format!("file.{}", format)); let after = &dir.join("after"); write_random_content( @@ -162,6 +162,14 @@ fn single_file_stdin( .unwrap() .assert() .success(); + + match ext { + Extension::Directory(_) => {} + // We don't know the original filename, so we create a file named stdin-output + // Change the top-level "before" directory to match + Extension::File(_) => fs::rename(before_file, before_file.with_file_name("stdin-output")).unwrap(), + }; + assert_same_directory(before, after, false); } diff --git a/tests/utils.rs b/tests/utils.rs index 4ad40d0..bd5fc34 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -73,10 +73,7 @@ pub fn assert_same_directory(x: impl Into, y: impl Into, prese loop { match (x.next(), y.next()) { (Some(x), Some(y)) => { - // If decompressing from stdin, the file name will be "-". - if x.file_name() != "-" && y.file_name() != "-" { - assert_eq!(x.file_name(), y.file_name()); - } + assert_eq!(x.file_name(), y.file_name()); let meta_x = x.metadata().unwrap(); let meta_y = y.metadata().unwrap();