refactor: changed how packages work
This commit is contained in:
parent
9416794101
commit
3293e407ae
7 changed files with 134 additions and 59 deletions
|
@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Build {
|
pub struct Build {
|
||||||
build_script: String,
|
pub build_script: String,
|
||||||
install_script: String,
|
pub install_script: String,
|
||||||
dependencies: HashMap<String, String>,
|
pub dependencies: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct PKGFile {
|
pub struct PKGFile {
|
||||||
pub manifest: String,
|
pub manifest: String,
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
|
|
|
@ -4,7 +4,7 @@ use clap::{Parser, Subcommand};
|
||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
use manifest::Manifest;
|
use manifest::Manifest;
|
||||||
use crate::package::installer::{InstallType, PackageInstaller};
|
use crate::package::installer::{InstallType, PackageInstaller};
|
||||||
use crate::package::fetch::fetch_package;
|
use crate::package::Package;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[clap(name = "pkgr", version)]
|
#[clap(name = "pkgr", version)]
|
||||||
|
@ -58,31 +58,35 @@ impl Command {
|
||||||
|
|
||||||
info!("Parsing package...");
|
info!("Parsing package...");
|
||||||
trace!("Fetching package: {}", package_identifier);
|
trace!("Fetching package: {}", package_identifier);
|
||||||
let pkgfile = fetch_package(package_identifier.clone()).unwrap();
|
let mut pkg = Package::fetch(package_identifier.clone()).unwrap();
|
||||||
debug!("size: manifest({}kb) data({}kb)", pkgfile.manifest.len() / 1024, pkgfile.data.len() / 1024);
|
debug!("manifest size: {}kb", pkg.pkgfile.manifest.len() / 1024);
|
||||||
trace!("parsing manifest");
|
debug!("files size: {}kb", pkg.pkgfile.data.len() / 1024);
|
||||||
let manifest = Manifest::try_from(pkgfile.manifest.clone()).unwrap();
|
|
||||||
debug!("manifest pkg name: {}", manifest.package.name);
|
|
||||||
trace!("creating installer");
|
|
||||||
let installer = PackageInstaller::new(manifest.clone(), pkgfile, if *build { InstallType::Build } else { InstallType::Bin });
|
|
||||||
info!("Installing: {}...", &manifest.package.name);
|
|
||||||
|
|
||||||
trace!("starting install");
|
trace!("Checking if package is installed...");
|
||||||
match installer.install() {
|
if pkg.is_installed() {
|
||||||
Ok(_) => {
|
error!("Package is already installed.");
|
||||||
info!("Sucessfully installed: {}", &manifest.package.name);
|
exit(1);
|
||||||
()
|
}
|
||||||
},
|
|
||||||
|
trace!("Starting install...");
|
||||||
|
match pkg.install() {
|
||||||
|
Ok(_) => (),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("{}", e.to_string());
|
error!("Install failed: {}", e.to_string());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let unix_end = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap();
|
|
||||||
let end = std::time::Instant::now();
|
let end = std::time::Instant::now();
|
||||||
// float ms
|
let unix_end = std::time::SystemTime::now()
|
||||||
let duration = (end - start).as_nanos() as f64;
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
info!("Install took: {}ms", (duration / 1_000_000.0));
|
.unwrap();
|
||||||
|
|
||||||
|
let duration = end.duration_since(start);
|
||||||
|
|
||||||
|
info!("Install complete.");
|
||||||
|
info!("Install took {}ms.", duration.as_nanos() as f64 / 1000000.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
Command::Remove { package_identifier, index } => {
|
Command::Remove { package_identifier, index } => {
|
||||||
if let PackageIdentifier::URI(_) = package_identifier {
|
if let PackageIdentifier::URI(_) = package_identifier {
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use log::warn;
|
|
||||||
use pkgfile::PKGFile;
|
use pkgfile::PKGFile;
|
||||||
use crate::package::identifier::PackageIdentifier;
|
|
||||||
use reqwest::blocking::get;
|
use reqwest::blocking::get;
|
||||||
|
use crate::package::identifier::PackageLocator;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum FetchError {
|
pub enum FetchError {
|
||||||
|
@ -26,34 +24,33 @@ impl Display for FetchError {
|
||||||
|
|
||||||
impl Error for FetchError {}
|
impl Error for FetchError {}
|
||||||
|
|
||||||
pub fn fetch_package(package_identifier: PackageIdentifier) -> Result<PKGFile, FetchError> {
|
pub fn fetch_by_path<S: Into<String>>(path: S) -> Result<PKGFile, FetchError> {
|
||||||
match package_identifier {
|
std::fs::read(path.into())
|
||||||
PackageIdentifier::Path(path) => {
|
.map_err(|e| FetchError::IOError(e)).and_then(|bytes| {
|
||||||
std::fs::read(path)
|
PKGFile::try_from(bytes).map_err(|_| FetchError::ParseError)
|
||||||
.map_err(|e| FetchError::IOError(e)).and_then(|bytes| {
|
})
|
||||||
PKGFile::try_from(bytes).map_err(|_| FetchError::ParseError)
|
}
|
||||||
})
|
|
||||||
}
|
pub fn fetch_by_uri<S: Into<String>>(uri: S) -> Result<PKGFile, FetchError> {
|
||||||
PackageIdentifier::URI(uri) => {
|
// get file contents as bytes
|
||||||
// get file contents as bytes
|
let mut bytes = Vec::new();
|
||||||
let mut bytes = Vec::new();
|
match get(uri.into()) {
|
||||||
match get(&uri) {
|
Ok(mut response) => {
|
||||||
Ok(mut response) => {
|
match response.take(1024 * 1024).read_to_end(&mut bytes) {
|
||||||
match response.take(1024 * 1024).read_to_end(&mut bytes) {
|
Ok(_) => (),
|
||||||
Ok(_) => (),
|
Err(e) => return Err(FetchError::IOError(e)),
|
||||||
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())
|
|
||||||
}
|
}
|
||||||
|
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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fetch_by_package_locator(package_locator: PackageLocator) -> Result<PKGFile, FetchError> {
|
||||||
|
// TODO: search index for package locator
|
||||||
|
Ok(PKGFile::default())
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@ impl Display for BinError {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum BuildError {}
|
pub enum BuildError {
|
||||||
|
InvalidManifest
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for BuildError {
|
impl Display for BuildError {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
@ -28,7 +30,7 @@ impl Display for BuildError {
|
||||||
pub enum InstallError {
|
pub enum InstallError {
|
||||||
BuildError(BuildError),
|
BuildError(BuildError),
|
||||||
BinError(BinError),
|
BinError(BinError),
|
||||||
InstallError
|
Generic
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for InstallError {
|
impl ToString for InstallError {
|
||||||
|
@ -36,7 +38,7 @@ impl ToString for InstallError {
|
||||||
match self {
|
match self {
|
||||||
InstallError::BuildError(e) => format!("Build error: {}", e),
|
InstallError::BuildError(e) => format!("Build error: {}", e),
|
||||||
InstallError::BinError(e) => format!("Bin error: {}", e),
|
InstallError::BinError(e) => format!("Bin error: {}", e),
|
||||||
InstallError::InstallError => "Install error".to_string(),
|
InstallError::Generic => "Install error".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,13 @@ impl PackageInstaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build(&self) -> Result<(), BuildError> {
|
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
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,68 @@
|
||||||
|
use log::trace;
|
||||||
|
|
||||||
pub mod identifier;
|
pub mod identifier;
|
||||||
pub mod installer;
|
pub mod installer;
|
||||||
pub mod fetch;
|
pub mod fetch;
|
||||||
|
|
||||||
|
pub struct Package {
|
||||||
|
pub identifier: identifier::PackageIdentifier,
|
||||||
|
pub pkgfile: pkgfile::PKGFile,
|
||||||
|
is_installed: bool,
|
||||||
|
is_indexed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Package {
|
||||||
|
pub fn new(identifier: identifier::PackageIdentifier, pkgfile: pkgfile::PKGFile) -> Package {
|
||||||
|
Package {
|
||||||
|
identifier,
|
||||||
|
pkgfile,
|
||||||
|
is_installed: false,
|
||||||
|
is_indexed: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn manifest(&self) -> manifest::Manifest {
|
||||||
|
manifest::Manifest::try_from(self.pkgfile.manifest.clone())
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fetch(package_identifier: identifier::PackageIdentifier) -> Result<Package, fetch::FetchError> {
|
||||||
|
match &package_identifier {
|
||||||
|
identifier::PackageIdentifier::Path(path) => {
|
||||||
|
trace!("fetching package from path: {}", path);
|
||||||
|
let pkgfile = fetch::fetch_by_path(path).unwrap();
|
||||||
|
Ok(Package::new(package_identifier, pkgfile))
|
||||||
|
},
|
||||||
|
identifier::PackageIdentifier::URI(url) => {
|
||||||
|
trace!("fetching package from uri: {}", url);
|
||||||
|
let pkgfile = fetch::fetch_by_uri(url).unwrap();
|
||||||
|
Ok(Package::new(package_identifier, pkgfile))
|
||||||
|
},
|
||||||
|
identifier::PackageIdentifier::PackageLocator(locator) => {
|
||||||
|
trace!("fetching package from locator: {}", locator);
|
||||||
|
let pkgfile = fetch::fetch_by_package_locator(locator.clone()).unwrap();
|
||||||
|
Ok(Package::new(package_identifier, pkgfile))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn install(&mut self) -> Result<(), installer::errors::InstallError> {
|
||||||
|
let manifest = self.manifest();
|
||||||
|
let installer = installer::PackageInstaller::new(manifest.clone(), self.pkgfile.clone(), installer::InstallType::Bin);
|
||||||
|
match installer.install() {
|
||||||
|
Ok(_) => {
|
||||||
|
self.is_installed = true;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
Err(e) => Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_installed(&self) -> bool {
|
||||||
|
self.is_installed
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_indexed(&self) -> bool {
|
||||||
|
self.is_indexed
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue