116 lines
3.6 KiB
Rust
116 lines
3.6 KiB
Rust
use crate::tmpfs::TempDir;
|
|
use errors::{BinError, BuildError, InstallError};
|
|
use log::{debug, error, info, trace};
|
|
use manifest::Manifest;
|
|
use pkgfile::PKGFile;
|
|
use std::fmt::Display;
|
|
use std::process::exit;
|
|
use crate::CONFIG;
|
|
use crate::package::identifier::{PackageIdentifier, PackageLocator};
|
|
use crate::package::Package;
|
|
|
|
pub mod errors;
|
|
|
|
#[derive(Debug)]
|
|
pub enum InstallType {
|
|
Build,
|
|
Bin,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct PackageInstaller {
|
|
manifest: Manifest,
|
|
pkgfile: PKGFile,
|
|
install_type: InstallType,
|
|
}
|
|
|
|
impl PackageInstaller {
|
|
pub fn new(m: Manifest, p: PKGFile, i: InstallType) -> PackageInstaller {
|
|
PackageInstaller {
|
|
manifest: m,
|
|
pkgfile: p,
|
|
install_type: i,
|
|
}
|
|
}
|
|
|
|
fn extract_to(&self, path: String) -> Result<(), BinError> {
|
|
if !self.pkgfile.has_data() {
|
|
return Err(BinError::UnpackError("package has no data".to_string()));
|
|
}
|
|
if std::path::Path::new(&path).exists() {
|
|
return Err(BinError::UnpackError("path already exists".to_string()));
|
|
}
|
|
tar::Archive::new(self.pkgfile.data.as_slice())
|
|
.unpack(&path)
|
|
.map_err(|e| BinError::UnpackError(e.to_string()))
|
|
}
|
|
|
|
fn bin(&self) -> Result<(), BinError> {
|
|
let mut tmpdir = TempDir::default();
|
|
tmpdir.push(&self.manifest.package.name);
|
|
trace!("extracting package into: {}", tmpdir.to_string());
|
|
match self.extract_to(tmpdir.to_string()) {
|
|
Ok(_) => {}
|
|
Err(e) => return Err(e),
|
|
}
|
|
debug!("extracted package in: {}", tmpdir.to_string());
|
|
Ok(())
|
|
}
|
|
|
|
fn build(&self) -> Result<(), BuildError> {
|
|
if let None = self.manifest.build.clone() {
|
|
return Err(BuildError::InvalidManifest);
|
|
}
|
|
let build_manifest = self.manifest.build.clone().unwrap();
|
|
// TODO: Check dependencies
|
|
for pkg_tuple in build_manifest.dependencies {
|
|
let mut pkg = Package::fetch(
|
|
PackageIdentifier::PackageLocator(
|
|
PackageLocator::from(pkg_tuple)
|
|
)
|
|
).expect("no pkg");
|
|
|
|
if !pkg.is_installed() {
|
|
match pkg.install(CONFIG.with(|c| {
|
|
c.build_by_default
|
|
})) {
|
|
Ok(_) => { info!("Installed dependency: \"{}\"", pkg.manifest().package.name) },
|
|
Err(_) => {
|
|
error!("Could not install dependency: \"{}\"", pkg.identifier);
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn install(&mut self) -> Result<(), InstallError> {
|
|
match self.install_type {
|
|
InstallType::Bin => {
|
|
if let None = self.manifest.bin {
|
|
self.install_type = InstallType::Build;
|
|
if let None = self.manifest.build {
|
|
return Err(InstallError::InvalidManifest);
|
|
}
|
|
}
|
|
}
|
|
InstallType::Build => {
|
|
if let None = self.manifest.build {
|
|
self.install_type = InstallType::Bin;
|
|
if let None = self.manifest.bin {
|
|
return Err(InstallError::InvalidManifest);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
match self.install_type {
|
|
InstallType::Bin => self.bin()
|
|
.map_err(|e| InstallError::BinError(e)),
|
|
InstallType::Build => self.build()
|
|
.map_err(|e| InstallError::BuildError(e)),
|
|
}
|
|
}
|
|
}
|