Add Update and Database types and begin forming infra for updating
packages
This commit is contained in:
parent
9d53c9f44d
commit
6c62f15a41
64
src/db/mod.rs
Normal file
64
src/db/mod.rs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
use {
|
||||||
|
crate::{Repository, Package, Version},
|
||||||
|
serde::{Deserialize, Serialize},
|
||||||
|
std::{collections::HashMap, error::Error},
|
||||||
|
url::Url,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Update {
|
||||||
|
pub name: String,
|
||||||
|
pub version: Version,
|
||||||
|
pub url: Url,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Database {
|
||||||
|
pub packages: HashMap<String, Package>,
|
||||||
|
pub available: HashMap<String, Repository>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Database {
|
||||||
|
pub fn update(&mut self) -> Result<(), Box<dyn Error>> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_upgradable(&mut self) -> Result<HashMap<String, Update>, Box<dyn Error>> {
|
||||||
|
self.update()?;
|
||||||
|
let mut updates = HashMap::<String, Update>::new();
|
||||||
|
for local_package in self.packages.values() {
|
||||||
|
let name = local_package.name.clone();
|
||||||
|
for repo in self.available.values() {
|
||||||
|
// Check if the remote has a package by this name
|
||||||
|
if let Some(remote_package) = repo.packages.get(&name) {
|
||||||
|
// Check if the remote package is an update
|
||||||
|
if remote_package.is_upgrade(&local_package) {
|
||||||
|
// Check if we've already pulled in an update from another repo,
|
||||||
|
// and if so compare versions
|
||||||
|
if let Some(other_update) = updates.get(&name) {
|
||||||
|
if remote_package.version > other_update.version {
|
||||||
|
// The remote version is an update to the already
|
||||||
|
// pulled in update, so swap it out
|
||||||
|
let update = Update {
|
||||||
|
name: name.clone(),
|
||||||
|
version: remote_package.version,
|
||||||
|
url: repo.base_url.clone(),
|
||||||
|
};
|
||||||
|
updates.insert(name, update);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// First time we've seen this update, so insert it
|
||||||
|
// into our hashmap
|
||||||
|
let update = Update {
|
||||||
|
name: name.clone(),
|
||||||
|
version: remote_package.version,
|
||||||
|
url: repo.base_url,
|
||||||
|
};
|
||||||
|
updates.insert(name, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(updates)
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
#![warn(clippy::all, clippy::pedantic)]
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
|
mod db;
|
||||||
mod hooks;
|
mod hooks;
|
||||||
mod item;
|
mod item;
|
||||||
mod package;
|
mod package;
|
||||||
@ -7,9 +8,10 @@ mod repository;
|
|||||||
mod version;
|
mod version;
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
|
db: Database,
|
||||||
hooks::Hooks,
|
hooks::Hooks,
|
||||||
item::Item,
|
item::Item,
|
||||||
package::{create as create_package, Dependency, Package, Specs},
|
package::{create_package, Dependency, Package, Specs},
|
||||||
plist::*,
|
plist::*,
|
||||||
repository::Repository,
|
repository::Repository,
|
||||||
tar,
|
tar,
|
||||||
|
@ -37,6 +37,7 @@ pub struct Group {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
|
||||||
|
/// the metadata associated with a package
|
||||||
pub struct Package {
|
pub struct Package {
|
||||||
/// The name of the package minus all version information
|
/// The name of the package minus all version information
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@ -91,7 +92,7 @@ impl Package {
|
|||||||
to_string_pretty(self, cfg)
|
to_string_pretty(self, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_ron_and_create_tar_node(&self, outdir: &Path) -> Result<Node, Box<dyn Error>> {
|
fn save_ron_and_create_tar_node(&self, outdir: &Path) -> Result<Node, Box<dyn Error>> {
|
||||||
if !outdir.exists() {
|
if !outdir.exists() {
|
||||||
fs::create_dir_all(outdir)?;
|
fs::create_dir_all(outdir)?;
|
||||||
}
|
}
|
||||||
@ -112,12 +113,35 @@ impl Package {
|
|||||||
Ok(node)
|
Ok(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the formatted full package name including version and release strings
|
||||||
pub fn fullname(&self) -> String {
|
pub fn fullname(&self) -> String {
|
||||||
format!("{}-{}_{}", self.name, self.version, self.release)
|
format!("{}-{}_{}", self.name, self.version, self.release)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tests whether this package is an update for another
|
||||||
|
pub fn is_upgrade(&self, other: &Self) -> bool {
|
||||||
|
self.name == other.name && self.version > other.version
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create(path: &Path, specs: Specs, outdir: &Path) -> Result<(), Box<dyn Error>> {
|
/// Creates a package archive given a path to the included files, a package `Specs`
|
||||||
|
/// file and an output directory
|
||||||
|
///
|
||||||
|
/// ## Usage
|
||||||
|
/// ```
|
||||||
|
/// use std::path::Path;
|
||||||
|
/// use hpk::Specs;
|
||||||
|
///
|
||||||
|
/// let staging = Path::new("staged");
|
||||||
|
/// let outdir = Path::new("package");
|
||||||
|
/// let specs = Specs {
|
||||||
|
/// name: "foo".to_string(),
|
||||||
|
/// version: "0.42.0".parse().unwrap(),
|
||||||
|
/// description: "an example package".to_string(),
|
||||||
|
/// ..Default::default()
|
||||||
|
/// };
|
||||||
|
/// let result = hpk::create_package(&staging, specs, &outdir);
|
||||||
|
pub fn create_package(path: &Path, specs: Specs, outdir: &Path) -> Result<(), Box<dyn Error>> {
|
||||||
if !outdir.exists() {
|
if !outdir.exists() {
|
||||||
fs::create_dir_all(outdir)?;
|
fs::create_dir_all(outdir)?;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user