Skip to content

Commit 6267cd3

Browse files
committed
move shared crate-details functions into database crate
1 parent 90094f5 commit 6267cd3

16 files changed

+346
-130
lines changed

Cargo.lock

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

crates/lib/docs_rs_cargo_metadata/src/metadata.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,19 @@ struct DeserializedMetadata {
144144
#[derive(Deserialize)]
145145
struct DeserializedResolve {
146146
root: String,
147+
#[allow(dead_code)]
147148
nodes: Vec<DeserializedResolveNode>,
148149
}
149150

150151
#[derive(Deserialize)]
152+
#[allow(dead_code)]
151153
struct DeserializedResolveNode {
152154
id: String,
153155
deps: Vec<DeserializedResolveDep>,
154156
}
155157

156158
#[derive(Deserialize)]
157159
struct DeserializedResolveDep {
160+
#[allow(dead_code)]
158161
pkg: String,
159162
}

crates/lib/docs_rs_database/.sqlx/query-1e660947261dfa1a5d1745d1732df59e0cf67ef1906da818086d063e6a0e21c6.json

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

crates/lib/docs_rs_database/.sqlx/query-4894c7d8c4e354dca1d952362b2e0cb25441e8e65b273e01ed86d2d3ecebfe84.json

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

crates/lib/docs_rs_database/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ build = "build.rs"
66

77
[dependencies]
88
anyhow = { workspace = true }
9+
chrono = { workspace = true }
910
docs_rs_env_vars = { path = "../docs_rs_env_vars" }
1011
docs_rs_opentelemetry = { path = "../docs_rs_opentelemetry" }
12+
docs_rs_types = { path = "../docs_rs_types" }
1113
futures-util = { workspace = true }
1214
hex = "0.4.3"
1315
opentelemetry = { workspace = true }
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
use anyhow::Result;
2+
use chrono::{DateTime, Utc};
3+
use futures_util::TryStreamExt as _;
4+
use serde_json::Value;
5+
use docs_rs_types::{BuildStatus, CrateId, ReleaseId, Version};
6+
7+
#[derive(Debug, Clone, Eq, PartialEq)]
8+
pub struct Release {
9+
pub id: ReleaseId,
10+
pub version: Version,
11+
#[allow(clippy::doc_overindented_list_items)]
12+
/// Aggregated build status of the release.
13+
/// * no builds -> build In progress
14+
/// * any build is successful -> Success
15+
/// -> even with failed or in-progress builds we have docs to show
16+
/// * any build is failed -> Failure
17+
/// -> we can only have Failure or InProgress here, so the Failure is the
18+
/// important part on this aggregation level.
19+
/// * the rest is all builds are in-progress -> InProgress
20+
/// -> if we have any builds, and the previous conditions don't match, we end
21+
/// up here, but we still check.
22+
///
23+
/// calculated in a database view : `release_build_status`
24+
pub build_status: BuildStatus,
25+
pub yanked: Option<bool>,
26+
pub is_library: Option<bool>,
27+
pub rustdoc_status: Option<bool>,
28+
pub target_name: Option<String>,
29+
pub default_target: Option<String>,
30+
pub doc_targets: Option<Vec<String>>,
31+
pub release_time: Option<DateTime<Utc>>,
32+
}
33+
34+
pub fn parse_doc_targets(targets: Value) -> Vec<String> {
35+
let mut targets: Vec<String> = serde_json::from_value(targets).unwrap_or_default();
36+
targets.sort_unstable();
37+
targets
38+
}
39+
40+
/// Return all releases for a crate, sorted in descending order by semver
41+
pub async fn releases_for_crate(
42+
conn: &mut sqlx::PgConnection,
43+
crate_id: CrateId,
44+
) -> Result<Vec<Release>, anyhow::Error> {
45+
let mut releases: Vec<Release> = sqlx::query!(
46+
r#"SELECT
47+
releases.id as "id: ReleaseId",
48+
releases.version as "version: Version",
49+
release_build_status.build_status as "build_status!: BuildStatus",
50+
releases.yanked,
51+
releases.is_library,
52+
releases.rustdoc_status,
53+
releases.release_time,
54+
releases.target_name,
55+
releases.default_target,
56+
releases.doc_targets
57+
FROM releases
58+
INNER JOIN release_build_status ON releases.id = release_build_status.rid
59+
WHERE
60+
releases.crate_id = $1"#,
61+
crate_id.0,
62+
)
63+
.fetch(&mut *conn)
64+
.try_filter_map(|row| async move {
65+
Ok(Some(Release {
66+
id: row.id,
67+
version: row.version,
68+
build_status: row.build_status,
69+
yanked: row.yanked,
70+
is_library: row.is_library,
71+
rustdoc_status: row.rustdoc_status,
72+
target_name: row.target_name,
73+
default_target: row.default_target,
74+
doc_targets: row.doc_targets.map(parse_doc_targets),
75+
release_time: row.release_time,
76+
}))
77+
})
78+
.try_collect()
79+
.await?;
80+
81+
releases.sort_by(|a, b| b.version.cmp(&a.version));
82+
Ok(releases)
83+
}
84+
85+
pub fn latest_release(releases: &[Release]) -> Option<&Release> {
86+
if let Some(release) = releases.iter().find(|release| {
87+
release.version.pre.is_empty()
88+
&& release.yanked == Some(false)
89+
&& release.build_status != BuildStatus::InProgress
90+
}) {
91+
Some(release)
92+
} else {
93+
releases
94+
.iter()
95+
.find(|release| release.build_status != BuildStatus::InProgress)
96+
}
97+
}
98+
99+
pub async fn update_latest_version_id(
100+
conn: &mut sqlx::PgConnection,
101+
crate_id: CrateId,
102+
) -> Result<()> {
103+
let releases = releases_for_crate(conn, crate_id).await?;
104+
105+
sqlx::query!(
106+
"UPDATE crates
107+
SET latest_version_id = $2
108+
WHERE id = $1",
109+
crate_id.0,
110+
latest_release(&releases).map(|release| release.id.0),
111+
)
112+
.execute(&mut *conn)
113+
.await?;
114+
115+
Ok(())
116+
}

crates/lib/docs_rs_database/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod config;
2+
pub mod crate_details;
23
mod errors;
34
mod metrics;
45
mod migrations;

crates/lib/docs_rs_repository_stats/.sqlx/query-1e660947261dfa1a5d1745d1732df59e0cf67ef1906da818086d063e6a0e21c6.json

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

crates/lib/docs_rs_repository_stats/.sqlx/query-4894c7d8c4e354dca1d952362b2e0cb25441e8e65b273e01ed86d2d3ecebfe84.json

Lines changed: 87 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: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ use docs_rs::{
1010
list_crate_priorities, queue_builder, remove_crate_priority, set_crate_priority,
1111
},
1212
};
13-
use docs_rs_database::service_config::{ConfigName, get_config, set_config};
13+
use docs_rs_database::{
14+
crate_details,
15+
service_config::{ConfigName, get_config, set_config},
16+
};
1417
use docs_rs_storage::add_path_into_database;
1518
use docs_rs_types::{CrateId, Version};
1619
use futures_util::StreamExt;
@@ -533,7 +536,7 @@ impl DatabaseSubcommand {
533536

534537
println!("handling crate {}", row.name);
535538

536-
db::update_latest_version_id(&mut update_conn, row.id).await?;
539+
crate_details::update_latest_version_id(&mut update_conn, row.id).await?;
537540
}
538541

539542
Ok::<(), anyhow::Error>(())

0 commit comments

Comments
 (0)