diff --git a/Cargo.lock b/Cargo.lock index 5bdcec4f9f..857e7e87ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -792,9 +792,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "bytesize" @@ -2865,6 +2865,7 @@ dependencies = [ "anyhow", "async-trait", "cargo_toml", + "chrono", "clap", "comfy-table", "const_format", diff --git a/crates/fluvio-hub-util/Cargo.toml b/crates/fluvio-hub-util/Cargo.toml index 0985ee4233..5ea04da12c 100644 --- a/crates/fluvio-hub-util/Cargo.toml +++ b/crates/fluvio-hub-util/Cargo.toml @@ -20,6 +20,7 @@ connector-cmds = [ anyhow = { workspace = true } async-trait = { workspace = true } cargo_toml = { workspace = true } +chrono = { workspace = true } const_format = { workspace = true } dirs = { workspace = true } ed25519-dalek = { version = "2.1", features = ["serde", "rand_core"] } diff --git a/crates/fluvio-hub-util/src/package_meta_ext.rs b/crates/fluvio-hub-util/src/package_meta_ext.rs index 38934a0c23..ada7d514b7 100644 --- a/crates/fluvio-hub-util/src/package_meta_ext.rs +++ b/crates/fluvio-hub-util/src/package_meta_ext.rs @@ -2,10 +2,11 @@ use std::fs; use std::io::Read; use std::path::Path; +use chrono::{DateTime, Utc}; use tracing::debug; -use fluvio_hub_protocol::{PackageMeta, HubError}; -use fluvio_hub_protocol::constants::HUB_PACKAGE_META; +use fluvio_hub_protocol::{HubError, PackageMeta, PkgTag}; +use fluvio_hub_protocol::constants::{HUB_PACKAGE_META, PKG_TAG_META_PUBLISHED_AT}; use fluvio_hub_protocol::validate_allowedchars; use crate::package_get_topfile; @@ -17,6 +18,7 @@ pub trait PackageMetaExt { fn manifest_paths>(&self, pkgpath_in: P) -> Result>; fn write>(&self, pmetapath: P) -> Result<()>; fn update_from_cargo_toml>(&mut self, fpath: P) -> Result<()>; + fn published_at(&self) -> Result>; } impl PackageMetaExt for PackageMeta { @@ -56,6 +58,23 @@ impl PackageMetaExt for PackageMeta { Ok(()) } + + fn published_at(&self) -> Result> { + let published_at_pkg_tag = self + .tags + .as_ref() + .ok_or(HubError::General(String::from("No tags available")))? + .iter() + .find(|PkgTag { tag, .. }| tag == PKG_TAG_META_PUBLISHED_AT) + .ok_or(HubError::General(format!( + "Missing {PKG_TAG_META_PUBLISHED_AT} tag" + )))?; + + let publisted_at = DateTime::parse_from_rfc2822(published_at_pkg_tag.value.as_str()) + .map_err(|err| HubError::General(format!("Failed to parse publish date. {}", err)))?; + + Ok(publisted_at.to_utc()) + } } pub fn packagename_validate(pkgname: &str) -> Result<()> { @@ -144,6 +163,8 @@ pub fn package_meta_relative_path, T: AsRef>( #[cfg(test)] mod tests { + use fluvio_hub_protocol::PkgTag; + use super::*; #[test] @@ -458,4 +479,47 @@ mod tests { } } } + + #[test] + fn inf_meta_published_at_success() { + let pm = PackageMeta { + group: "infinyon".into(), + name: "example".into(), + version: "0.0.1".into(), + manifest: ["module.wasm".into()].to_vec(), + tags: Some(vec![PkgTag { + tag: PKG_TAG_META_PUBLISHED_AT.to_string(), + value: "Tue, 22 Nov 2022 21:24:11 GMT".to_string(), + }]), + ..Default::default() + }; + let published_at = pm.published_at(); + + assert!(published_at.is_ok()); + + let published_at = published_at.unwrap(); + assert_eq!(published_at.to_string(), "2022-11-22 21:24:11 UTC"); + } + + #[test] + fn inf_meta_published_at_missing_tag() { + let pm = PackageMeta { + group: "infinyon".into(), + name: "example".into(), + version: "0.0.1".into(), + manifest: ["module.wasm".into()].to_vec(), + tags: Some(vec![PkgTag { + tag: String::from("foo"), + value: String::from("bar"), + }]), + ..Default::default() + }; + let published_at = pm.published_at(); + + assert!(published_at.is_err()); + assert_eq!( + published_at.err().unwrap().to_string(), + format!("General Error: Missing inf::meta::published_at tag") + ); + } }