Skip to content

Commit 8fff5f5

Browse files
committed
update latest_release_id after yank/unyank too
1 parent 533118b commit 8fff5f5

File tree

9 files changed

+116
-34
lines changed

9 files changed

+116
-34
lines changed

.sqlx/query-75310f51de2b9064c400dfa4ea16bac989fb9ce51a2efe7661c000aa6ad932d4.json

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bin/cratesfyi.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use docs_rs::{
2020
Context, Index, InstanceMetrics, PackageKind, RegistryApi, RustwideBuilder, ServiceMetrics,
2121
Storage,
2222
};
23+
use futures_util::StreamExt;
2324
use humantime::Duration;
2425
use once_cell::sync::OnceCell;
2526
use tokio::runtime::{Builder, Runtime};
@@ -486,6 +487,9 @@ enum DatabaseSubcommand {
486487
version: Option<i64>,
487488
},
488489

490+
/// temporary commant to update the `crates.latest_version_id` field
491+
UpdateLatestVersionId,
492+
489493
/// Updates Github/Gitlab stats for crates.
490494
UpdateRepositoryFields,
491495

@@ -544,6 +548,30 @@ impl DatabaseSubcommand {
544548
.context("Failed to run database migrations")?
545549
}
546550

551+
Self::UpdateLatestVersionId => {
552+
let pool = ctx.pool()?;
553+
ctx.runtime()?
554+
.block_on(async {
555+
let mut list_conn = pool.get_async().await?;
556+
let mut update_conn = pool.get_async().await?;
557+
558+
let mut result_stream =
559+
sqlx::query!("SELECT id, name FROM crates ORDER BY name")
560+
.fetch(&mut *list_conn);
561+
562+
while let Some(row) = result_stream.next().await {
563+
let row = row?;
564+
565+
println!("handling crate {}", row.name);
566+
567+
db::update_latest_version_id(&mut update_conn, row.id).await?;
568+
}
569+
570+
Ok::<(), anyhow::Error>(())
571+
})
572+
.context("Failed to update latest version id")?
573+
}
574+
547575
Self::UpdateRepositoryFields => {
548576
ctx.runtime()?
549577
.block_on(ctx.repository_stats_updater()?.update_all_crates())?;
@@ -787,6 +815,7 @@ impl Context for BinContext {
787815
self.instance_metrics()?,
788816
self.config()?,
789817
self.storage()?,
818+
self.runtime()?,
790819
);
791820
fn storage(self) -> Storage = {
792821
let runtime = self.runtime()?;

src/build_queue.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::cdn;
2-
use crate::db::{delete_crate, delete_version, Pool};
2+
use crate::db::{delete_crate, delete_version, update_latest_version_id, Pool};
33
use crate::docbuilder::PackageKind;
44
use crate::error::Result;
55
use crate::storage::Storage;
@@ -8,11 +8,10 @@ use crate::Context;
88
use crate::{Config, Index, InstanceMetrics, RustwideBuilder};
99
use anyhow::Context as _;
1010
use fn_error_context::context;
11-
12-
use tracing::{debug, error, info};
13-
1411
use std::collections::HashMap;
1512
use std::sync::Arc;
13+
use tokio::runtime::Runtime;
14+
use tracing::{debug, error, info};
1615

1716
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize)]
1817
pub(crate) struct QueuedCrate {
@@ -30,6 +29,7 @@ pub struct BuildQueue {
3029
storage: Arc<Storage>,
3130
pub(crate) db: Pool,
3231
metrics: Arc<InstanceMetrics>,
32+
runtime: Arc<Runtime>,
3333
max_attempts: i32,
3434
}
3535

@@ -39,13 +39,15 @@ impl BuildQueue {
3939
metrics: Arc<InstanceMetrics>,
4040
config: Arc<Config>,
4141
storage: Arc<Storage>,
42+
runtime: Arc<Runtime>,
4243
) -> Self {
4344
BuildQueue {
4445
max_attempts: config.build_attempts.into(),
4546
config,
4647
db,
4748
metrics,
4849
storage,
50+
runtime,
4951
}
5052
}
5153

@@ -403,16 +405,18 @@ impl BuildQueue {
403405
) -> Result<()> {
404406
let activity = if yanked { "yanked" } else { "unyanked" };
405407

406-
let rows = conn.execute(
408+
let result = conn.query(
407409
"UPDATE releases
408410
SET yanked = $3
409411
FROM crates
410412
WHERE crates.id = releases.crate_id
411413
AND name = $1
412-
AND version = $2",
414+
AND version = $2
415+
RETURNING crates.id
416+
",
413417
&[&name, &version, &yanked],
414418
)?;
415-
if rows != 1 {
419+
if result.len() != 1 {
416420
match self
417421
.has_build_queued(name, version)
418422
.context("error trying to fetch build queue")
@@ -434,6 +438,17 @@ impl BuildQueue {
434438
} else {
435439
debug!("{}-{} {}", name, version, activity);
436440
}
441+
442+
if let Some(row) = result.first() {
443+
let crate_id: i32 = row.get(0);
444+
445+
self.runtime.block_on(async {
446+
let mut conn = self.db.get_async().await?;
447+
448+
update_latest_version_id(&mut conn, crate_id).await
449+
})?;
450+
}
451+
437452
Ok(())
438453
}
439454

src/db/add_package.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ use crate::{
55
registry_api::{CrateData, CrateOwner, ReleaseData},
66
storage::CompressionAlgorithm,
77
utils::MetadataPackage,
8-
web::crate_details::CrateDetails,
8+
web::crate_details::{latest_release, releases_for_crate},
99
};
10-
use anyhow::{anyhow, Context};
10+
use anyhow::Context;
1111
use futures_util::stream::TryStreamExt;
1212
use serde_json::Value;
1313
use slug::slugify;
@@ -126,27 +126,27 @@ pub(crate) async fn add_package_into_database(
126126
add_keywords_into_database(conn, metadata_pkg, release_id).await?;
127127
add_compression_into_database(conn, compression_algorithms.into_iter(), release_id).await?;
128128

129-
let crate_details = CrateDetails::new(
130-
&mut *conn,
131-
&metadata_pkg.name,
132-
&metadata_pkg.version,
133-
&metadata_pkg.version,
134-
)
135-
.await
136-
.context("error when fetching crate-details")?
137-
.ok_or_else(|| anyhow!("crate details not found directly after creating them"))?;
129+
update_latest_version_id(&mut *conn, crate_id)
130+
.await
131+
.context("couldn't update latest version id")?;
132+
133+
Ok(release_id)
134+
}
135+
136+
pub async fn update_latest_version_id(conn: &mut sqlx::PgConnection, crate_id: i32) -> Result<()> {
137+
let releases = releases_for_crate(conn, crate_id).await?;
138138

139139
sqlx::query!(
140140
"UPDATE crates
141141
SET latest_version_id = $2
142142
WHERE id = $1",
143143
crate_id,
144-
crate_details.latest_release().id,
144+
latest_release(&releases).map(|release| release.id),
145145
)
146146
.execute(&mut *conn)
147147
.await?;
148148

149-
Ok(release_id)
149+
Ok(())
150150
}
151151

152152
pub(crate) async fn add_doc_coverage(

src/db/delete.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
use crate::error::Result;
2-
use crate::storage::{rustdoc_archive_path, source_archive_path, Storage};
3-
use crate::Config;
1+
use crate::{
2+
error::Result,
3+
storage::{rustdoc_archive_path, source_archive_path, Storage},
4+
Config,
5+
};
46
use anyhow::Context as _;
57
use fn_error_context::context;
68
use postgres::Client;

src/db/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use anyhow::Result;
33
use sqlx::migrate::{Migrate, Migrator};
44

5+
pub use self::add_package::update_latest_version_id;
56
pub(crate) use self::add_package::{
67
add_build_into_database, add_doc_coverage, add_package_into_database,
78
};

src/test/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ impl TestEnvironment {
372372
self.instance_metrics(),
373373
self.config(),
374374
self.storage(),
375+
self.runtime(),
375376
))
376377
})
377378
.clone()

src/web/crate_details.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
},
1414
AsyncStorage,
1515
};
16-
use anyhow::{Context, Result};
16+
use anyhow::{anyhow, Context, Result};
1717
use axum::{
1818
extract::{Extension, Path},
1919
response::{IntoResponse, Response as AxumResponse},
@@ -302,11 +302,19 @@ impl CrateDetails {
302302

303303
/// Returns the latest non-yanked, non-prerelease release of this crate (or latest
304304
/// yanked/prereleased if that is all that exist).
305-
pub fn latest_release(&self) -> &Release {
306-
self.releases
307-
.iter()
308-
.find(|release| release.version.pre.is_empty() && !release.yanked)
309-
.unwrap_or(&self.releases[0])
305+
pub fn latest_release(&self) -> Result<&Release> {
306+
latest_release(&self.releases).ok_or_else(|| anyhow!("crate without releases"))
307+
}
308+
}
309+
310+
pub(crate) fn latest_release(releases: &[Release]) -> Option<&Release> {
311+
if let Some(release) = releases
312+
.iter()
313+
.find(|release| release.version.pre.is_empty() && !release.yanked)
314+
{
315+
Some(release)
316+
} else {
317+
releases.first()
310318
}
311319
}
312320

@@ -996,7 +1004,7 @@ mod tests {
9961004
.unwrap()
9971005
});
9981006
assert_eq!(
999-
details.latest_release().version,
1007+
details.latest_release().unwrap().version,
10001008
semver::Version::parse("0.0.3")?
10011009
);
10021010
}
@@ -1026,7 +1034,7 @@ mod tests {
10261034
.unwrap()
10271035
});
10281036
assert_eq!(
1029-
details.latest_release().version,
1037+
details.latest_release().unwrap().version,
10301038
semver::Version::parse("0.0.2")?
10311039
);
10321040
}
@@ -1057,7 +1065,7 @@ mod tests {
10571065
.unwrap()
10581066
});
10591067
assert_eq!(
1060-
details.latest_release().version,
1068+
details.latest_release().unwrap().version,
10611069
semver::Version::parse("0.0.2")?
10621070
);
10631071
}
@@ -1096,7 +1104,7 @@ mod tests {
10961104
.unwrap()
10971105
});
10981106
assert_eq!(
1099-
details.latest_release().version,
1107+
details.latest_release().unwrap().version,
11001108
semver::Version::parse("0.0.3")?
11011109
);
11021110
}

src/web/rustdoc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ pub(crate) async fn rustdoc_html_server_handler(
562562

563563
rendering_time.step("find latest path");
564564

565-
let latest_release = krate.latest_release();
565+
let latest_release = krate.latest_release()?;
566566

567567
// Get the latest version of the crate
568568
let latest_version = latest_release.version.to_string();

0 commit comments

Comments
 (0)