mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-05 02:55:31 +00:00
Improve hints when decompressing with no extension
refactored `check_missing_formats_when_decompressing` to be aware of missing extensions and unsupported extensions in order to give a more detailed error message
This commit is contained in:
parent
bc1d9457f0
commit
a26d3d34ce
55
src/check.rs
55
src/check.rs
@ -10,7 +10,7 @@ use std::{
|
||||
|
||||
use crate::{
|
||||
error::FinalError,
|
||||
extension::{build_archive_file_suggestion, Extension},
|
||||
extension::{build_archive_file_suggestion, Extension, PRETTY_SUPPORTED_ALIASES, PRETTY_SUPPORTED_EXTENSIONS},
|
||||
info,
|
||||
utils::{pretty_format_list_of_paths, try_infer_extension, user_wants_to_continue, EscapedPathDisplay},
|
||||
warning, QuestionAction, QuestionPolicy, Result,
|
||||
@ -127,32 +127,55 @@ pub fn check_archive_formats_position(formats: &[Extension], output_path: &Path)
|
||||
|
||||
/// Check if all provided files have formats to decompress.
|
||||
pub fn check_missing_formats_when_decompressing(files: &[PathBuf], formats: &[Vec<Extension>]) -> Result<()> {
|
||||
let files_missing_format: Vec<PathBuf> = files
|
||||
let files_with_broken_extension: Vec<&PathBuf> = files
|
||||
.iter()
|
||||
.zip(formats)
|
||||
.filter(|(_, format)| format.is_empty())
|
||||
.map(|(input_path, _)| PathBuf::from(input_path))
|
||||
.map(|(input_path, _)| input_path)
|
||||
.collect();
|
||||
|
||||
if let Some(path) = files_missing_format.first() {
|
||||
let error = FinalError::with_title("Cannot decompress files without extensions")
|
||||
.detail(format!(
|
||||
"Files without supported extensions: {}",
|
||||
pretty_format_list_of_paths(&files_missing_format)
|
||||
))
|
||||
.detail("Decompression formats are detected automatically by the file extension")
|
||||
.hint("Provide a file with a supported extension:")
|
||||
.hint(" ouch decompress example.tar.gz")
|
||||
if files_with_broken_extension.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let (files_with_unsupported_extensions, files_missing_extension): (Vec<&PathBuf>, Vec<&PathBuf>) =
|
||||
files_with_broken_extension
|
||||
.iter()
|
||||
.partition(|path| path.extension().is_some());
|
||||
|
||||
let mut error = FinalError::with_title("Cannot decompress files");
|
||||
|
||||
if !files_with_unsupported_extensions.is_empty() {
|
||||
error = error.detail(format!(
|
||||
"Files with unsupported extensions: {}",
|
||||
pretty_format_list_of_paths(&files_with_unsupported_extensions)
|
||||
));
|
||||
}
|
||||
|
||||
if !files_missing_extension.is_empty() {
|
||||
error = error.detail(format!(
|
||||
"Files with missing extensions: {}",
|
||||
pretty_format_list_of_paths(&files_missing_extension)
|
||||
));
|
||||
}
|
||||
|
||||
error = error
|
||||
.detail("Decompression formats are detected automatically from file extension")
|
||||
.hint(format!("Supported extensions are: {}", PRETTY_SUPPORTED_EXTENSIONS))
|
||||
.hint(format!("Supported aliases are: {}", PRETTY_SUPPORTED_ALIASES));
|
||||
|
||||
// If there's exactly one file, give a suggestion to use `--format`
|
||||
if let &[path] = files_with_broken_extension.as_slice() {
|
||||
error = error
|
||||
.hint("")
|
||||
.hint("Or overwrite this option with the '--format' flag:")
|
||||
.hint("Alternatively, you can pass an extension to the '--format' flag:")
|
||||
.hint(format!(
|
||||
" ouch decompress {} --format tar.gz",
|
||||
EscapedPathDisplay::new(path),
|
||||
));
|
||||
|
||||
return Err(error.into());
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Err(error.into())
|
||||
}
|
||||
|
||||
/// Check if there is a first format when compressing, and returns it.
|
||||
|
@ -7,6 +7,11 @@ use bstr::ByteSlice;
|
||||
use self::CompressionFormat::*;
|
||||
use crate::{error::Error, warning};
|
||||
|
||||
pub const SUPPORTED_EXTENSIONS: &[&str] = &["tar", "zip", "bz", "bz2", "gz", "lz4", "xz", "lzma", "sz", "zst"];
|
||||
pub const SUPPORTED_ALIASES: &[&str] = &["tgz", "tbz", "tlz4", "txz", "tzlma", "tsz", "tzst"];
|
||||
pub const PRETTY_SUPPORTED_EXTENSIONS: &str = "tar, zip, bz, bz2, gz, lz4, xz, lzma, sz, zst";
|
||||
pub const PRETTY_SUPPORTED_ALIASES: &str = "tgz, tbz, tlz4, txz, tzlma, tsz, tzst";
|
||||
|
||||
/// A wrapper around `CompressionFormat` that allows combinations like `tgz`
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
#[non_exhaustive]
|
||||
@ -85,11 +90,6 @@ impl CompressionFormat {
|
||||
}
|
||||
}
|
||||
|
||||
pub const SUPPORTED_EXTENSIONS: &[&str] = &[
|
||||
"tar", "tgz", "tbz", "tlz4", "txz", "tzlma", "tsz", "tzst", "zip", "bz", "bz2", "gz", "lz4", "xz", "lzma", "sz",
|
||||
"zst",
|
||||
];
|
||||
|
||||
fn to_extension(ext: &[u8]) -> Option<Extension> {
|
||||
Some(Extension::new(
|
||||
match ext {
|
||||
@ -156,7 +156,7 @@ pub fn separate_known_extensions_from_name(path: &Path) -> (&Path, Vec<Extension
|
||||
|
||||
if let Ok(name) = name.to_str() {
|
||||
let file_stem = name.trim_matches('.');
|
||||
if SUPPORTED_EXTENSIONS.contains(&file_stem) {
|
||||
if SUPPORTED_EXTENSIONS.contains(&file_stem) || SUPPORTED_ALIASES.contains(&file_stem) {
|
||||
warning!("Received a file with name '{file_stem}', but {file_stem} was expected as the extension.");
|
||||
}
|
||||
}
|
||||
@ -208,7 +208,7 @@ pub fn build_archive_file_suggestion(path: &Path, suggested_extension: &str) ->
|
||||
|
||||
// If the extension we got is a supported extension, generate the suggestion
|
||||
// at the position we found
|
||||
if SUPPORTED_EXTENSIONS.contains(&maybe_extension) {
|
||||
if SUPPORTED_EXTENSIONS.contains(&maybe_extension) || SUPPORTED_ALIASES.contains(&maybe_extension) {
|
||||
let mut path = path.to_string();
|
||||
path.insert_str(position_to_insert - 1, suggested_extension);
|
||||
|
||||
@ -227,7 +227,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_extensions_from_path() {
|
||||
use CompressionFormat::*;
|
||||
let path = Path::new("bolovo.tar.gz");
|
||||
|
||||
let extensions: Vec<Extension> = extensions_from_path(path);
|
||||
|
@ -0,0 +1,12 @@
|
||||
---
|
||||
source: tests/ui.rs
|
||||
expression: "run_ouch(\"ouch decompress a b.unknown\", dir)"
|
||||
---
|
||||
[ERROR] Cannot decompress files
|
||||
- Files with unsupported extensions: <FOLDER>/b.unknown
|
||||
- Files with missing extensions: <FOLDER>/a
|
||||
- Decompression formats are detected automatically from file extension
|
||||
|
||||
hint: Supported extensions are: tar, zip, bz, bz2, gz, lz4, xz, lzma, sz, zst
|
||||
hint: Supported aliases are: tgz, tbz, tlz4, txz, tzlma, tsz, tzst
|
||||
|
@ -0,0 +1,14 @@
|
||||
---
|
||||
source: tests/ui.rs
|
||||
expression: "run_ouch(\"ouch decompress b.unknown\", dir)"
|
||||
---
|
||||
[ERROR] Cannot decompress files
|
||||
- Files with unsupported extensions: <FOLDER>/b.unknown
|
||||
- Decompression formats are detected automatically from file extension
|
||||
|
||||
hint: Supported extensions are: tar, zip, bz, bz2, gz, lz4, xz, lzma, sz, zst
|
||||
hint: Supported aliases are: tgz, tbz, tlz4, txz, tzlma, tsz, tzst
|
||||
hint:
|
||||
hint: Alternatively, you can pass an extension to the '--format' flag:
|
||||
hint: ouch decompress <FOLDER>/b.unknown --format tar.gz
|
||||
|
@ -2,13 +2,13 @@
|
||||
source: tests/ui.rs
|
||||
expression: "run_ouch(\"ouch decompress a\", dir)"
|
||||
---
|
||||
[ERROR] Cannot decompress files without extensions
|
||||
- Files without supported extensions: <FOLDER>/a
|
||||
- Decompression formats are detected automatically by the file extension
|
||||
[ERROR] Cannot decompress files
|
||||
- Files with missing extensions: <FOLDER>/a
|
||||
- Decompression formats are detected automatically from file extension
|
||||
|
||||
hint: Provide a file with a supported extension:
|
||||
hint: ouch decompress example.tar.gz
|
||||
hint: Supported extensions are: tar, zip, bz, bz2, gz, lz4, xz, lzma, sz, zst
|
||||
hint: Supported aliases are: tgz, tbz, tlz4, txz, tzlma, tsz, tzst
|
||||
hint:
|
||||
hint: Or overwrite this option with the '--format' flag:
|
||||
hint: Alternatively, you can pass an extension to the '--format' flag:
|
||||
hint: ouch decompress <FOLDER>/a --format tar.gz
|
||||
|
||||
|
@ -71,9 +71,11 @@ fn ui_test_err_compress_missing_extension() {
|
||||
fn ui_test_err_decompress_missing_extension() {
|
||||
let (_dropper, dir) = testdir().unwrap();
|
||||
|
||||
run_in(dir, "touch", "a").unwrap();
|
||||
run_in(dir, "touch", "a b.unknown").unwrap();
|
||||
|
||||
ui!(run_ouch("ouch decompress a", dir));
|
||||
ui!(run_ouch("ouch decompress a b.unknown", dir));
|
||||
ui!(run_ouch("ouch decompress b.unknown", dir));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
x
Reference in New Issue
Block a user