Skip to content

Commit

Permalink
Implement v1-v2 release conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
theory committed Sep 17, 2024
1 parent f421515 commit 7675005
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 12 deletions.
47 changes: 47 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ chrono = { version = "0.4.38", features = ["serde"] }
email_address = "0.2.9"
json-patch = "2.0.0"
lexopt = "0.3.0"
rand = "0.8.5"
relative-path = { version = "1.9", features = ["serde"] }
semver = { version = "1.0", features = ["std", "serde"] }
serde = { version = "1", features = ["derive"] }
Expand Down
2 changes: 1 addition & 1 deletion src/meta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use semver::Version;
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;

mod v1;
pub(crate) mod v1;
mod v2;

/// Represents the `meta-spec` object in [`Distribution`].
Expand Down
4 changes: 2 additions & 2 deletions src/meta/v1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub fn to_v2(v1: &Value) -> Result<Value, Box<dyn Error>> {
// Copy common fields.
let mut v2 = v1_to_v2_common(v1);

// Convert maintainer.
// Convert maintainers.
v2.insert("maintainers".to_string(), v1_to_v2_maintainers(v1)?);

// Convert license.
Expand Down Expand Up @@ -45,7 +45,7 @@ pub fn to_v2(v1: &Value) -> Result<Value, Box<dyn Error>> {
/// from_value parses v1, which contains PGXN v1 metadata, into a
/// [`Distribution`] object containing valid PGXN v2 metadata.
pub fn from_value(v1: Value) -> Result<Distribution, Box<dyn Error>> {
Distribution::try_from(to_v2(&v1)?)
to_v2(&v1)?.try_into()
}

/// v1_to_v2_common sets up a new v2 map with compatible fields copied from v1
Expand Down
2 changes: 1 addition & 1 deletion src/release/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ impl TryFrom<&[&Value]> for Release {

// Convert the first doc to v2 if necessary.
let mut v2 = match version {
// 1 => v1::to_v2(meta[0])?,
1 => v1::to_v2(meta[0])?,
2 => meta[0].clone(),
_ => unreachable!(),
};
Expand Down
5 changes: 0 additions & 5 deletions src/release/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ fn test_corpus() -> Result<(), Box<dyn Error>> {
),
(2, release_meta()),
] {
// Skip version 1 for now.
if version == 1 {
continue;
}

let v_dir = format!("v{version}");
let dir: PathBuf = [env!("CARGO_MANIFEST_DIR"), "corpus", &v_dir]
.iter()
Expand Down
58 changes: 55 additions & 3 deletions src/release/v1/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,59 @@
use super::Release;
use serde_json::Value;
use crate::meta::v1 as dist;
use serde_json::{json, Value};
use std::error::Error;

pub fn from_value(_: Value) -> Result<Release, Box<dyn Error>> {
Err("TODO".into())
/// to_v2 parses v1, which contains PGXN v1 release metadata, into a JSON
/// object containing valid PGXN v2 release metadata.
pub fn to_v2(v1: &Value) -> Result<Value, Box<dyn Error>> {
let mut v2_val = dist::to_v2(v1)?;
let v2 = v2_val
.as_object_mut()
.ok_or("Date returned from v1::to_v2 is not an object")?;

// Convert release.
v2.insert("release".to_string(), v1_to_v2_release(v1)?);

Ok(v2_val)
}

/// from_value parses v1, which contains PGXN v1 metadata, into a
/// [`Release`] object containing valid PGXN v2 metadata.
pub fn from_value(v1: Value) -> Result<Release, Box<dyn Error>> {
to_v2(&v1)?.try_into()
}

/// v1_to_v2_release clones release metadata from v1 to the v2 format. The
/// included signature information will be random and un-verifiable, but
/// adequate for v2 JSON Schema validation.
fn v1_to_v2_release(v1: &Value) -> Result<Value, Box<dyn Error>> {
use rand::distributions::{Alphanumeric, DistString};
if let Some(Value::String(user)) = v1.get("user") {
if let Some(Value::String(date)) = v1.get("date") {
if let Some(Value::String(sha1)) = v1.get("sha1") {
if let Some(Value::String(name)) = v1.get("name") {
if let Some(Value::String(version)) = v1.get("version") {
let uri = format!(
"/dist/semver/{}/{}-{}.zip",
version.as_str(),
name.as_str(),
version.as_str()
);
let mut rng = rand::thread_rng();
return Ok(json!({
"headers": [format!("eyJ{}", Alphanumeric.sample_string(&mut rng, 12))],
"signatures": [Alphanumeric.sample_string(&mut rng, 32)],
"payload": {
"user": user,
"date": date,
"uri": uri,
"digests": {"sha1": sha1},
}
}));
}
}
}
}
}
Err(Box::from("release metadata missing"))
}

0 comments on commit 7675005

Please sign in to comment.