Write decompressed stdin to stdin-output.

This commit is contained in:
Ryan Roden-Corrent 2024-07-31 06:37:29 -04:00 committed by João Marcos
parent 77c1a4e9db
commit a7fe78fc68
4 changed files with 36 additions and 27 deletions

View File

@ -253,28 +253,25 @@ fn smart_unpack(
let files = unpack_fn(temp_dir_path)?; let files = unpack_fn(temp_dir_path)?;
let root_contains_only_one_element = fs::read_dir(temp_dir_path)?.count() == 1; 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 // 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 file = fs::read_dir(temp_dir_path)?.next().expect("item exists")?;
let files = fs::read_dir(temp_dir_path)?; let file_path = file.path();
for file in files { let file_name = file_path
let file_path = file?.path(); .file_name()
let file_name = file_path .expect("Should be safe because paths in archives should not end with '..'");
.file_name() let correct_path = output_dir.join(file_name);
.expect("Should be safe because paths in archives should not end with '..'"); // Before moving, need to check if a file with the same name already exists
let correct_path = output_dir.join(file_name); if !utils::clear_path(&correct_path, question_policy)? {
// Before moving, need to check if a file with the same name already exists return Ok(ControlFlow::Break(()));
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)
));
} }
fs::rename(&file_path, &correct_path)?;
info_accessible(format!(
"Successfully moved {} to {}.",
nice_directory_display(&file_path),
nice_directory_display(&correct_path)
));
} else { } else {
// Multiple files in the root directory, so: // Multiple files in the root directory, so:
// Rename the temporary directory to the archive name, which is output_file_path // Rename the temporary directory to the archive name, which is output_file_path

View File

@ -16,7 +16,9 @@ use crate::{
error::{Error, FinalError}, error::{Error, FinalError},
extension::{self, parse_format}, extension::{self, parse_format},
list::ListOptions, 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, CliArgs, QuestionPolicy,
}; };
@ -173,7 +175,12 @@ pub fn run(
.zip(formats) .zip(formats)
.zip(output_paths) .zip(output_paths)
.try_for_each(|((input_path, formats), file_name)| { .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( decompress_file(
input_path, input_path,
formats, formats,

View File

@ -144,7 +144,7 @@ fn single_file_stdin(
let before = &dir.join("before"); let before = &dir.join("before");
fs::create_dir(before).unwrap(); fs::create_dir(before).unwrap();
let before_file = &before.join("file"); 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 archive = &dir.join(format!("file.{}", format));
let after = &dir.join("after"); let after = &dir.join("after");
write_random_content( write_random_content(
@ -162,6 +162,14 @@ fn single_file_stdin(
.unwrap() .unwrap()
.assert() .assert()
.success(); .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); assert_same_directory(before, after, false);
} }

View File

@ -73,10 +73,7 @@ pub fn assert_same_directory(x: impl Into<PathBuf>, y: impl Into<PathBuf>, prese
loop { loop {
match (x.next(), y.next()) { match (x.next(), y.next()) {
(Some(x), Some(y)) => { (Some(x), Some(y)) => {
// If decompressing from stdin, the file name will be "-". assert_eq!(x.file_name(), y.file_name());
if x.file_name() != "-" && y.file_name() != "-" {
assert_eq!(x.file_name(), y.file_name());
}
let meta_x = x.metadata().unwrap(); let meta_x = x.metadata().unwrap();
let meta_y = y.metadata().unwrap(); let meta_y = y.metadata().unwrap();