1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use std::{path::Path, process::Command};
use anyhow::Result;
use super::Extractor;
pub struct TarExtractor;
impl Extractor for TarExtractor {
fn file_extensions(&self) -> Vec<&'static str> {
vec![
"tar", "tar.gz", "tgz", "tar.bz2", "tbz2", "tar.xz", "txz", "tar.zst",
]
}
fn binary_names(&self) -> Vec<&'static str> {
vec!["unar", "tar", "gtar", "bsdtar"]
}
fn build_command(
&self,
binary: &Path,
file: &Path,
output_dir: &Path,
verbose: bool,
) -> Result<Command> {
let mut cmd = Command::new(binary);
match binary.file_name().unwrap().to_str().unwrap() {
"unar" => {
cmd.arg("-o").arg(output_dir).arg(file);
if !verbose {
cmd.arg("-q");
}
}
_ => {
cmd.arg("-xf").arg(file).arg("-C").arg(output_dir);
if verbose {
cmd.arg("-v");
}
// Add compression flag based on file extension
if let Some(ext) = file.extension() {
match ext.to_str().unwrap_or("") {
"gz" | "tgz" => {
cmd.arg("-z");
}
"bz2" | "tbz2" => {
cmd.arg("-j");
}
"xz" | "txz" => {
cmd.arg("-J");
}
"zst" => {
cmd.arg("--zstd");
}
"" => {}
_ => {
anyhow::bail!(
"Unsupported tar extension tar.{}",
ext.to_string_lossy()
);
}
};
}
}
}
Ok(cmd)
}
}