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)]
|
||||
mod db;
|
||||
mod hooks;
|
||||
mod item;
|
||||
mod package;
|
||||
@ -7,9 +8,10 @@ mod repository;
|
||||
mod version;
|
||||
|
||||
pub use {
|
||||
db: Database,
|
||||
hooks::Hooks,
|
||||
item::Item,
|
||||
package::{create as create_package, Dependency, Package, Specs},
|
||||
package::{create_package, Dependency, Package, Specs},
|
||||
plist::*,
|
||||
repository::Repository,
|
||||
tar,
|
||||
|
@ -37,6 +37,7 @@ pub struct Group {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
|
||||
/// the metadata associated with a package
|
||||
pub struct Package {
|
||||
/// The name of the package minus all version information
|
||||
pub name: String,
|
||||
@ -91,7 +92,7 @@ impl Package {
|
||||
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() {
|
||||
fs::create_dir_all(outdir)?;
|
||||
}
|
||||
@ -112,12 +113,35 @@ impl Package {
|
||||
Ok(node)
|
||||
}
|
||||
|
||||
/// Returns the formatted full package name including version and release strings
|
||||
pub fn fullname(&self) -> String {
|
||||
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() {
|
||||
fs::create_dir_all(outdir)?;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user