🏡 index : ~doyle/chartered.git

author Jordan Doyle <jordan@doyle.la> 2021-10-08 1:03:34.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2021-10-08 1:03:34.0 +01:00:00
commit
7c3cf1c2e8a6e249b6d5fea5e92e9de607f1b5cd [patch]
tree
c908e7671829ad3e9787aa003df92a602f7d78f4
parent
63abc7f6dac6236b93b97c54cdab2f50d9e57b76
download
7c3cf1c2e8a6e249b6d5fea5e92e9de607f1b5cd.tar.gz

Fix dependencies with dependencies

Cargo for whatever reason uses a separate struct for uploading than downloading,
with the only difference being `version_req` -> `req`.

Diff

 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<Cow<'a, str>>,
    pub optional: bool,
    pub default_features: bool,
    pub target: Option<Cow<'a, str>>, // 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<Cow<'a, str>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub package: Option<Cow<'a, str>>,
}

@@ -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) => (
                  <Dependency
                    key={`${dep.name}-${dep.version_req}`}
                    key={`${dep.name}-${dep.req}`}
                    organisation={organisation}
                    dep={dep}
                  />
@@ -292,7 +292,7 @@

  return (
    <li className="list-group-item">
      {link} = "<strong>{dep.version_req}</strong>"
      {link} = "<strong>{dep.req}</strong>"
    </li>
  );
}
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<MetadataCrateDependency<'a>>,
    pub features: CrateFeatures,
    #[serde(borrow)]
    pub links: Option<Cow<'a, str>>,
}

impl From<MetadataCrateVersion<'_>> 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<Cow<'a, str>>,
    pub optional: bool,
    pub default_features: bool,
    pub target: Option<Cow<'a, str>>, // a string such as "cfg(windows)"
    pub kind: Cow<'a, str>,           // dev, build or normal
    pub registry: Option<Cow<'a, str>>,
    pub explicit_name_in_toml: Option<Cow<'a, str>>,
}

impl From<MetadataCrateDependency<'_>> 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),
        }
    }
}