diff --git a/crates/bin/docs_rs_web/src/handlers/builds.rs b/crates/bin/docs_rs_web/src/handlers/builds.rs index b90f7909d..e5b3991e9 100644 --- a/crates/bin/docs_rs_web/src/handlers/builds.rs +++ b/crates/bin/docs_rs_web/src/handlers/builds.rs @@ -28,10 +28,10 @@ use std::sync::Arc; #[derive(Debug, Clone, PartialEq, Eq)] pub(crate) struct Build { id: BuildId, - rustc_version: Option, + pub rustc_version: Option, docsrs_version: Option, - build_status: BuildStatus, - build_time: Option>, + pub build_status: BuildStatus, + pub build_time: Option>, build_duration: Option, memory_peak: Option, errors: Option, @@ -179,7 +179,7 @@ pub(crate) async fn build_trigger_rebuild_handler( Ok((StatusCode::CREATED, Json(serde_json::json!({})))) } -async fn get_builds( +pub(super) async fn get_builds( conn: &mut sqlx::PgConnection, name: &KrateName, version: &Version, diff --git a/crates/bin/docs_rs_web/src/handlers/crate_details.rs b/crates/bin/docs_rs_web/src/handlers/crate_details.rs index 4659000b4..67409ee41 100644 --- a/crates/bin/docs_rs_web/src/handlers/crate_details.rs +++ b/crates/bin/docs_rs_web/src/handlers/crate_details.rs @@ -5,6 +5,7 @@ use crate::{ DbConnection, rustdoc::{PageKind, RustdocParams}, }, + handlers::builds::{self, Build}, impl_axum_webpage, match_release::{MatchedRelease, match_version}, metadata::MetaData, @@ -45,6 +46,7 @@ pub(crate) struct CrateDetails { build_status: BuildStatus, pub latest_build_id: Option, last_successful_build: Option, + pub latest_build: Option, pub rustdoc_status: Option, pub archive_storage: bool, pub repository_url: Option, @@ -218,6 +220,14 @@ impl CrateDetails { .map(Into::into) .collect(); + let builds = builds::get_builds(conn, &krate.name, version).await?; + let latest_build = builds + .into_iter() + .filter(|build| { + build.build_status == BuildStatus::Success && build.build_time.is_some() + }) + .max_by_key(|build| build.build_time); + let mut crate_details = CrateDetails { name: krate.name, version: version.clone(), @@ -230,6 +240,7 @@ impl CrateDetails { build_status: krate.build_status, latest_build_id: krate.latest_build_id, last_successful_build: None, + latest_build, rustdoc_status: krate.rustdoc_status, archive_storage: krate.archive_storage, repository_url: krate.repository_url, diff --git a/crates/bin/docs_rs_web/src/handlers/rustdoc.rs b/crates/bin/docs_rs_web/src/handlers/rustdoc.rs index 6518c9da3..8baebabdc 100644 --- a/crates/bin/docs_rs_web/src/handlers/rustdoc.rs +++ b/crates/bin/docs_rs_web/src/handlers/rustdoc.rs @@ -32,6 +32,7 @@ use axum_extra::{ headers::{ContentType, ETag, Header as _, HeaderMapExt as _}, typed_header::TypedHeader, }; +use chrono::{DateTime, Utc}; use docs_rs_cargo_metadata::Dependency; use docs_rs_database::Pool; use docs_rs_headers::{ETagComputer, IfNoneMatch, X_ROBOTS_TAG}; @@ -397,6 +398,8 @@ pub struct LimitedCrateDetails { dependencies: Vec, total_items: Option, documented_items: Option, + latest_build_time: Option>, + latest_build_rustc_version: Option, } impl From for LimitedCrateDetails { @@ -410,9 +413,16 @@ impl From for LimitedCrateDetails { dependencies, total_items, documented_items, + latest_build, .. } = value; + let (latest_build_time, latest_build_rustc_version) = if let Some(b) = latest_build { + (b.build_time, b.rustc_version) + } else { + (None, None) + }; + Self { total_items, documented_items, @@ -422,6 +432,8 @@ impl From for LimitedCrateDetails { repository_url, owners, dependencies, + latest_build_time, + latest_build_rustc_version, } } } diff --git a/crates/bin/docs_rs_web/templates/rustdoc/topbar.html b/crates/bin/docs_rs_web/templates/rustdoc/topbar.html index 1c2000680..736c52024 100644 --- a/crates/bin/docs_rs_web/templates/rustdoc/topbar.html +++ b/crates/bin/docs_rs_web/templates/rustdoc/topbar.html @@ -58,6 +58,13 @@ {%- endif -%} + {%- if let Some(time) = krate.latest_build_time -%} +
  • + + {{ crate::icons::IconGears.render_solid(false, false, "") }} {{ time.format("%d %B %Y") }} + +
  • + {%- endif -%}