diff --git a/.sqlx/query-2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d.json b/.sqlx/query-2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d.json deleted file mode 100644 index 20591e34a..000000000 --- a/.sqlx/query-2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n dr.avg_duration AS \"avg_build_duration_release?: Duration\",\n dc.avg_duration AS \"avg_build_duration_crate?: Duration\"\n FROM\n build_durations_release AS dr\n INNER JOIN build_durations_crate AS dc on dr.crate_id = dc.crate_id\n WHERE rid = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "avg_build_duration_release?: Duration", - "type_info": "Interval" - }, - { - "ordinal": 1, - "name": "avg_build_duration_crate?: Duration", - "type_info": "Interval" - } - ], - "parameters": { - "Left": [ - "Int4" - ] - }, - "nullable": [ - true, - true - ] - }, - "hash": "2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d" -} diff --git a/crates/bin/docs_rs_web/.sqlx/query-e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120.json b/.sqlx/query-b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee.json similarity index 66% rename from crates/bin/docs_rs_web/.sqlx/query-e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120.json rename to .sqlx/query-b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee.json index 0e487319a..26969a794 100644 --- a/crates/bin/docs_rs_web/.sqlx/query-e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120.json +++ b/.sqlx/query-b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n builds.id as \"id: BuildId\",\n builds.rustc_version,\n builds.docsrs_version,\n builds.build_status as \"build_status: BuildStatus\",\n COALESCE(builds.build_finished, builds.build_started) as build_time,\n durations.duration AS \"build_duration?: Duration\",\n builds.errors\n FROM builds\n INNER JOIN build_durations AS durations ON durations.build_id = builds.id\n INNER JOIN releases ON releases.id = builds.rid\n INNER JOIN crates ON releases.crate_id = crates.id\n WHERE\n crates.name = $1 AND\n releases.version = $2\n ORDER BY builds.id DESC", + "query": "SELECT\n builds.id as \"id: BuildId\",\n builds.rustc_version,\n builds.docsrs_version,\n builds.build_status as \"build_status: BuildStatus\",\n COALESCE(builds.build_finished, builds.build_started) as build_time,\n builds.errors\n FROM builds\n INNER JOIN releases ON releases.id = builds.rid\n INNER JOIN crates ON releases.crate_id = crates.id\n WHERE\n crates.name = $1 AND\n releases.version = $2\n ORDER BY builds.id DESC", "describe": { "columns": [ { @@ -41,11 +41,6 @@ }, { "ordinal": 5, - "name": "build_duration?: Duration", - "type_info": "Interval" - }, - { - "ordinal": 6, "name": "errors", "type_info": "Text" } @@ -62,9 +57,8 @@ true, false, null, - true, true ] }, - "hash": "e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120" + "hash": "b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee" } diff --git a/Cargo.lock b/Cargo.lock index 39bdc4d98..681b56f76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2335,7 +2335,6 @@ dependencies = [ "sqlx", "strum", "test-case", - "thiserror 2.0.17", "tokio", ] diff --git a/crates/bin/cratesfyi/.sqlx/query-2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d.json b/crates/bin/cratesfyi/.sqlx/query-2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d.json deleted file mode 100644 index 20591e34a..000000000 --- a/crates/bin/cratesfyi/.sqlx/query-2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n dr.avg_duration AS \"avg_build_duration_release?: Duration\",\n dc.avg_duration AS \"avg_build_duration_crate?: Duration\"\n FROM\n build_durations_release AS dr\n INNER JOIN build_durations_crate AS dc on dr.crate_id = dc.crate_id\n WHERE rid = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "avg_build_duration_release?: Duration", - "type_info": "Interval" - }, - { - "ordinal": 1, - "name": "avg_build_duration_crate?: Duration", - "type_info": "Interval" - } - ], - "parameters": { - "Left": [ - "Int4" - ] - }, - "nullable": [ - true, - true - ] - }, - "hash": "2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d" -} diff --git a/.sqlx/query-e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120.json b/crates/bin/cratesfyi/.sqlx/query-b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee.json similarity index 66% rename from .sqlx/query-e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120.json rename to crates/bin/cratesfyi/.sqlx/query-b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee.json index 0e487319a..26969a794 100644 --- a/.sqlx/query-e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120.json +++ b/crates/bin/cratesfyi/.sqlx/query-b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n builds.id as \"id: BuildId\",\n builds.rustc_version,\n builds.docsrs_version,\n builds.build_status as \"build_status: BuildStatus\",\n COALESCE(builds.build_finished, builds.build_started) as build_time,\n durations.duration AS \"build_duration?: Duration\",\n builds.errors\n FROM builds\n INNER JOIN build_durations AS durations ON durations.build_id = builds.id\n INNER JOIN releases ON releases.id = builds.rid\n INNER JOIN crates ON releases.crate_id = crates.id\n WHERE\n crates.name = $1 AND\n releases.version = $2\n ORDER BY builds.id DESC", + "query": "SELECT\n builds.id as \"id: BuildId\",\n builds.rustc_version,\n builds.docsrs_version,\n builds.build_status as \"build_status: BuildStatus\",\n COALESCE(builds.build_finished, builds.build_started) as build_time,\n builds.errors\n FROM builds\n INNER JOIN releases ON releases.id = builds.rid\n INNER JOIN crates ON releases.crate_id = crates.id\n WHERE\n crates.name = $1 AND\n releases.version = $2\n ORDER BY builds.id DESC", "describe": { "columns": [ { @@ -41,11 +41,6 @@ }, { "ordinal": 5, - "name": "build_duration?: Duration", - "type_info": "Interval" - }, - { - "ordinal": 6, "name": "errors", "type_info": "Text" } @@ -62,9 +57,8 @@ true, false, null, - true, true ] }, - "hash": "e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120" + "hash": "b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee" } diff --git a/crates/bin/docs_rs_web/.sqlx/query-2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d.json b/crates/bin/docs_rs_web/.sqlx/query-2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d.json deleted file mode 100644 index 20591e34a..000000000 --- a/crates/bin/docs_rs_web/.sqlx/query-2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n dr.avg_duration AS \"avg_build_duration_release?: Duration\",\n dc.avg_duration AS \"avg_build_duration_crate?: Duration\"\n FROM\n build_durations_release AS dr\n INNER JOIN build_durations_crate AS dc on dr.crate_id = dc.crate_id\n WHERE rid = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "avg_build_duration_release?: Duration", - "type_info": "Interval" - }, - { - "ordinal": 1, - "name": "avg_build_duration_crate?: Duration", - "type_info": "Interval" - } - ], - "parameters": { - "Left": [ - "Int4" - ] - }, - "nullable": [ - true, - true - ] - }, - "hash": "2d8f2d5c887fef11e3184d48181cb7a54564002de4c5728b254488f9a2470d1d" -} diff --git a/crates/bin/cratesfyi/.sqlx/query-e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120.json b/crates/bin/docs_rs_web/.sqlx/query-b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee.json similarity index 66% rename from crates/bin/cratesfyi/.sqlx/query-e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120.json rename to crates/bin/docs_rs_web/.sqlx/query-b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee.json index 0e487319a..26969a794 100644 --- a/crates/bin/cratesfyi/.sqlx/query-e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120.json +++ b/crates/bin/docs_rs_web/.sqlx/query-b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n builds.id as \"id: BuildId\",\n builds.rustc_version,\n builds.docsrs_version,\n builds.build_status as \"build_status: BuildStatus\",\n COALESCE(builds.build_finished, builds.build_started) as build_time,\n durations.duration AS \"build_duration?: Duration\",\n builds.errors\n FROM builds\n INNER JOIN build_durations AS durations ON durations.build_id = builds.id\n INNER JOIN releases ON releases.id = builds.rid\n INNER JOIN crates ON releases.crate_id = crates.id\n WHERE\n crates.name = $1 AND\n releases.version = $2\n ORDER BY builds.id DESC", + "query": "SELECT\n builds.id as \"id: BuildId\",\n builds.rustc_version,\n builds.docsrs_version,\n builds.build_status as \"build_status: BuildStatus\",\n COALESCE(builds.build_finished, builds.build_started) as build_time,\n builds.errors\n FROM builds\n INNER JOIN releases ON releases.id = builds.rid\n INNER JOIN crates ON releases.crate_id = crates.id\n WHERE\n crates.name = $1 AND\n releases.version = $2\n ORDER BY builds.id DESC", "describe": { "columns": [ { @@ -41,11 +41,6 @@ }, { "ordinal": 5, - "name": "build_duration?: Duration", - "type_info": "Interval" - }, - { - "ordinal": 6, "name": "errors", "type_info": "Text" } @@ -62,9 +57,8 @@ true, false, null, - true, true ] }, - "hash": "e7979edad0ebdbc61e7abc790ff2c1ee3d5a3831bc42e318f5c29cbf8aa6b120" + "hash": "b7d805d65e97349dde8ac57e176bc92ae7ef49af5b09b0fc532f763947bd1aee" } diff --git a/crates/bin/docs_rs_web/Cargo.toml b/crates/bin/docs_rs_web/Cargo.toml index 6c9b4a960..4831675aa 100644 --- a/crates/bin/docs_rs_web/Cargo.toml +++ b/crates/bin/docs_rs_web/Cargo.toml @@ -100,3 +100,4 @@ pretty_assertions = { workspace = true } tempfile = { workspace = true } test-case = { workspace = true } walkdir = { workspace = true } + diff --git a/crates/bin/docs_rs_web/src/handlers/builds.rs b/crates/bin/docs_rs_web/src/handlers/builds.rs index 31113f75a..70d3aba22 100644 --- a/crates/bin/docs_rs_web/src/handlers/builds.rs +++ b/crates/bin/docs_rs_web/src/handlers/builds.rs @@ -21,7 +21,7 @@ use docs_rs_build_limits::Limits; use docs_rs_build_queue::{AsyncBuildQueue, PRIORITY_MANUAL_FROM_CRATES_IO}; use docs_rs_context::Context; use docs_rs_headers::CanonicalUrl; -use docs_rs_types::{BuildId, BuildStatus, Duration, KrateName, ReqVersion, Version}; +use docs_rs_types::{BuildId, BuildStatus, KrateName, ReqVersion, Version}; use http::StatusCode; use std::sync::Arc; @@ -32,7 +32,6 @@ pub(crate) struct Build { docsrs_version: Option, build_status: BuildStatus, build_time: Option>, - build_duration: Option, errors: Option, } @@ -196,10 +195,8 @@ async fn get_builds( builds.docsrs_version, builds.build_status as "build_status: BuildStatus", COALESCE(builds.build_finished, builds.build_started) as build_time, - durations.duration AS "build_duration?: Duration", builds.errors FROM builds - INNER JOIN build_durations AS durations ON durations.build_id = builds.id INNER JOIN releases ON releases.id = builds.rid INNER JOIN crates ON releases.crate_id = crates.id WHERE @@ -533,14 +530,14 @@ mod tests { }; Overrides::save(&mut conn, &FOO, limits).await?; - let page = kuchikiki::parse_html().one(dbg!( + let page = kuchikiki::parse_html().one( env.web_app() .await - .assert_success(&format!("/crate/foo/{V1}/builds")) + .get(&format!("/crate/foo/{V1}/builds")) .await? .text() - .await? - )); + .await?, + ); let header = page.select(".about h4").unwrap().next().unwrap(); assert_eq!(header.text_contents(), "foo's sandbox limits"); @@ -553,7 +550,7 @@ mod tests { let values: Vec<_> = values.iter().map(|v| &**v).collect(); assert!(values.contains(&"6.44 GB")); - assert!(values.contains(&"2h")); + assert!(values.contains(&"2 hours")); assert!(values.contains(&"102.4 kB")); assert!(values.contains(&"blocked")); assert!(values.contains(&"1")); 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 69e47e229..5e7884661 100644 --- a/crates/bin/docs_rs_web/src/handlers/crate_details.rs +++ b/crates/bin/docs_rs_web/src/handlers/crate_details.rs @@ -23,9 +23,7 @@ use docs_rs_database::crate_details::{Release, latest_release, parse_doc_targets use docs_rs_headers::CanonicalUrl; use docs_rs_registry_api::OwnerKind; use docs_rs_storage::{AsyncStorage, PathNotFoundError}; -use docs_rs_types::{ - BuildId, BuildStatus, CrateId, Duration, KrateName, ReleaseId, ReqVersion, Version, -}; +use docs_rs_types::{BuildId, BuildStatus, CrateId, KrateName, ReleaseId, ReqVersion, Version}; use futures_util::stream::TryStreamExt; use serde_json::Value; use std::sync::Arc; @@ -344,40 +342,6 @@ impl CrateDetails { } } -#[derive(Debug, Clone, Default)] -struct BuildStatistics { - avg_build_duration_release: Option, - avg_build_duration_crate: Option, -} - -impl BuildStatistics { - fn has_data(&self) -> bool { - self.avg_build_duration_crate.is_some() || self.avg_build_duration_release.is_some() - } - - async fn fetch_for_release( - conn: &mut sqlx::PgConnection, - release_id: ReleaseId, - ) -> Result { - Ok(sqlx::query_as!( - BuildStatistics, - r#" - SELECT - dr.avg_duration AS "avg_build_duration_release?: Duration", - dc.avg_duration AS "avg_build_duration_crate?: Duration" - FROM - build_durations_release AS dr - INNER JOIN build_durations_crate AS dc on dr.crate_id = dc.crate_id - WHERE rid = $1 - "#, - release_id as _, - ) - .fetch_optional(conn) - .await? - .unwrap_or_default()) - } -} - #[derive(Debug, Clone, Template)] #[template(path = "crate/details.html")] struct CrateDetailsPage { @@ -388,7 +352,6 @@ struct CrateDetailsPage { documented_items: Option, total_items: Option, total_items_needing_examples: Option, - build_statistics: BuildStatistics, items_with_examples: Option, homepage_url: Option, documentation_url: Option, @@ -455,9 +418,6 @@ pub(crate) async fn crate_details_handler( Err(e) => warn!(?e, "error fetching readme"), } - let build_statistics = - BuildStatistics::fetch_for_release(&mut conn, details.release_id).await?; - let CrateDetails { version, name, @@ -494,7 +454,6 @@ pub(crate) async fn crate_details_handler( documented_items, total_items, total_items_needing_examples, - build_statistics, items_with_examples, homepage_url, documentation_url, @@ -685,7 +644,6 @@ mod tests { use docs_rs_registry_api::CrateOwner; use docs_rs_test_fakes::{FakeBuild, fake_release_that_failed_before_build}; use docs_rs_types::KrateName; - use docs_rs_types::testing::{FOO, V1}; use http::StatusCode; use kuchikiki::traits::TendrilSink; use pretty_assertions::assert_eq; @@ -2353,45 +2311,4 @@ path = "src/lib.rs" Ok(()) }); } - - #[tokio::test(flavor = "multi_thread")] - async fn test_build_stats_no_data() -> Result<()> { - let env = TestEnvironment::new().await?; - let mut conn = env.async_conn().await?; - - let stats = BuildStatistics::fetch_for_release(&mut conn, ReleaseId(42)).await?; - assert!(!stats.has_data()); - assert!(stats.avg_build_duration_release.is_none()); - assert!(stats.avg_build_duration_crate.is_none()); - - Ok(()) - } - - #[tokio::test(flavor = "multi_thread")] - async fn test_build_stats_with_build() -> Result<()> { - let env = TestEnvironment::new().await?; - - let rid = env - .fake_release() - .await - .name(&FOO) - .version(V1) - .create() - .await?; - - let mut conn = env.async_conn().await?; - - let stats = BuildStatistics::fetch_for_release(&mut conn, rid).await?; - assert!(stats.has_data()); - assert!(stats.avg_build_duration_release.is_some()); - assert!(stats.avg_build_duration_crate.is_some()); - - assert!( - !BuildStatistics::fetch_for_release(&mut conn, ReleaseId(42)) - .await? - .has_data() - ); - - Ok(()) - } } diff --git a/crates/bin/docs_rs_web/src/page/templates.rs b/crates/bin/docs_rs_web/src/page/templates.rs index 7c8288366..760861da9 100644 --- a/crates/bin/docs_rs_web/src/page/templates.rs +++ b/crates/bin/docs_rs_web/src/page/templates.rs @@ -94,7 +94,6 @@ pub mod filters { use chrono::{DateTime, Utc}; use std::borrow::Cow; use std::fmt::Display; - use std::time::Duration; pub fn escape_html_inner(input: &str) -> askama::Result { if !input.chars().any(|c| "&<>\"'/".contains(c)) { @@ -151,26 +150,27 @@ pub mod filters { } #[askama::filter_fn] - pub fn format_duration(duration: &Duration, _: &dyn Values) -> askama::Result> { - let mut secs = duration.as_secs(); + pub fn format_secs(mut value: f32, _: &dyn Values) -> askama::Result { + const TIMES: &[&str] = &["seconds", "minutes", "hours"]; - let hours = secs / 3_600; - secs %= 3_600; - let minutes = secs / 60; - let seconds = secs % 60; + let mut chosen_time = &TIMES[0]; - let mut parts = Vec::new(); - if hours > 0 { - parts.push(format!("{hours}h")); - } - if minutes > 0 { - parts.push(format!("{minutes}m")); + for time in &TIMES[1..] { + if value / 60.0 >= 1.0 { + chosen_time = time; + value /= 60.0; + } else { + break; + } } - if seconds > 0 || parts.is_empty() { - parts.push(format!("{seconds}s")); + + // TODO: This formatting section can be optimized, two string allocations aren't needed + let mut value = format!("{value:.1}"); + if value.ends_with(".0") { + value.truncate(value.len() - 2); } - Ok(Safe(parts.join(" "))) + Ok(format!("{value} {chosen_time}")) } /// Dedent a string by removing all leading whitespace @@ -299,25 +299,3 @@ fn render( askama::filters::Safe(icon) } - -#[cfg(test)] -mod tests { - use super::*; - use std::{any::Any, collections::HashMap, time::Duration}; - use test_case::test_case; - - #[test_case(Duration::from_secs(0) => "0s"; "zero")] - #[test_case(Duration::from_secs(1) => "1s"; "simple")] - #[test_case(Duration::from_micros(2123456) => "2s"; "cuts microseconds")] - #[test_case(Duration::from_secs(3723) => "1h 2m 3s"; "hours minutes seconds")] - #[test_case(Duration::from_secs(120) => "2m"; "just minutes")] - #[test_case(Duration::from_secs(2123456) => "589h 50m 56s"; "big")] - fn test_format_duration(duration: Duration) -> String { - let values: HashMap<&str, Box> = HashMap::new(); - - filters::format_duration::default() - .execute(&duration, &values) - .unwrap() - .to_string() - } -} diff --git a/crates/bin/docs_rs_web/templates/crate/builds.html b/crates/bin/docs_rs_web/templates/crate/builds.html index 087bfe2c2..27647c079 100644 --- a/crates/bin/docs_rs_web/templates/crate/builds.html +++ b/crates/bin/docs_rs_web/templates/crate/builds.html @@ -30,6 +30,7 @@
    +
  • {%- for build in builds -%}
  • {%- if build.build_status != "in_progress" -%} @@ -44,14 +45,14 @@ {{ crate::icons::IconX.render_solid(false, false, "") }} {%- endif -%} {#- -#} -
    +
    {%- if let Some(rustc_version) = build.rustc_version -%} {{ rustc_version }} {%- else -%} — {%- endif -%}
    {#- -#} -
    +
    {%- if let Some(docsrs_version) = build.docsrs_version -%} {{ docsrs_version }} {%- else -%} @@ -64,14 +65,7 @@ {%- else -%} — {%- endif -%} -
    -
    - {%- if let Some(build_duration) = build.build_duration -%} - took {{ build_duration|format_duration }} - {%- else -%} - — - {%- endif -%} -
    +
    {#- -#}
    {#- -#} {%- else -%} @@ -80,21 +74,8 @@
    {{- crate::icons::IconGear.render_solid(false, true, "") -}}
    {#- -#} -
    {#- -#} - in progress {#- -#} -
    -
    - — -
    {#- -#} -
    - — -
    {#- -#} -
    - {%- if let Some(build_duration) = build.build_duration -%} - since {{ build_duration|format_duration }} - {%- else -%} - — - {%- endif -%} +
    {#- -#} + In the build queue {#- -#}
    @@ -130,4 +111,3 @@

    {{ metadata.name }}'s sandbox limits

    {%- endblock body -%} - diff --git a/crates/bin/docs_rs_web/templates/crate/details.html b/crates/bin/docs_rs_web/templates/crate/details.html index 12bb565f6..555962e38 100644 --- a/crates/bin/docs_rs_web/templates/crate/details.html +++ b/crates/bin/docs_rs_web/templates/crate/details.html @@ -39,41 +39,17 @@ {%- if let Some(source_size) = source_size -%}
  • Size
  • - Source code size: {{(*source_size)|filesizeformat}} - {{- crate::icons::IconCircleInfo.render_solid(false, false, "") -}} - This is the summed size of all the files inside the crates.io package for this release. - + Source code size: {{(*source_size)|filesizeformat}} + {{- crate::icons::IconCircleInfo.render_solid(false, false, "") -}} + This is the summed size of all the files inside the crates.io package for this release.
  • {%- if let Some(doc_size) = documentation_size -%}
  • - Documentation size: {{(*doc_size)|filesizeformat}} - {{- crate::icons::IconCircleInfo.render_solid(false, false, "") -}} - This is the summed size of all files generated by rustdoc for all configured targets - - -
  • - {%- endif -%} - {%- endif -%} - - {%- if build_statistics.has_data() -%} -
  • Ø build duration
  • - {%- if let Some(duration) = build_statistics.avg_build_duration_release -%} -
  • - this release: {{duration|format_duration}} - {{- crate::icons::IconCircleInfo.render_solid(false, false, "") -}} - Average build duration of successful builds. - - -
  • - {%- endif -%} - {%- if let Some(duration) = build_statistics.avg_build_duration_crate -%} -
  • - all releases: {{duration|format_duration}} - {{- crate::icons::IconCircleInfo.render_solid(false, false, "") -}} - Average build duration of successful builds. - - + Documentation size: {{(*doc_size)|filesizeformat}} + {{- crate::icons::IconCircleInfo.render_solid(false, false, "") -}} + This is the summed size of all files generated by rustdoc for all configured targets +
  • {%- endif -%} {%- endif -%} diff --git a/crates/bin/docs_rs_web/templates/macros.html b/crates/bin/docs_rs_web/templates/macros.html index 95c43cc56..c6d3d10e3 100644 --- a/crates/bin/docs_rs_web/templates/macros.html +++ b/crates/bin/docs_rs_web/templates/macros.html @@ -41,7 +41,7 @@ Maximum rustdoc execution time - {{ limits.timeout|format_duration }} + {{ limits.timeout.as_secs_f32()|format_secs }} diff --git a/crates/bin/docs_rs_web/templates/style/style.scss b/crates/bin/docs_rs_web/templates/style/style.scss index ac8eb7faf..dd5ec025f 100644 --- a/crates/bin/docs_rs_web/templates/style/style.scss +++ b/crates/bin/docs_rs_web/templates/style/style.scss @@ -386,8 +386,7 @@ div.recent-releases-container { } } - .date, - .duration { + .date { font-weight: normal; @media #{$media-sm} { diff --git a/crates/lib/docs_rs_database/migrations/20260111133536_build-durations.down.sql b/crates/lib/docs_rs_database/migrations/20260111133536_build-durations.down.sql deleted file mode 100644 index df6533a78..000000000 --- a/crates/lib/docs_rs_database/migrations/20260111133536_build-durations.down.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP VIEW build_durations_crate; -DROP VIEW build_durations_release; -DROP VIEW build_durations; diff --git a/crates/lib/docs_rs_database/migrations/20260111133536_build-durations.up.sql b/crates/lib/docs_rs_database/migrations/20260111133536_build-durations.up.sql deleted file mode 100644 index fd6dbd2ed..000000000 --- a/crates/lib/docs_rs_database/migrations/20260111133536_build-durations.up.sql +++ /dev/null @@ -1,57 +0,0 @@ -CREATE VIEW build_durations AS - -SELECT - b.id AS build_id, - CASE - -- for old builds, `build_started` is empty. - WHEN b.build_started IS NULL - THEN NULL - ELSE - CASE - -- for in-progress builds we show the duration until now - WHEN b.build_finished IS NULL - THEN (CURRENT_TIMESTAMP - b.build_started) - -- for finished builds we can show the full duration - ELSE (b.build_finished - b.build_started) - END - END AS duration -FROM - builds AS b -; - -CREATE VIEW build_durations_release AS - -SELECT - r.crate_id, - b.rid, - AVG(bd.duration) AS avg_duration - -FROM - releases AS r -INNER JOIN builds AS b ON r.id = b.rid -INNER JOIN build_durations AS bd ON b.id = bd.build_id - -WHERE - b.build_status = 'success' AND - b.build_started IS NOT NULL - -GROUP BY r.crate_id, b.rid -; - -CREATE VIEW build_durations_crate AS - -SELECT - r.crate_id, - AVG(bd.duration) AS avg_duration - -FROM - releases AS r -INNER JOIN builds AS b ON r.id = b.rid -INNER JOIN build_durations AS bd ON b.id = bd.build_id - -WHERE - b.build_status = 'success' AND - b.build_started IS NOT NULL - -GROUP BY r.crate_id -; diff --git a/crates/lib/docs_rs_types/Cargo.toml b/crates/lib/docs_rs_types/Cargo.toml index d3f7f6ea8..eb4949b45 100644 --- a/crates/lib/docs_rs_types/Cargo.toml +++ b/crates/lib/docs_rs_types/Cargo.toml @@ -20,7 +20,6 @@ serde_json = { workspace = true } serde_with = { workspace = true } sqlx = { workspace = true } strum = { workspace = true } -thiserror = { workspace = true } [dev-dependencies] pretty_assertions = { workspace = true } diff --git a/crates/lib/docs_rs_types/src/convert/mod.rs b/crates/lib/docs_rs_types/src/convert/mod.rs deleted file mode 100644 index 9ad5d5996..000000000 --- a/crates/lib/docs_rs_types/src/convert/mod.rs +++ /dev/null @@ -1,86 +0,0 @@ -use sqlx::postgres::types::PgInterval; -use std::time::Duration; - -#[derive(Debug, thiserror::Error)] -pub enum IntervalError { - #[error("months not supported")] - MonthsNotSupported, - #[error("negative duration")] - NegativeDuration, - #[error("duration too large")] - DurationTooLarge, -} - -pub(crate) fn interval_to_duration(interval: PgInterval) -> Result { - if interval.months != 0 { - return Err(IntervalError::MonthsNotSupported); - } - - if interval.days < 0 || interval.microseconds < 0 { - return Err(IntervalError::NegativeDuration); - } - - Ok(Duration::from_hours(interval.days as u64 * 24) - + Duration::from_micros(interval.microseconds as u64)) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_month_is_invalid() { - let interval = PgInterval { - months: 1, - days: 0, - microseconds: 0, - }; - let result = interval_to_duration(interval); - assert!(matches!(result, Err(IntervalError::MonthsNotSupported))); - } - - #[test] - fn test_negative_day_is_invalid() { - let interval = PgInterval { - months: 0, - days: -1, - microseconds: 0, - }; - let result = interval_to_duration(interval); - assert!(matches!(result, Err(IntervalError::NegativeDuration))); - } - - #[test] - fn test_negative_ms_is_invalid() { - let interval = PgInterval { - months: 0, - days: 0, - microseconds: -1, - }; - let result = interval_to_duration(interval); - assert!(matches!(result, Err(IntervalError::NegativeDuration))); - } - - #[test] - fn test_simple_conversion() { - let interval = PgInterval { - months: 0, - days: 1, - microseconds: 1_000_000, - }; - let result = interval_to_duration(interval).unwrap(); - assert_eq!(result, Duration::from_secs(86401)); - } - - #[test] - fn test_with_microseconds_conversion() { - const MICROS: i64 = 1_123_456; - let interval = PgInterval { - months: 0, - days: 0, - microseconds: MICROS, - }; - let result = interval_to_duration(interval).unwrap(); - assert_eq!(result, Duration::from_micros(MICROS as u64)); - } -} diff --git a/crates/lib/docs_rs_types/src/duration.rs b/crates/lib/docs_rs_types/src/duration.rs deleted file mode 100644 index d19dae15d..000000000 --- a/crates/lib/docs_rs_types/src/duration.rs +++ /dev/null @@ -1,52 +0,0 @@ -mod duration_impl { - use anyhow::Result; - use derive_more::{Deref, From, Into}; - use sqlx::postgres::types::PgInterval; - use sqlx::{ - Postgres, - error::BoxDynError, - postgres::{PgTypeInfo, PgValueRef}, - prelude::*, - }; - use std::time::Duration as StdDuration; - - /// NewType around std Duration to be able to use it with sqlx. - /// - /// For now only for decoding intervals from the database. - #[derive(Clone, Debug, Deref, Eq, From, Hash, Into, PartialEq)] - pub struct Duration(pub StdDuration); - - impl Duration { - pub const fn from_secs(secs: u64) -> Duration { - Self(StdDuration::from_secs(secs)) - } - } - - impl Type for Duration { - fn type_info() -> PgTypeInfo { - >::type_info() - } - - fn compatible(ty: &PgTypeInfo) -> bool { - >::compatible(ty) - } - } - - impl TryFrom for Duration { - type Error = crate::convert::IntervalError; - - fn try_from(value: PgInterval) -> Result { - Ok(Self(crate::convert::interval_to_duration(value)?)) - } - } - - impl<'r> Decode<'r, Postgres> for Duration { - fn decode(value: PgValueRef<'r>) -> Result { - let interval: PgInterval = Decode::::decode(value)?; - - Ok(interval.try_into()?) - } - } -} - -pub use duration_impl::Duration; diff --git a/crates/lib/docs_rs_types/src/lib.rs b/crates/lib/docs_rs_types/src/lib.rs index acaa4b148..1373cc6fe 100644 --- a/crates/lib/docs_rs_types/src/lib.rs +++ b/crates/lib/docs_rs_types/src/lib.rs @@ -1,8 +1,6 @@ mod build_status; mod compression_algorithm; -pub(crate) mod convert; pub mod doc_coverage; -mod duration; mod feature; mod ids; mod krate_name; @@ -14,7 +12,6 @@ mod version; pub use build_status::BuildStatus; pub use compression_algorithm::{CompressionAlgorithm, compression_from_file_extension}; pub use doc_coverage::{DocCoverage, RawFileCoverage}; -pub use duration::Duration; pub use feature::Feature; pub use ids::{BuildId, CrateId, ReleaseId}; pub use krate_name::KrateName;