feat: added command functionality to install
This commit is contained in:
parent
3a21d12c07
commit
092c616ca4
20 changed files with 464 additions and 76 deletions
71
pkgr/src/package/builder/mod.rs
Normal file
71
pkgr/src/package/builder/mod.rs
Normal file
|
@ -0,0 +1,71 @@
|
|||
use libc::fork;
|
||||
use log::{debug, trace};
|
||||
use manifest::Manifest;
|
||||
use pkgfile::PKGFile;
|
||||
use crate::tmp::TempDir;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum InstallType {
|
||||
Build,
|
||||
Bin
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum InstallError {
|
||||
BuildError(String),
|
||||
BinError(String),
|
||||
InstallError
|
||||
}
|
||||
|
||||
impl ToString for InstallError {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
InstallError::BuildError(e) => format!("Build error: {}", e),
|
||||
InstallError::BinError(e) => format!("Bin error: {}", e),
|
||||
InstallError::InstallError => "Install error".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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<S: Into<String>>(&self, path: S) -> Result<(), String> {
|
||||
tar::Archive::new(self.pkgfile.data.as_slice())
|
||||
.unpack(path.into())
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
fn bin(&self) -> Result<(), String> {
|
||||
let mut tmpdir = TempDir::default();
|
||||
tmpdir.push(&self.manifest.package.name);
|
||||
trace!("extracting package into: {}", tmpdir.to_string());
|
||||
self.extract_to(tmpdir.to_string())?;
|
||||
debug!("extracted package in: {}", tmpdir.to_string());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build(&self) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn install(&self) -> Result<(), InstallError> {
|
||||
match self.install_type {
|
||||
InstallType::Bin => self.bin().map_err(|e| InstallError::BinError(e)),
|
||||
InstallType::Build => self.build().map_err(|e| InstallError::BuildError(e))
|
||||
}
|
||||
}
|
||||
}
|
59
pkgr/src/package/fetch.rs
Normal file
59
pkgr/src/package/fetch.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::Display;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use log::warn;
|
||||
use pkgfile::PKGFile;
|
||||
use crate::package::identifier::PackageIdentifier;
|
||||
use reqwest::blocking::get;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FetchError {
|
||||
HTTPError(reqwest::Error),
|
||||
IOError(std::io::Error),
|
||||
ParseError,
|
||||
}
|
||||
|
||||
impl Display for FetchError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
FetchError::HTTPError(e) => write!(f, "HTTP Error: {}", e),
|
||||
FetchError::IOError(e) => write!(f, "IO Error: {}", e),
|
||||
FetchError::ParseError => write!(f, "Parse Error"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for FetchError {}
|
||||
|
||||
pub fn fetch_package(package_identifier: PackageIdentifier) -> Result<PKGFile, FetchError> {
|
||||
match package_identifier {
|
||||
PackageIdentifier::Path(path) => {
|
||||
std::fs::read(path)
|
||||
.map_err(|e| FetchError::IOError(e)).and_then(|bytes| {
|
||||
PKGFile::try_from(bytes).map_err(|_| FetchError::ParseError)
|
||||
})
|
||||
}
|
||||
PackageIdentifier::URI(uri) => {
|
||||
// get file contents as bytes
|
||||
let mut bytes = Vec::new();
|
||||
match get(&uri) {
|
||||
Ok(mut response) => {
|
||||
match response.take(1024 * 1024).read_to_end(&mut bytes) {
|
||||
Ok(_) => (),
|
||||
Err(e) => return Err(FetchError::IOError(e)),
|
||||
};
|
||||
}
|
||||
Err(e) => return Err(FetchError::HTTPError(e)),
|
||||
};
|
||||
// parse bytes as PKGFile
|
||||
match PKGFile::try_from(bytes) {
|
||||
Ok(pkgfile) => Ok(pkgfile),
|
||||
Err(e) => Err(FetchError::ParseError),
|
||||
}
|
||||
}
|
||||
PackageIdentifier::PackageLocator(package_locator) => {
|
||||
Ok(PKGFile::default())
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ impl Error for PackageIdentifierError {}
|
|||
pub enum PackageIdentifier {
|
||||
PackageLocator(PackageLocator),
|
||||
URI(String),
|
||||
Path(String),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PackageIdentifier {
|
||||
|
@ -33,6 +34,7 @@ impl std::fmt::Display for PackageIdentifier {
|
|||
match self {
|
||||
PackageIdentifier::PackageLocator(pl) => write!(f, "{}", pl),
|
||||
PackageIdentifier::URI(uri) => write!(f, "{}", uri),
|
||||
PackageIdentifier::Path(path) => write!(f, "{}", path),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +63,7 @@ impl FromStr for PackageIdentifier {
|
|||
type Err = PackageIdentifierError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let uri_re = regex::Regex::new(r"^[a-zA-Z0-9]+://").unwrap();
|
||||
let uri_re = Regex::new(r"^[a-zA-Z0-9]+://").unwrap();
|
||||
if uri_re.is_match(s) {
|
||||
// there needs to be stuff after the protocol
|
||||
let split = s.split("://").collect::<Vec<&str>>();
|
||||
|
@ -69,6 +71,8 @@ impl FromStr for PackageIdentifier {
|
|||
return Err(PackageIdentifierError::InvalidURI(s.to_string()));
|
||||
}
|
||||
Ok(PackageIdentifier::URI(s.to_string()))
|
||||
} else if std::path::Path::new(s).exists() {
|
||||
return Ok(PackageIdentifier::Path(s.to_string()));
|
||||
} else {
|
||||
let pl = match PackageLocator::from_str(s) {
|
||||
Ok(pl) => pl,
|
||||
|
@ -84,7 +88,7 @@ impl FromStr for PackageLocator {
|
|||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
#[allow(unused_assignments)] // false positive
|
||||
let mut name = None;
|
||||
let mut name = None;
|
||||
let mut version = None;
|
||||
let mut tags = None;
|
||||
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
pub mod identifier;
|
||||
pub mod builder;
|
||||
pub mod fetch;
|
Loading…
Add table
Add a link
Reference in a new issue