Skip to content

Commit 3e26e34

Browse files
committed
wip
1 parent 7749ebe commit 3e26e34

File tree

2 files changed

+59
-29
lines changed

2 files changed

+59
-29
lines changed

src/db/types.rs

+6
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,9 @@ impl BuildStatus {
3737
matches!(self, BuildStatus::Success)
3838
}
3939
}
40+
41+
impl sqlx::postgres::PgHasArrayType for BuildStatus {
42+
fn array_type_info() -> sqlx::postgres::PgTypeInfo {
43+
sqlx::postgres::PgTypeInfo::with_name("_build_status")
44+
}
45+
}

src/web/crate_details.rs

+53-29
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ where
9090
pub(crate) struct Release {
9191
pub id: i32,
9292
pub version: semver::Version,
93+
/// Aggregated build status of the release.
94+
/// * no builds -> build In progress
95+
/// * any build is successful -> Success
96+
/// -> even with failed or in-progress builds we have docs to show
97+
/// * any build is failed -> Failure
98+
/// -> we can only have Failure or InProgress here, so the Failure is the
99+
/// important part on this aggregation level.
100+
/// * the rest is all builds are in-progress -> InProgress
101+
/// -> if we have any builds, and the previous conditions don't match, we end
102+
/// up here, but we still check.
93103
pub build_status: BuildStatus,
94104
pub yanked: bool,
95105
pub is_library: bool,
@@ -352,46 +362,60 @@ pub(crate) async fn releases_for_crate(
352362
r#"SELECT
353363
releases.id,
354364
releases.version,
355-
COALESCE(builds.build_status, 'failure') as "build_status!: BuildStatus",
365+
(
366+
SELECT ARRAY_AGG(builds.build_status ORDER BY builds.id)
367+
FROM builds
368+
WHERE builds.rid = releases.id
369+
) as "build_status?: Vec<BuildStatus>",
356370
releases.yanked,
357371
releases.is_library,
358372
releases.rustdoc_status,
359373
releases.target_name
360374
FROM releases
361-
LEFT JOIN LATERAL (
362-
SELECT build_status FROM builds
363-
WHERE builds.rid = releases.id
364-
ORDER BY builds.build_time
365-
DESC LIMIT 1
366-
) AS builds ON true
367375
WHERE
368376
releases.crate_id = $1"#,
369377
crate_id,
370378
)
371379
.fetch(&mut *conn)
372380
.try_filter_map(|row| async move {
373-
Ok(
374-
match semver::Version::parse(&row.version).with_context(|| {
375-
format!(
376-
"invalid semver in database for crate {crate_id}: {}",
377-
row.version
378-
)
379-
}) {
380-
Ok(semversion) => Some(Release {
381-
id: row.id,
382-
version: semversion,
383-
build_status: row.build_status,
384-
yanked: row.yanked,
385-
is_library: row.is_library,
386-
rustdoc_status: row.rustdoc_status,
387-
target_name: row.target_name,
388-
}),
389-
Err(err) => {
390-
report_error(&err);
391-
None
392-
}
393-
},
394-
)
381+
let semversion = match semver::Version::parse(&row.version).with_context(|| {
382+
format!(
383+
"invalid semver in database for crate {crate_id}: {}",
384+
row.version
385+
)
386+
}) {
387+
Ok(semver) => semver,
388+
Err(err) => {
389+
report_error(&err);
390+
return Ok(None);
391+
}
392+
};
393+
394+
Ok(Some(Release {
395+
id: row.id,
396+
version: semversion,
397+
build_status: row
398+
.build_status
399+
.map(|build_status| {
400+
if build_status.contains(&BuildStatus::Success) {
401+
BuildStatus::Success
402+
} else if build_status.contains(&BuildStatus::Failure) {
403+
BuildStatus::Failure
404+
} else if build_status
405+
.iter()
406+
.all(|status| *status == BuildStatus::InProgress)
407+
{
408+
BuildStatus::InProgress
409+
} else {
410+
unreachable!()
411+
}
412+
})
413+
.unwrap_or(BuildStatus::InProgress),
414+
yanked: row.yanked,
415+
is_library: row.is_library,
416+
rustdoc_status: row.rustdoc_status,
417+
target_name: row.target_name,
418+
}))
395419
})
396420
.try_collect()
397421
.await?;

0 commit comments

Comments
 (0)