Skip to content

Commit 822811a

Browse files
committed
don't delete full crates from docs.rs when only a version was deleted from the index
1 parent eb80347 commit 822811a

File tree

4 files changed

+67
-21
lines changed

4 files changed

+67
-21
lines changed

src/bin/cratesfyi.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -554,9 +554,14 @@ impl DatabaseSubcommand {
554554

555555
Self::Delete {
556556
command: DeleteSubcommand::Version { name, version },
557-
} => {
558-
db::delete_version(&ctx, &name, &version).context("failed to delete the version")?
559-
}
557+
} => db::delete_version(
558+
&mut *ctx.pool()?.get()?,
559+
&*ctx.storage()?,
560+
&*ctx.config()?,
561+
&name,
562+
&version,
563+
)
564+
.context("failed to delete the version")?,
560565
Self::Delete {
561566
command: DeleteSubcommand::Crate { name },
562567
} => db::delete_crate(

src/build_queue.rs

+46-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::cdn;
2-
use crate::db::{delete_crate, Pool};
2+
use crate::db::{delete_crate, delete_version, Pool};
33
use crate::docbuilder::PackageKind;
44
use crate::error::Result;
55
use crate::storage::Storage;
@@ -283,16 +283,52 @@ impl BuildQueue {
283283
changes.reverse();
284284

285285
for change in &changes {
286-
if let Some((ref krate, ..)) = change.deleted() {
287-
match delete_crate(&mut conn, &self.storage, &self.config, krate)
288-
.with_context(|| format!("failed to delete crate {krate}"))
289-
{
290-
Ok(_) => info!(
291-
"crate {} was deleted from the index and the database",
292-
krate
293-
),
294-
Err(err) => report_error(&err),
286+
if let Some((ref krate, versions)) = change.deleted() {
287+
for version in versions {
288+
let version = version.version.as_str();
289+
match delete_version(&mut conn, &self.storage, &self.config, krate, version)
290+
.with_context(|| format!("failed to delete version {krate} {version}"))
291+
{
292+
Ok(_) => info!(
293+
"version {} {} was deleted from the index and the database",
294+
krate, version,
295+
),
296+
Err(err) => report_error(&err),
297+
}
295298
}
299+
300+
// FIXME: Change::Deleted (and `.deleted()`) is documented to be only crate-deletes,
301+
// but can also be one or multiple version-deletes.
302+
// Until crates-index-diff can separately emit crate- or version-deletes,
303+
// we try to figure this out here.
304+
let versions_remaining: i32 = conn
305+
.query_one(
306+
"
307+
SELECT
308+
COUNT(*)
309+
FROM
310+
crates
311+
INNER JOIN releases ON crates.id = releases.crate_id
312+
WHERE
313+
crates.name = $1
314+
",
315+
&[&krate],
316+
)
317+
.with_context(|| format!("could not fetch version count for crate {krate}"))?
318+
.get(0);
319+
320+
if versions_remaining == 0 {
321+
match delete_crate(&mut conn, &self.storage, &self.config, krate)
322+
.with_context(|| format!("failed to delete crate {krate}"))
323+
{
324+
Ok(_) => info!(
325+
"crate {} was deleted from the index and the database",
326+
krate
327+
),
328+
Err(err) => report_error(&err),
329+
}
330+
}
331+
296332
if let Err(err) = cdn::queue_crate_invalidation(&mut *conn, &self.config, krate) {
297333
report_error(&err);
298334
}

src/db/delete.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::error::Result;
22
use crate::storage::{rustdoc_archive_path, source_archive_path, Storage};
3-
use crate::{Config, Context};
3+
use crate::Config;
44
use anyhow::Context as _;
55
use fn_error_context::context;
66
use postgres::Client;
@@ -55,10 +55,13 @@ pub fn delete_crate(
5555
}
5656

5757
#[context("error trying to delete release {name}-{version} from database")]
58-
pub fn delete_version(ctx: &dyn Context, name: &str, version: &str) -> Result<()> {
59-
let conn = &mut ctx.pool()?.get()?;
60-
let storage = ctx.storage()?;
61-
58+
pub fn delete_version(
59+
conn: &mut Client,
60+
storage: &Storage,
61+
config: &Config,
62+
name: &str,
63+
version: &str,
64+
) -> Result<()> {
6265
let is_library = delete_version_from_database(conn, name, version)?;
6366
let paths = if is_library {
6467
LIBRARY_STORAGE_PATHS_TO_DELETE
@@ -70,7 +73,7 @@ pub fn delete_version(ctx: &dyn Context, name: &str, version: &str) -> Result<()
7073
storage.delete_prefix(&format!("{prefix}/{name}/{version}/"))?;
7174
}
7275

73-
let local_archive_cache = &ctx.config()?.local_archive_cache_path;
76+
let local_archive_cache = &config.local_archive_cache_path;
7477
let mut paths = vec![source_archive_path(name, version)];
7578
if is_library {
7679
paths.push(rustdoc_archive_path(name, version));
@@ -359,7 +362,7 @@ mod tests {
359362
vec!["Peter Rabbit".to_string()]
360363
);
361364

362-
delete_version(env, "a", "1.0.0")?;
365+
delete_version(&mut db.conn(), &env.storage(), &env.config(), "a", "1.0.0")?;
363366
assert!(!release_exists(&mut db.conn(), v1)?);
364367
if archive_storage {
365368
// for archive storage the archive and index files

src/utils/consistency/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ where
111111
}
112112
diff::Difference::ReleaseNotInIndex(name, version) => {
113113
if !dry_run {
114-
if let Err(err) = delete::delete_version(ctx, name, version) {
114+
if let Err(err) =
115+
delete::delete_version(&mut conn, &storage, &config, name, version)
116+
{
115117
warn!("{:?}", err);
116118
}
117119
}

0 commit comments

Comments
 (0)