use std::{fs::File, path::Path};
use anyhow::{Context, Result};
use flate2::read::{GzDecoder, ZlibDecoder};
use tar::Archive;
use crate::common::{is_in_path, path_to_string, BSDTAR, SEVENZ};
use crate::io::{execute_and_output, execute_without_output};
use crate::{log_info, log_line};
pub fn decompress_zip(source: &Path) -> Result<()> {
let file = File::open(source)?;
let mut zip = zip::ZipArchive::new(file)?;
let parent = source
.parent()
.context("decompress: source should have a parent")?;
zip.extract(parent)?;
Ok(())
}
pub fn decompress_gz(source: &Path) -> Result<()> {
let tar_gz = File::open(source)?;
let tar = GzDecoder::new(tar_gz);
let mut archive = Archive::new(tar);
let parent = source
.parent()
.context("decompress: source should have a parent")?;
archive.unpack(parent)?;
Ok(())
}
pub fn decompress_7z(source: &Path) -> Result<()> {
if !is_in_path(SEVENZ) {
log_info!(
"Can't decompress {source} without {SEVENZ} executable",
source = source.display()
);
log_line!(
"Can't decompress {source} without {SEVENZ} executable",
source = source.display()
);
return Ok(());
}
let parent = source
.parent()
.context("decompress: source should have a parent")?;
let args = &[
"x",
&path_to_string(&source),
&format!("-o{parent}", parent = parent.display()),
"-y",
"-bd",
];
let _ = execute_without_output(SEVENZ, args);
Ok(())
}
pub fn decompress_xz(source: &Path) -> Result<()> {
let tar_xz = File::open(source)?;
let tar = ZlibDecoder::new(tar_xz);
let mut archive = Archive::new(tar);
let parent = source
.parent()
.context("decompress: source should have a parent")?;
archive.unpack(parent)?;
Ok(())
}
pub fn list_files_zip<P>(source: P) -> Result<Vec<String>>
where
P: AsRef<Path>,
{
let file = File::open(source)?;
let zip = zip::ZipArchive::new(file)?;
Ok(zip
.file_names()
.map(std::borrow::ToOwned::to_owned)
.collect())
}
pub fn list_files_tar<P>(source: P) -> Result<Vec<String>>
where
P: AsRef<Path>,
{
if let Ok(output) = execute_and_output(
BSDTAR,
["-v", "--list", "--file", path_to_string(&source).as_str()],
) {
let output = String::from_utf8(output.stdout).unwrap_or_default();
let content = output.lines().map(std::borrow::ToOwned::to_owned).collect();
return Ok(content);
}
Err(anyhow::anyhow!("Tar couldn't read the file content"))
}