From 7c3cf1c2e8a6e249b6d5fea5e92e9de607f1b5cd Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Fri, 08 Oct 2021 01:03:34 +0100 Subject: [PATCH] Fix dependencies with dependencies Cargo for whatever reason uses a separate struct for uploading than downloading, with the only difference being `version_req` -> `req`. --- chartered-types/src/cargo.rs | 14 ++++++-------- chartered-frontend/src/pages/crate/CrateView.tsx | 6 +++--- chartered-web/src/endpoints/cargo_api/publish.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 13 deletions(-) diff --git a/chartered-types/src/cargo.rs b/chartered-types/src/cargo.rs index 820ca5f..0c907b5 100644 --- a/chartered-types/src/cargo.rs +++ a/chartered-types/src/cargo.rs @@ -40,13 +40,15 @@ #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub struct CrateDependency<'a> { pub name: Cow<'a, str>, - pub version_req: Cow<'a, str>, // needs to be: https://github.com/steveklabnik/semver#requirements + pub req: Cow<'a, str>, pub features: Vec>, pub optional: bool, pub default_features: bool, pub target: Option>, // a string such as "cfg(windows)" - pub kind: Cow<'a, str>, // dev, build or normal + pub kind: Cow<'a, str>, // dev, build or normal + #[serde(skip_serializing_if = "Option::is_none")] pub registry: Option>, + #[serde(skip_serializing_if = "Option::is_none")] pub package: Option>, } @@ -54,12 +56,8 @@ pub fn into_owned(self) -> CrateDependency<'static> { CrateDependency { name: Cow::Owned(self.name.into_owned()), - version_req: Cow::Owned(self.version_req.into_owned()), - features: self - .features - .into_iter() - .map(|v| Cow::Owned(v.into_owned())) - .collect(), + req: Cow::Owned(self.req.into_owned()), + features: self.features.into_iter().map(|v| Cow::Owned(v.into_owned())).collect(), optional: self.optional, default_features: self.default_features, target: self.target.map(|v| Cow::Owned(v.into_owned())), diff --git a/chartered-frontend/src/pages/crate/CrateView.tsx b/chartered-frontend/src/pages/crate/CrateView.tsx index be5a265..7f60f1c 100644 --- a/chartered-frontend/src/pages/crate/CrateView.tsx +++ a/chartered-frontend/src/pages/crate/CrateView.tsx @@ -63,7 +63,7 @@ export interface CrateInfoVersionDependency { name: string; - version_req: string; + req: string; registry?: string; } @@ -236,7 +236,7 @@ )} {crateVersion.deps.map((dep) => ( @@ -292,7 +292,7 @@ return (
  • - {link} = "{dep.version_req}" + {link} = "{dep.req}"
  • ); } diff --git a/chartered-web/src/endpoints/cargo_api/publish.rs b/chartered-web/src/endpoints/cargo_api/publish.rs index 72eebb0..9de7c80 100644 --- a/chartered-web/src/endpoints/cargo_api/publish.rs +++ a/chartered-web/src/endpoints/cargo_api/publish.rs @@ -1,7 +1,8 @@ use axum::extract; use bytes::Bytes; use chartered_db::{crates::Crate, users::User, ConnectionPool}; use chartered_fs::FileSystem; +use chartered_types::cargo::{CrateFeatures, CrateVersion, CrateDependency}; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use std::{borrow::Cow, convert::TryInto, sync::Arc}; @@ -84,7 +85,7 @@ file_ref, hex::encode(Sha256::digest(crate_bytes)), metadata_bytes.len().try_into().unwrap(), - metadata.inner.into_owned(), + metadata.inner.into(), metadata.meta, ) .await?; @@ -125,5 +126,66 @@ #[serde(flatten)] meta: chartered_types::cargo::CrateVersionMetadata, #[serde(flatten)] - inner: chartered_types::cargo::CrateVersion<'a>, + inner: MetadataCrateVersion<'a>, +} + +#[derive(Deserialize, Debug)] +pub struct MetadataCrateVersion<'a> { + #[serde(borrow)] + pub name: Cow<'a, str>, + #[serde(borrow)] + pub vers: Cow<'a, str>, + pub deps: Vec>, + pub features: CrateFeatures, + #[serde(borrow)] + pub links: Option>, +} + +impl From> for CrateVersion<'static> { + fn from(us: MetadataCrateVersion<'_>) -> Self { + Self { + name: Cow::Owned(us.name.into_owned()), + vers: Cow::Owned(us.vers.into_owned()), + deps: us.deps.into_iter().map(CrateDependency::from).collect(), + features: us.features, + links: us.links.map(|v| Cow::Owned(v.into_owned())), + } + } +} + +/// We've redefined MetadataCrateDependency for deserialisation because `cargo publish` passes +/// a `version_req`, whereas when downloading it expects `req` - and `package` isn't returned. +#[derive(Deserialize, Debug)] +pub struct MetadataCrateDependency<'a> { + pub name: Cow<'a, str>, + pub version_req: Cow<'a, str>, // needs to be: https://github.com/steveklabnik/semver#requirements + pub features: Vec>, + pub optional: bool, + pub default_features: bool, + pub target: Option>, // a string such as "cfg(windows)" + pub kind: Cow<'a, str>, // dev, build or normal + pub registry: Option>, + pub explicit_name_in_toml: Option>, +} + +impl From> for CrateDependency<'static> { + fn from(us: MetadataCrateDependency<'_>) -> CrateDependency<'static> { + let (name, package) = if let Some(explicit_name_in_toml) = us.explicit_name_in_toml { + (explicit_name_in_toml.into_owned(), Some(us.name.into_owned())) + } else { + (us.name.into_owned(), None) + }; + + Self { + name: Cow::Owned(name), + req: Cow::Owned(us.version_req.into_owned()), + features: us.features.into_iter().map(|v| Cow::Owned(v.into_owned())).collect(), + optional: us.optional, + default_features: us.default_features, + target: us.target.map(|v| Cow::Owned(v.into_owned())), + kind: Cow::Owned(us.kind.into_owned()), + registry: us.registry.map(|v| Cow::Owned(v.into_owned())), + package: package.map(Cow::Owned), + } + } } -- rgit 0.1.3