diff --git a/app/templates/crate/delete.hbs b/app/templates/crate/delete.hbs index 6c1a9e317c8..7ba82654346 100644 --- a/app/templates/crate/delete.hbs +++ b/app/templates/crate/delete.hbs @@ -20,7 +20,16 @@

Requirements:

-

A crate can only be deleted if either:

+

+ A crate can only be deleted if it is not depended upon by any other crate on crates.io. (This is a temporary + restriction due to + #10538.) +

+

Additionally, a crate can only be deleted if either:

  1. the crate has been published for less than 72 hours
@@ -29,8 +38,7 @@
    1. the crate only has a single owner, and
    2. -
    3. the crate has been downloaded less than 500 times for each month it has been published, and
    4. -
    5. the crate is not depended upon by any other crate on crates.io.
    6. +
    7. the crate has been downloaded less than 500 times for each month it has been published.
  • diff --git a/src/controllers/krate/delete.rs b/src/controllers/krate/delete.rs index 16ebaa2c707..6dfb4d7b156 100644 --- a/src/controllers/krate/delete.rs +++ b/src/controllers/krate/delete.rs @@ -94,11 +94,14 @@ pub async fn delete_crate( let msg = format!("only crates with less than {DOWNLOADS_PER_MONTH_LIMIT} downloads per month can be deleted after 72 hours"); return Err(custom(StatusCode::UNPROCESSABLE_ENTITY, msg)); } + } - if has_rev_dep(&mut conn, krate.id).await? { - let msg = "only crates without reverse dependencies can be deleted after 72 hours"; - return Err(custom(StatusCode::UNPROCESSABLE_ENTITY, msg)); - } + // Temporary hack to mitigate https://github.com/rust-lang/crates.io/issues/10538: all crates + // with reverse dependencies are currently blocked from being deleted to avoid unexpected + // historical index changes. + if has_rev_dep(&mut conn, krate.id).await? { + let msg = "only crates without reverse dependencies can be deleted"; + return Err(custom(StatusCode::UNPROCESSABLE_ENTITY, msg)); } let crate_name = krate.name.clone(); @@ -491,11 +494,9 @@ mod tests { #[tokio::test(flavor = "multi_thread")] async fn test_rev_deps() -> anyhow::Result<()> { - let (app, anon, user) = TestApp::full().with_user().await; - let mut conn = app.db_conn().await; + let (_app, anon, user) = TestApp::full().with_user().await; publish_crate(&user, "foo").await; - adjust_creation_date(&mut conn, "foo", 73).await?; // Publish another crate let pb = PublishBuilder::new("bar", "1.0.0").dependency(DependencyBuilder::new("foo")); @@ -504,7 +505,7 @@ mod tests { let response = delete_crate(&user, "foo").await; assert_eq!(response.status(), StatusCode::UNPROCESSABLE_ENTITY); - assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"only crates without reverse dependencies can be deleted after 72 hours"}]}"#); + assert_snapshot!(response.text(), @r#"{"errors":[{"detail":"only crates without reverse dependencies can be deleted"}]}"#); assert_crate_exists(&anon, "foo", true).await;