mod tar_impl;
use crate::{
error::Result,
tar::tar_impl::{ Tar, TarImpl }
};
use std::{
fs,
path::{ Path, PathBuf }
};
pub struct Tarball {
archive: PathBuf
}
impl Tarball {
pub fn new<T>(path: T) -> Result<Self> where T: Into<PathBuf> {
let path = path.into();
if !path.is_file() {
Err(eio!("No such archive: {:?}", path))?;
}
Ok(Self { archive: path.to_path_buf() })
}
pub fn extract<T>(&self, working_dir: T) -> Result where T: AsRef<Path> {
let working_dir = working_dir.as_ref();
if !working_dir.is_dir() {
Err(eio!("The target directory does not exist: {:?}", working_dir))?;
}
let tar = TarImpl::new()?;
tar.extract(&self.archive, working_dir)
}
pub fn package_dir<T>(&self, working_dir: T) -> Result<PathBuf> where T: AsRef<Path> {
let working_dir = working_dir.as_ref();
if Self::is_package_dir(working_dir) {
Ok(working_dir.to_path_buf())
} else {
for entry in fs::read_dir(working_dir)? {
let entry = entry?;
let entry_path = entry.path();
let is_valid = entry_path.is_dir()
&& !entry.file_name().to_string_lossy().starts_with(".")
&& Self::is_package_dir(&entry_path);
if is_valid {
return Ok(entry_path)
}
}
Err(einval!(r#"Archive is not a valid ezinstall package (missing "install.sh" or "uninstall.sh")"#))
}
}
fn is_package_dir<T>(dir: T) -> bool where T: AsRef<Path> {
let dir = dir.as_ref();
dir.join("install.sh").is_file() && dir.join("uninstall.sh").is_file()
}
}