huber 1.0.11

Huber, simplify GitHub package management
Documentation
use std::fs::File;
use std::io;
use std::io::BufReader;
use std::path::Path;

use flate2::read::GzDecoder;
use tar::Archive;
use xz2::read::XzDecoder;
use zip::ZipArchive;

use crate::fs::set_executable_permission;

pub fn uncompress_archive(file: &Path, extract_dir: &Path, ext: &str) -> anyhow::Result<()> {
    match ext {
        "zip" => {
            unzip(file, extract_dir)?;
        }
        "tar" => {
            untar(file, extract_dir)?;
        }
        "tar.gz" | "tgz" => {
            untar_gz(file, extract_dir)?;
        }
        "tar.xz" => {
            untar_xz(file, extract_dir)?;
        }
        "gz" => {
            ungz(file, extract_dir)?;
        }
        _ => {
            return Err(anyhow::anyhow!("Unsupported archive format: {}", ext));
        }
    }

    Ok(())
}

fn untar_xz(file: &Path, extract_dir: &Path) -> anyhow::Result<()> {
    let tar_xz = File::open(file)?;
    let tar = XzDecoder::new(BufReader::new(tar_xz));
    let mut archive = Archive::new(tar);

    Ok(archive.unpack(extract_dir)?)
}

fn untar_gz(file: &Path, extract_dir: &Path) -> anyhow::Result<()> {
    let tar_gz = File::open(file)?;
    let tar = GzDecoder::new(BufReader::new(tar_gz));
    let mut archive = Archive::new(tar);

    Ok(archive.unpack(extract_dir)?)
}

fn untar(file: &Path, extract_dir: &Path) -> anyhow::Result<()> {
    let tar_file = File::open(file)?;
    let tar = BufReader::new(tar_file);
    let mut archive = Archive::new(tar);

    Ok(archive.unpack(extract_dir)?)
}

fn unzip(file: &Path, extract_dir: &Path) -> anyhow::Result<()> {
    let file = File::open(file)?;

    let mut reader = ZipArchive::new(BufReader::new(file))?;
    reader.extract(extract_dir)?;

    Ok(())
}

fn ungz(file: &Path, extract_dir: &Path) -> anyhow::Result<()> {
    let gz = File::open(file)?;
    let mut gz = GzDecoder::new(BufReader::new(gz));

    let outfile_path = extract_dir.join(
        file.file_name()
            .unwrap_or_default()
            .to_string_lossy()
            .replace(".gz", ""),
    );
    let mut out_file = File::create(&outfile_path)?;
    io::copy(&mut gz, &mut out_file)?;
    set_executable_permission(&outfile_path)?;

    Ok(())
}