Skip to content

Commit b239314

Browse files
committed
Auto merge of #3650 - Turbo87:no-semver-columns, r=jtgeibel
models::Version: Change `num` field to a plain `String` This PR prepares for `semver` v1.x no longer having a `diesel` feature, which would make it much more complicated for us to directly deserialize the SQL column into a `semver::Version` field. We can deserialize it to a `String` instead, and only parse it into a `semver::Version` on demand.
2 parents 492d16c + 7a5e799 commit b239314

File tree

5 files changed

+41
-23
lines changed

5 files changed

+41
-23
lines changed

src/controllers/krate/downloads.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub fn downloads(req: &mut dyn RequestExt) -> EndpointResult {
2323
let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
2424

2525
let mut versions: Vec<Version> = krate.all_versions().load(&*conn)?;
26-
versions.sort_by(|a, b| b.num.cmp(&a.num));
26+
versions.sort_by_cached_key(|version| cmp::Reverse(semver::Version::parse(&version.num).ok()));
2727
let (latest_five, rest) = versions.split_at(cmp::min(5, versions.len()));
2828

2929
let downloads = VersionDownload::belonging_to(latest_five)

src/controllers/krate/metadata.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
//! index or cached metadata which was extracted (client side) from the
55
//! `Cargo.toml` file.
66
7+
use std::cmp::Reverse;
8+
79
use crate::controllers::frontend_prelude::*;
810
use crate::controllers::helpers::pagination::PaginationOptions;
911

@@ -128,7 +130,10 @@ pub fn show(req: &mut dyn RequestExt) -> EndpointResult {
128130
.left_outer_join(users::table)
129131
.select((versions::all_columns, users::all_columns.nullable()))
130132
.load(&*conn)?;
131-
versions_and_publishers.sort_by(|a, b| b.0.num.cmp(&a.0.num));
133+
134+
versions_and_publishers
135+
.sort_by_cached_key(|(version, _)| Reverse(semver::Version::parse(&version.num).ok()));
136+
132137
let versions = versions_and_publishers
133138
.iter()
134139
.map(|(v, _)| v)
@@ -224,7 +229,10 @@ pub fn versions(req: &mut dyn RequestExt) -> EndpointResult {
224229
.left_outer_join(users::table)
225230
.select((versions::all_columns, users::all_columns.nullable()))
226231
.load(&*conn)?;
227-
versions_and_publishers.sort_by(|a, b| b.0.num.cmp(&a.0.num));
232+
233+
versions_and_publishers
234+
.sort_by_cached_key(|(version, _)| Reverse(semver::Version::parse(&version.num).ok()));
235+
228236
let versions = versions_and_publishers
229237
.iter()
230238
.map(|(v, _)| v)

src/git.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,13 +328,12 @@ pub fn yank(
328328
}
329329

330330
let prev = fs::read_to_string(&dst)?;
331-
let version_num = version.num.to_string();
332331
let new = prev
333332
.lines()
334333
.map(|line| {
335334
let mut git_crate = serde_json::from_str::<Crate>(line)
336335
.map_err(|_| format!("couldn't decode: `{}`", line))?;
337-
if git_crate.name != krate || git_crate.vers != version_num {
336+
if git_crate.name != krate || git_crate.vers != version.num {
338337
return Ok(line.to_string());
339338
}
340339
git_crate.yanked = Some(yanked);

src/models/version.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::schema::*;
1414
pub struct Version {
1515
pub id: i32,
1616
pub crate_id: i32,
17-
pub num: semver::Version,
17+
pub num: String,
1818
pub updated_at: NaiveDateTime,
1919
pub created_at: NaiveDateTime,
2020
pub downloads: i32,
@@ -59,16 +59,26 @@ impl TopVersions {
5959
/// highest version (in semver order) for a collection of date/version pairs.
6060
pub fn from_date_version_pairs<T>(pairs: T) -> Self
6161
where
62-
T: Clone + IntoIterator<Item = (NaiveDateTime, semver::Version)>,
62+
T: Clone + IntoIterator<Item = (NaiveDateTime, String)>,
6363
{
64-
let newest = pairs.clone().into_iter().max().map(|(_, v)| v);
65-
let highest = pairs.clone().into_iter().map(|(_, v)| v).max();
64+
// filter out versions that we can't parse
65+
let pairs: Vec<(NaiveDateTime, semver::Version)> = pairs
66+
.into_iter()
67+
.filter_map(|(date, version)| {
68+
semver::Version::parse(&version)
69+
.ok()
70+
.map(|version| (date, version))
71+
})
72+
.collect();
6673

74+
let newest = pairs.iter().max().map(|(_, v)| v.clone());
75+
let highest = pairs.iter().map(|(_, v)| v).max().map(|v| v.clone());
6776
let highest_stable = pairs
68-
.into_iter()
77+
.iter()
6978
.map(|(_, v)| v)
7079
.filter(|v| !v.is_prerelease())
71-
.max();
80+
.max()
81+
.map(|v| v.clone());
7282

7383
Self {
7484
highest,
@@ -217,7 +227,7 @@ mod tests {
217227

218228
#[test]
219229
fn top_versions_single() {
220-
let versions = vec![(date("2020-12-03T12:34:56"), version("1.0.0"))];
230+
let versions = vec![(date("2020-12-03T12:34:56"), "1.0.0".into())];
221231
assert_eq!(
222232
TopVersions::from_date_version_pairs(versions),
223233
TopVersions {
@@ -230,7 +240,7 @@ mod tests {
230240

231241
#[test]
232242
fn top_versions_prerelease() {
233-
let versions = vec![(date("2020-12-03T12:34:56"), version("1.0.0-beta.5"))];
243+
let versions = vec![(date("2020-12-03T12:34:56"), "1.0.0-beta.5".into())];
234244
assert_eq!(
235245
TopVersions::from_date_version_pairs(versions),
236246
TopVersions {
@@ -244,10 +254,11 @@ mod tests {
244254
#[test]
245255
fn top_versions_multiple() {
246256
let versions = vec![
247-
(date("2018-12-03T12:34:56"), version("1.0.0")),
248-
(date("2019-12-03T12:34:56"), version("2.0.0-alpha.1")),
249-
(date("2020-12-03T12:34:56"), version("1.1.0")),
250-
(date("2020-12-31T12:34:56"), version("1.0.4")),
257+
(date("2018-12-03T12:34:56"), "1.0.0".into()),
258+
(date("2019-12-03T12:34:56"), "2.0.0-alpha.1".into()),
259+
(date("2020-12-01T12:34:56"), "everything is broken".into()),
260+
(date("2020-12-03T12:34:56"), "1.1.0".into()),
261+
(date("2020-12-31T12:34:56"), "1.0.4".into()),
251262
];
252263
assert_eq!(
253264
TopVersions::from_date_version_pairs(versions),

src/views.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -607,12 +607,15 @@ impl EncodableVersion {
607607
..
608608
} = version;
609609

610-
let num = num.to_string();
610+
let links = EncodableVersionLinks {
611+
dependencies: format!("/api/v1/crates/{}/{}/dependencies", crate_name, num),
612+
version_downloads: format!("/api/v1/crates/{}/{}/downloads", crate_name, num),
613+
};
611614

612615
Self {
613616
dl_path: format!("/api/v1/crates/{}/{}/download", crate_name, num),
614617
readme_path: format!("/api/v1/crates/{}/{}/readme", crate_name, num),
615-
num: num.clone(),
618+
num,
616619
id,
617620
krate: crate_name.to_string(),
618621
updated_at,
@@ -621,10 +624,7 @@ impl EncodableVersion {
621624
features,
622625
yanked,
623626
license,
624-
links: EncodableVersionLinks {
625-
dependencies: format!("/api/v1/crates/{}/{}/dependencies", crate_name, num),
626-
version_downloads: format!("/api/v1/crates/{}/{}/downloads", crate_name, num),
627-
},
627+
links,
628628
crate_size,
629629
published_by: published_by.map(User::into),
630630
audit_actions: audit_actions

0 commit comments

Comments
 (0)