feat: implement packagequeue
This commit is contained in:
parent
825114136a
commit
f29f944f99
10 changed files with 176 additions and 60 deletions
|
@ -8,3 +8,13 @@ pub struct Build {
|
||||||
pub install_script: String,
|
pub install_script: String,
|
||||||
pub dependencies: HashMap<String, String>,
|
pub dependencies: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Build {
|
||||||
|
fn default() -> Self {
|
||||||
|
Build {
|
||||||
|
dependencies: HashMap::default(),
|
||||||
|
build_script: String::default(),
|
||||||
|
install_script: String::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ use std::fmt::{Display, Formatter};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct PKGFile {
|
pub struct PKGFile {
|
||||||
pub manifest: String,
|
pub manifest: String,
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
|
|
|
@ -44,7 +44,6 @@ build_script = "scripts/build" # relative to pkg
|
||||||
install_script = "scripts/install" # relative to pkg
|
install_script = "scripts/install" # relative to pkg
|
||||||
|
|
||||||
[build.dependencies]
|
[build.dependencies]
|
||||||
base = "latest,stable" # selected by default
|
|
||||||
|
|
||||||
## pkgr.*
|
## pkgr.*
|
||||||
# packager is the official client but you may use other clients supporting the "pkgr v1 spec".
|
# packager is the official client but you may use other clients supporting the "pkgr v1 spec".
|
||||||
|
|
27
pkgr/src/api/mod.rs
Normal file
27
pkgr/src/api/mod.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
use reqwest::blocking::Response;
|
||||||
|
|
||||||
|
pub struct APITransaction<R = Response> {
|
||||||
|
/// Query made to API.
|
||||||
|
query: String, //TODO: enum
|
||||||
|
/// Response struct from abstracted library
|
||||||
|
_response: Option<R>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R> APITransaction<R> {
|
||||||
|
pub fn new(_response: Option<R>) -> Self {
|
||||||
|
APITransaction {
|
||||||
|
query: String::default(),
|
||||||
|
_response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct API {
|
||||||
|
base_url: String,
|
||||||
|
token: Option<String>,
|
||||||
|
history: Vec<APITransaction>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl API {
|
||||||
|
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ use manifest::package::PackageType;
|
||||||
use crate::CONFIG;
|
use crate::CONFIG;
|
||||||
use crate::package::identifier::PackageIdentifier;
|
use crate::package::identifier::PackageIdentifier;
|
||||||
use crate::package::Package;
|
use crate::package::Package;
|
||||||
|
use crate::package::queue::PackageQueue;
|
||||||
use crate::process::Process;
|
use crate::process::Process;
|
||||||
use crate::types::fetch::TryFetch;
|
use crate::types::fetch::TryFetch;
|
||||||
|
|
||||||
|
@ -76,14 +77,10 @@ impl Command {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!("Starting install...");
|
let mut queue = PackageQueue::new();
|
||||||
match pkg.install(CONFIG.with(|c| if !*build { c.build_by_default } else { *build })) {
|
queue.add_package(pkg, *build);
|
||||||
Ok(_) => (),
|
trace!("Installing queue...");
|
||||||
Err(e) => {
|
queue.install(*build);
|
||||||
error!("Install failed: {}", e.to_string());
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let end = std::time::Instant::now();
|
let end = std::time::Instant::now();
|
||||||
let _unix_end = std::time::SystemTime::now()
|
let _unix_end = std::time::SystemTime::now()
|
||||||
|
@ -117,6 +114,7 @@ impl Command {
|
||||||
} => {
|
} => {
|
||||||
if let Some(p) = package_identifier {
|
if let Some(p) = package_identifier {
|
||||||
if let Ok(mut pkg) = Package::try_fetch(p.clone()) {
|
if let Ok(mut pkg) = Package::try_fetch(p.clone()) {
|
||||||
|
trace!("{}", pkg.pkgfile.manifest);
|
||||||
info!(target: "item", "Identifier: {:?}", pkg.identifier);
|
info!(target: "item", "Identifier: {:?}", pkg.identifier);
|
||||||
info!(target: "item", "");
|
info!(target: "item", "");
|
||||||
let mani = pkg.manifest();
|
let mani = pkg.manifest();
|
||||||
|
@ -134,6 +132,34 @@ impl Command {
|
||||||
types.join(", ")
|
types.join(", ")
|
||||||
});
|
});
|
||||||
info!(target: "item", "");
|
info!(target: "item", "");
|
||||||
|
info!(target: "item", "Dependencies: {}", {
|
||||||
|
let deps = pkg.dependencies();
|
||||||
|
if deps.len() == 0 {
|
||||||
|
String::from("None")
|
||||||
|
} else {
|
||||||
|
deps
|
||||||
|
.iter()
|
||||||
|
.map(|p| {
|
||||||
|
p.identifier.to_string()
|
||||||
|
})
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
info!(target: "item", "Build Dependencies: {}", {
|
||||||
|
let deps = pkg.build_dependencies();
|
||||||
|
if deps.len() == 0 {
|
||||||
|
String::from("None")
|
||||||
|
} else {
|
||||||
|
deps
|
||||||
|
.iter()
|
||||||
|
.map(|p| {
|
||||||
|
p.identifier.to_string()
|
||||||
|
})
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ")
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
error!("Could not find {p}");
|
error!("Could not find {p}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ mod config;
|
||||||
mod types;
|
mod types;
|
||||||
/// utils
|
/// utils
|
||||||
mod util;
|
mod util;
|
||||||
|
mod api;
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static CONFIG: config::Config = config::Config::from_path("/etc/pkgr.toml")
|
static CONFIG: config::Config = config::Config::from_path("/etc/pkgr.toml")
|
||||||
|
|
|
@ -24,11 +24,11 @@ impl std::fmt::Display for PackageIdentifierError {
|
||||||
|
|
||||||
impl Error for PackageIdentifierError {}
|
impl Error for PackageIdentifierError {}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Eq, PartialEq)]
|
||||||
pub enum PackageIdentifier {
|
pub enum PackageIdentifier {
|
||||||
PackageLocator(PackageLocator),
|
PackageLocator(PackageLocator),
|
||||||
URI(String),
|
URI(String),
|
||||||
Path(String),
|
Path(String)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for PackageIdentifier {
|
impl std::fmt::Debug for PackageIdentifier {
|
||||||
|
@ -59,7 +59,7 @@ impl std::fmt::Display for PackageIdentifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct PackageLocator {
|
pub struct PackageLocator {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub version: Option<u32>,
|
pub version: Option<u32>,
|
||||||
|
@ -160,8 +160,9 @@ impl FromStr for PackageLocator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<(String, String)> for PackageLocator {
|
impl TryFrom<(String, String)> for PackageLocator {
|
||||||
fn from((name, locate_str): (String, String)) -> Self {
|
type Error = PackageIdentifierError;
|
||||||
|
fn try_from((name, locate_str): (String, String)) -> Result<PackageLocator, Self::Error> {
|
||||||
// name = "pkg"
|
// name = "pkg"
|
||||||
// locate_str = "1.0.0:tag1,tag2" or "1.0.0" or "tag1,tag2"
|
// locate_str = "1.0.0:tag1,tag2" or "1.0.0" or "tag1,tag2"
|
||||||
let mut version = None;
|
let mut version = None;
|
||||||
|
@ -185,10 +186,10 @@ impl From<(String, String)> for PackageLocator {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageLocator {
|
Ok(PackageLocator {
|
||||||
name,
|
name,
|
||||||
version,
|
version,
|
||||||
tags,
|
tags,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,25 +68,6 @@ impl PackageInstaller {
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
debug!("extracted package in: {}", tmpdir.to_string());
|
debug!("extracted package in: {}", tmpdir.to_string());
|
||||||
{
|
|
||||||
let mut tmpdir = tmpdir.clone();
|
|
||||||
tmpdir.push(&self.manifest.bin.clone().unwrap().root);
|
|
||||||
if prompt_bool("See all pending installation files?", true) {
|
|
||||||
if let Err(e) = visit_dirs(tmpdir.path().as_path(),
|
|
||||||
&|d| {
|
|
||||||
info!(target: "item", "{}", d.path()
|
|
||||||
.to_str()
|
|
||||||
.unwrap()
|
|
||||||
.replace(&tmpdir.to_string(), ""))
|
|
||||||
})
|
|
||||||
{
|
|
||||||
error!("Could not show files: {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !prompt_bool("Continue?", is_noninteractive()) {
|
|
||||||
return Err(BinError::Cancelled);
|
|
||||||
}
|
|
||||||
match self.apply_overlay() {
|
match self.apply_overlay() {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(e) => Err(BinError::IOError(e))
|
Err(e) => Err(BinError::IOError(e))
|
||||||
|
@ -109,25 +90,6 @@ impl PackageInstaller {
|
||||||
}
|
}
|
||||||
let build_manifest = self.manifest.build.clone().unwrap();
|
let build_manifest = self.manifest.build.clone().unwrap();
|
||||||
// TODO: Check dependencies
|
// TODO: Check dependencies
|
||||||
for pkg_tuple in build_manifest.dependencies {
|
|
||||||
let mut pkg = Package::try_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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,24 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
use log::{debug, info, trace};
|
use log::{debug, error, info, trace};
|
||||||
use reqwest::blocking::get;
|
use reqwest::blocking::get;
|
||||||
|
|
||||||
|
use manifest::build::Build;
|
||||||
use pkgfile::PKGFile;
|
use pkgfile::PKGFile;
|
||||||
|
|
||||||
use crate::package::identifier::PackageIdentifier;
|
use crate::package::identifier::{PackageIdentifier, PackageLocator};
|
||||||
use crate::types::fetch::TryFetch;
|
use crate::types::fetch::TryFetch;
|
||||||
|
|
||||||
pub mod identifier;
|
pub mod identifier;
|
||||||
pub mod installer;
|
pub mod installer;
|
||||||
|
pub mod queue;
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq)]
|
||||||
pub struct Package {
|
pub struct Package {
|
||||||
pub identifier: identifier::PackageIdentifier,
|
pub identifier: PackageIdentifier,
|
||||||
pub pkgfile: pkgfile::PKGFile,
|
pub pkgfile: PKGFile,
|
||||||
is_installed: bool,
|
is_installed: bool,
|
||||||
is_indexed: bool,
|
is_indexed: bool,
|
||||||
}
|
}
|
||||||
|
@ -35,6 +39,55 @@ impl Package {
|
||||||
manifest::Manifest::try_from(self.pkgfile.manifest.clone()).unwrap()
|
manifest::Manifest::try_from(self.pkgfile.manifest.clone()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get package dependencies
|
||||||
|
pub fn dependencies(&self) -> Vec<Package> {
|
||||||
|
let mut dependencies = vec![];
|
||||||
|
for dependency in self.manifest().dependencies {
|
||||||
|
let pkglocate = if let Ok(pl) = PackageLocator::try_from(dependency.clone()) {
|
||||||
|
trace!("parsed pl successfully...");
|
||||||
|
pl
|
||||||
|
} else {
|
||||||
|
error!("Could not parse package locator: {:?} in dependencies.", &dependency);
|
||||||
|
exit(1);
|
||||||
|
};
|
||||||
|
let pkg = match Package::try_fetch(PackageIdentifier::PackageLocator(pkglocate)) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Could not fetch dependency: {}", e);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dependencies.push(pkg);
|
||||||
|
}
|
||||||
|
dependencies
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_dependencies(&self) -> Vec<Package> {
|
||||||
|
let mut dependencies = vec![];
|
||||||
|
for dependency in self
|
||||||
|
.manifest()
|
||||||
|
.build
|
||||||
|
.unwrap_or(Build::default())
|
||||||
|
.dependencies {
|
||||||
|
let pkglocate = if let Ok(pl) = PackageLocator::try_from(dependency.clone()) {
|
||||||
|
trace!("parsed pl successfully...");
|
||||||
|
pl
|
||||||
|
} else {
|
||||||
|
error!("Could not parse package locator: {:?} in dependencies.", &dependency);
|
||||||
|
exit(1);
|
||||||
|
};
|
||||||
|
let pkg = match Package::try_fetch(PackageIdentifier::PackageLocator(pkglocate)) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Could not fetch dependency: {}", e);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dependencies.push(pkg);
|
||||||
|
}
|
||||||
|
dependencies
|
||||||
|
}
|
||||||
|
|
||||||
/// Install the package.
|
/// Install the package.
|
||||||
pub fn install(&mut self, build: bool) -> Result<(), installer::errors::InstallError> {
|
pub fn install(&mut self, build: bool) -> Result<(), installer::errors::InstallError> {
|
||||||
let manifest = self.manifest();
|
let manifest = self.manifest();
|
||||||
|
@ -119,7 +172,7 @@ impl TryFetch<PackageIdentifier> for Package {
|
||||||
if let Ok(b) = response.bytes() {
|
if let Ok(b) = response.bytes() {
|
||||||
bytes.extend(b);
|
bytes.extend(b);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => return Err(FetchError::HTTPError(e)),
|
Err(e) => return Err(FetchError::HTTPError(e)),
|
||||||
};
|
};
|
||||||
// parse bytes as PKGFile
|
// parse bytes as PKGFile
|
||||||
|
|
37
pkgr/src/package/queue.rs
Normal file
37
pkgr/src/package/queue.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
use log::trace;
|
||||||
|
use crate::package::Package;
|
||||||
|
|
||||||
|
pub struct PackageQueue {
|
||||||
|
packages: Vec<Package>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PackageQueue {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
PackageQueue {
|
||||||
|
packages: vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_package(&mut self, package: Package, build: bool) {
|
||||||
|
let dependencies = package.dependencies();
|
||||||
|
for dependency in dependencies {
|
||||||
|
trace!("Checking package: {}", &dependency.identifier);
|
||||||
|
if self.packages.contains(&dependency) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
trace!("Adding package: {}", &dependency.identifier);
|
||||||
|
self.packages.push(dependency);
|
||||||
|
}
|
||||||
|
if !self.packages.contains(&package) {
|
||||||
|
self.packages.push(package);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn install(&mut self, build: bool) {
|
||||||
|
self.packages
|
||||||
|
.iter_mut()
|
||||||
|
.for_each(|pkg| {
|
||||||
|
pkg.install(build);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue