Skip to content

Commit 838cb2d

Browse files
committed
Allow crate max_version to be null
This is required for the situation where the final non-yanked version is yanked leaving no non-yanked version.
1 parent 19213f3 commit 838cb2d

File tree

4 files changed

+44
-30
lines changed

4 files changed

+44
-30
lines changed

src/krate.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub struct Crate {
4444
pub updated_at: Timespec,
4545
pub created_at: Timespec,
4646
pub downloads: i32,
47-
pub max_version: semver::Version,
47+
pub max_version: Option<semver::Version>,
4848
pub description: Option<String>,
4949
pub homepage: Option<String>,
5050
pub documentation: Option<String>,
@@ -65,7 +65,7 @@ pub struct EncodableCrate {
6565
pub badges: Option<Vec<EncodableBadge>>,
6666
pub created_at: String,
6767
pub downloads: i32,
68-
pub max_version: String,
68+
pub max_version: Option<String>,
6969
pub description: Option<String>,
7070
pub homepage: Option<String>,
7171
pub documentation: Option<String>,
@@ -266,7 +266,7 @@ impl Crate {
266266
keywords: keyword_ids,
267267
categories: category_ids,
268268
badges: badges,
269-
max_version: max_version.to_string(),
269+
max_version: max_version.map(|v| v.to_string()),
270270
documentation: documentation,
271271
homepage: homepage,
272272
description: description,
@@ -384,12 +384,17 @@ impl Crate {
384384
None => {}
385385
}
386386
let zero = semver::Version::parse("0.0.0").unwrap();
387-
if *ver > self.max_version || self.max_version == zero {
388-
self.max_version = ver.clone();
387+
let new_max = match self.max_version {
388+
Some(ref max_version) if *ver > *max_version || *max_version == zero => true,
389+
_ => false,
390+
};
391+
if new_max {
392+
self.max_version = Some(ver.clone());
389393
}
390394
let stmt = conn.prepare("UPDATE crates SET max_version = $1
391395
WHERE id = $2 RETURNING updated_at")?;
392-
let rows = stmt.query(&[&self.max_version.to_string(), &self.id])?;
396+
let max_version = self.max_version.clone().map(|v| v.to_string());
397+
let rows = stmt.query(&[&max_version, &self.id])?;
393398
self.updated_at = rows.get(0).get("updated_at");
394399
Version::insert(conn, self.id, ver, features, authors)
395400
}
@@ -460,7 +465,7 @@ impl Crate {
460465

461466
impl Model for Crate {
462467
fn from_row(row: &Row) -> Crate {
463-
let max: String = row.get("max_version");
468+
let max: Option<String> = row.get("max_version");
464469
Crate {
465470
id: row.get("id"),
466471
name: row.get("name"),
@@ -471,7 +476,7 @@ impl Model for Crate {
471476
documentation: row.get("documentation"),
472477
homepage: row.get("homepage"),
473478
readme: row.get("readme"),
474-
max_version: semver::Version::parse(&max).unwrap(),
479+
max_version: max.map(|m| semver::Version::parse(&m).unwrap()),
475480
license: row.get("license"),
476481
repository: row.get("repository"),
477482
max_upload_size: row.get("max_upload_size"),

src/tests/all.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ fn krate(name: &str) -> Crate {
193193
updated_at: time::now().to_timespec(),
194194
created_at: time::now().to_timespec(),
195195
downloads: 10,
196-
max_version: semver::Version::parse("0.0.0").unwrap(),
196+
max_version: Some(semver::Version::parse("0.0.0").unwrap()),
197197
documentation: None,
198198
homepage: None,
199199
description: None,

src/tests/krate.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,8 @@ fn new_krate() {
347347
let mut response = ok_resp!(middle.call(&mut req));
348348
let json: GoodCrate = ::json(&mut response);
349349
assert_eq!(json.krate.name, "foo_new");
350-
assert_eq!(json.krate.max_version, "1.0.0");
350+
assert!(json.krate.max_version.is_some());
351+
assert_eq!(json.krate.max_version.unwrap(), "1.0.0");
351352
}
352353

353354
#[test]
@@ -360,7 +361,8 @@ fn new_krate_weird_version() {
360361
let mut response = ok_resp!(middle.call(&mut req));
361362
let json: GoodCrate = ::json(&mut response);
362363
assert_eq!(json.krate.name, "foo_weird");
363-
assert_eq!(json.krate.max_version, "0.0.0-pre");
364+
assert!(json.krate.max_version.is_some());
365+
assert_eq!(json.krate.max_version.unwrap(), "0.0.0-pre");
364366
}
365367

366368
#[test]
@@ -917,7 +919,8 @@ fn good_categories() {
917919
let mut response = ok_resp!(middle.call(&mut req));
918920
let json: GoodCrate = ::json(&mut response);
919921
assert_eq!(json.krate.name, "foo_good_cat");
920-
assert_eq!(json.krate.max_version, "1.0.0");
922+
assert!(json.krate.max_version.is_some());
923+
assert_eq!(json.krate.max_version.unwrap(), "1.0.0");
921924
assert_eq!(json.warnings.invalid_categories.len(), 0);
922925
}
923926

@@ -931,7 +934,8 @@ fn ignored_categories() {
931934
let mut response = ok_resp!(middle.call(&mut req));
932935
let json: GoodCrate = ::json(&mut response);
933936
assert_eq!(json.krate.name, "foo_ignored_cat");
934-
assert_eq!(json.krate.max_version, "1.0.0");
937+
assert!(json.krate.max_version.is_some());
938+
assert_eq!(json.krate.max_version.unwrap(), "1.0.0");
935939
assert_eq!(json.warnings.invalid_categories, vec!["bar".to_string()]);
936940
}
937941

@@ -954,7 +958,8 @@ fn good_badges() {
954958

955959
let json: GoodCrate = ::json(&mut response);
956960
assert_eq!(json.krate.name, "foobadger");
957-
assert_eq!(json.krate.max_version, "1.0.0");
961+
assert!(json.krate.max_version.is_some());
962+
assert_eq!(json.krate.max_version.unwrap(), "1.0.0");
958963

959964
let mut response = ok_resp!(
960965
middle.call(req.with_method(Method::Get)
@@ -1000,7 +1005,8 @@ fn ignored_badges() {
10001005

10011006
let json: GoodCrate = ::json(&mut response);
10021007
assert_eq!(json.krate.name, "foo_ignored_badge");
1003-
assert_eq!(json.krate.max_version, "1.0.0");
1008+
assert!(json.krate.max_version.is_some());
1009+
assert_eq!(json.krate.max_version.unwrap(), "1.0.0");
10041010
assert_eq!(json.warnings.invalid_badges.len(), 2);
10051011
assert!(json.warnings.invalid_badges.contains(&"travis-ci".to_string()));
10061012
assert!(json.warnings.invalid_badges.contains(&"not-a-badge".to_string()));

src/version.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -198,22 +198,25 @@ impl Version {
198198
&[&self.crate_id])?;
199199
let max_version = rows.iter()
200200
.next()
201-
.map(|r| r.get::<&str, String>("max_version"))
202-
.map(|v| semver::Version::parse(&v).unwrap())
203-
.unwrap();
204-
let zero = semver::Version::parse("0.0.0").unwrap();
201+
.and_then(|r| r.get::<&str, Option<String>>("max_version"))
202+
.map(|v| semver::Version::parse(&v).unwrap());
205203
let max_update_stmt = conn.prepare("UPDATE crates SET max_version = $1 WHERE id = $2")?;
206-
if yanked && max_version == self.num {
207-
let new_max = conn.query("SELECT num FROM versions \
208-
WHERE crate_id = $1 AND yanked = FALSE AND id != $2",
209-
&[&self.crate_id, &self.id])?
210-
.iter()
211-
.map(|r| r.get::<&str, String>("num"))
212-
.filter_map(|v| semver::Version::parse(&v).ok())
213-
.max()
214-
.unwrap();
215-
max_update_stmt.execute(&[&new_max.to_string(), &self.crate_id])?;
216-
} else if !yanked && (self.num > max_version || max_version == zero) {
204+
if let Some(max_version) = max_version {
205+
let zero = semver::Version::parse("0.0.0").unwrap();
206+
if yanked && max_version == self.num {
207+
let new_max = conn.query("SELECT num FROM versions \
208+
WHERE crate_id = $1 AND yanked = FALSE AND id != $2",
209+
&[&self.crate_id, &self.id])?
210+
.iter()
211+
.map(|r| r.get::<&str, String>("num"))
212+
.filter_map(|v| semver::Version::parse(&v).ok())
213+
.max();
214+
max_update_stmt.execute(&[&new_max.map(|v| v.to_string()), &self.crate_id])?;
215+
} else if !yanked && (self.num > max_version || max_version == zero) {
216+
max_update_stmt.execute(&[&self.num.to_string(), &self.crate_id])?;
217+
}
218+
} else if !yanked {
219+
// no max version, all versions yanked
217220
max_update_stmt.execute(&[&self.num.to_string(), &self.crate_id])?;
218221
}
219222

0 commit comments

Comments
 (0)