From f29f944f99ff97a1b697d3d50dc250e288bfd6d1 Mon Sep 17 00:00:00 2001 From: Raine Date: Sat, 14 Oct 2023 22:39:50 +0200 Subject: [PATCH] feat: implement packagequeue --- manifest/src/build.rs | 10 +++++ pkgfile/src/lib.rs | 2 +- pkgr/package.toml | 1 - pkgr/src/api/mod.rs | 27 +++++++++++++ pkgr/src/commands.rs | 42 +++++++++++++++++---- pkgr/src/main.rs | 1 + pkgr/src/package/identifier.rs | 15 ++++---- pkgr/src/package/installer/mod.rs | 38 ------------------- pkgr/src/package/mod.rs | 63 ++++++++++++++++++++++++++++--- pkgr/src/package/queue.rs | 37 ++++++++++++++++++ 10 files changed, 176 insertions(+), 60 deletions(-) create mode 100644 pkgr/src/api/mod.rs create mode 100644 pkgr/src/package/queue.rs diff --git a/manifest/src/build.rs b/manifest/src/build.rs index 1879710..6d406b1 100644 --- a/manifest/src/build.rs +++ b/manifest/src/build.rs @@ -8,3 +8,13 @@ pub struct Build { pub install_script: String, pub dependencies: HashMap, } + +impl Default for Build { + fn default() -> Self { + Build { + dependencies: HashMap::default(), + build_script: String::default(), + install_script: String::default() + } + } +} \ No newline at end of file diff --git a/pkgfile/src/lib.rs b/pkgfile/src/lib.rs index 5db8e6f..6a9457d 100644 --- a/pkgfile/src/lib.rs +++ b/pkgfile/src/lib.rs @@ -3,7 +3,7 @@ use std::fmt::{Display, Formatter}; use std::io; use std::path::Path; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Eq, PartialEq)] pub struct PKGFile { pub manifest: String, pub data: Vec, diff --git a/pkgr/package.toml b/pkgr/package.toml index 91ff425..723ebed 100644 --- a/pkgr/package.toml +++ b/pkgr/package.toml @@ -44,7 +44,6 @@ build_script = "scripts/build" # relative to pkg install_script = "scripts/install" # relative to pkg [build.dependencies] -base = "latest,stable" # selected by default ## pkgr.* # packager is the official client but you may use other clients supporting the "pkgr v1 spec". diff --git a/pkgr/src/api/mod.rs b/pkgr/src/api/mod.rs new file mode 100644 index 0000000..3cec172 --- /dev/null +++ b/pkgr/src/api/mod.rs @@ -0,0 +1,27 @@ +use reqwest::blocking::Response; + +pub struct APITransaction { + /// Query made to API. + query: String, //TODO: enum + /// Response struct from abstracted library + _response: Option +} + +impl APITransaction { + pub fn new(_response: Option) -> Self { + APITransaction { + query: String::default(), + _response + } + } +} + +pub struct API { + base_url: String, + token: Option, + history: Vec +} + +impl API { + +} \ No newline at end of file diff --git a/pkgr/src/commands.rs b/pkgr/src/commands.rs index 8e35d49..869e961 100644 --- a/pkgr/src/commands.rs +++ b/pkgr/src/commands.rs @@ -8,6 +8,7 @@ use manifest::package::PackageType; use crate::CONFIG; use crate::package::identifier::PackageIdentifier; use crate::package::Package; +use crate::package::queue::PackageQueue; use crate::process::Process; use crate::types::fetch::TryFetch; @@ -76,14 +77,10 @@ impl Command { exit(1); } - trace!("Starting install..."); - match pkg.install(CONFIG.with(|c| if !*build { c.build_by_default } else { *build })) { - Ok(_) => (), - Err(e) => { - error!("Install failed: {}", e.to_string()); - exit(1); - } - } + let mut queue = PackageQueue::new(); + queue.add_package(pkg, *build); + trace!("Installing queue..."); + queue.install(*build); let end = std::time::Instant::now(); let _unix_end = std::time::SystemTime::now() @@ -117,6 +114,7 @@ impl Command { } => { if let Some(p) = package_identifier { if let Ok(mut pkg) = Package::try_fetch(p.clone()) { + trace!("{}", pkg.pkgfile.manifest); info!(target: "item", "Identifier: {:?}", pkg.identifier); info!(target: "item", ""); let mani = pkg.manifest(); @@ -134,6 +132,34 @@ impl Command { types.join(", ") }); 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::>() + .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::>() + .join(", ") + } + }); } else { error!("Could not find {p}"); } diff --git a/pkgr/src/main.rs b/pkgr/src/main.rs index cdad0a0..798eb1d 100644 --- a/pkgr/src/main.rs +++ b/pkgr/src/main.rs @@ -19,6 +19,7 @@ mod config; mod types; /// utils mod util; +mod api; thread_local! { static CONFIG: config::Config = config::Config::from_path("/etc/pkgr.toml") diff --git a/pkgr/src/package/identifier.rs b/pkgr/src/package/identifier.rs index 523b74b..e39ac87 100644 --- a/pkgr/src/package/identifier.rs +++ b/pkgr/src/package/identifier.rs @@ -24,11 +24,11 @@ impl std::fmt::Display for PackageIdentifierError { impl Error for PackageIdentifierError {} -#[derive(Clone)] +#[derive(Clone, Eq, PartialEq)] pub enum PackageIdentifier { PackageLocator(PackageLocator), URI(String), - Path(String), + Path(String) } 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 name: String, pub version: Option, @@ -160,8 +160,9 @@ impl FromStr for PackageLocator { } } -impl From<(String, String)> for PackageLocator { - fn from((name, locate_str): (String, String)) -> Self { +impl TryFrom<(String, String)> for PackageLocator { + type Error = PackageIdentifierError; + fn try_from((name, locate_str): (String, String)) -> Result { // name = "pkg" // locate_str = "1.0.0:tag1,tag2" or "1.0.0" or "tag1,tag2" let mut version = None; @@ -185,10 +186,10 @@ impl From<(String, String)> for PackageLocator { ); } - PackageLocator { + Ok(PackageLocator { name, version, tags, - } + }) } } diff --git a/pkgr/src/package/installer/mod.rs b/pkgr/src/package/installer/mod.rs index bea639d..da37f1b 100644 --- a/pkgr/src/package/installer/mod.rs +++ b/pkgr/src/package/installer/mod.rs @@ -68,25 +68,6 @@ impl PackageInstaller { return Err(e); } 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() { Ok(_) => Ok(()), Err(e) => Err(BinError::IOError(e)) @@ -109,25 +90,6 @@ impl PackageInstaller { } let build_manifest = self.manifest.build.clone().unwrap(); // 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(()) } diff --git a/pkgr/src/package/mod.rs b/pkgr/src/package/mod.rs index 96328f4..6378cef 100644 --- a/pkgr/src/package/mod.rs +++ b/pkgr/src/package/mod.rs @@ -1,20 +1,24 @@ use std::fmt::Display; use std::path::Path; +use std::process::exit; -use log::{debug, info, trace}; +use log::{debug, error, info, trace}; use reqwest::blocking::get; +use manifest::build::Build; use pkgfile::PKGFile; -use crate::package::identifier::PackageIdentifier; +use crate::package::identifier::{PackageIdentifier, PackageLocator}; use crate::types::fetch::TryFetch; pub mod identifier; pub mod installer; +pub mod queue; +#[derive(Eq, PartialEq)] pub struct Package { - pub identifier: identifier::PackageIdentifier, - pub pkgfile: pkgfile::PKGFile, + pub identifier: PackageIdentifier, + pub pkgfile: PKGFile, is_installed: bool, is_indexed: bool, } @@ -35,6 +39,55 @@ impl Package { manifest::Manifest::try_from(self.pkgfile.manifest.clone()).unwrap() } + /// Get package dependencies + pub fn dependencies(&self) -> Vec { + 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 { + 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. pub fn install(&mut self, build: bool) -> Result<(), installer::errors::InstallError> { let manifest = self.manifest(); @@ -119,7 +172,7 @@ impl TryFetch for Package { if let Ok(b) = response.bytes() { bytes.extend(b); } - }, + } Err(e) => return Err(FetchError::HTTPError(e)), }; // parse bytes as PKGFile diff --git a/pkgr/src/package/queue.rs b/pkgr/src/package/queue.rs new file mode 100644 index 0000000..16a7b95 --- /dev/null +++ b/pkgr/src/package/queue.rs @@ -0,0 +1,37 @@ +use log::trace; +use crate::package::Package; + +pub struct PackageQueue { + packages: Vec +} + +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); + }); + } +}