Skip to content

Commit 28f60f2

Browse files
authored
Merge pull request #293 from onur/failures-count
Show daily build failure count in release activity page
2 parents 58621fa + f639b28 commit 28f60f2

File tree

7 files changed

+98
-39
lines changed

7 files changed

+98
-39
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.

src/utils/daemon.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,12 @@ pub fn start_daemon() {
121121
});
122122

123123

124-
// update release activity everyday at 02:00
124+
// update release activity everyday at 23:55
125125
thread::spawn(move || {
126126
loop {
127127
thread::sleep(Duration::from_secs(60));
128128
let now = time::now();
129-
if now.tm_hour == 2 && now.tm_min == 0 {
129+
if now.tm_hour == 23 && now.tm_min == 55 {
130130
info!("Updating release activity");
131131
if let Err(e) = update_release_activity() {
132132
error!("Failed to update release activity: {}", e);

src/utils/release_activity_updater.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,45 @@ pub fn update_release_activity() -> Result<()> {
1111
let conn = try!(connect_db());
1212
let mut dates = Vec::new();
1313
let mut crate_counts = Vec::new();
14+
let mut failure_counts = Vec::new();
1415

15-
for day in 1..31 {
16+
for day in 0..30 {
1617
let rows = try!(conn.query(&format!("SELECT COUNT(*)
1718
FROM releases
1819
WHERE release_time < NOW() - INTERVAL '{} day' AND
1920
release_time > NOW() - INTERVAL '{} day'",
2021
day,
2122
day + 1),
2223
&[]));
24+
let failures_count_rows = try!(conn.query(
25+
&format!("SELECT COUNT(*)
26+
FROM releases
27+
WHERE is_library = TRUE AND
28+
build_status = FALSE AND
29+
release_time < NOW() - INTERVAL '{} day' AND
30+
release_time > NOW() - INTERVAL '{} day'",
31+
day,
32+
day + 1),
33+
&[]));
2334
let release_count: i64 = rows.get(0).get(0);
35+
let failure_count: i64 = failures_count_rows.get(0).get(0);
2436
let now = now();
2537
let date = now - Duration::days(day);
2638
dates.push(format!("{}", date.strftime("%d %b").unwrap()));
2739
// unwrap is fine here, ~~~~~~~~~~~~^ our date format is always valid
2840
crate_counts.push(release_count);
41+
failure_counts.push(failure_count);
2942
}
3043

3144
dates.reverse();
3245
crate_counts.reverse();
46+
failure_counts.reverse();
3347

3448
let map = {
3549
let mut map = BTreeMap::new();
3650
map.insert("dates".to_owned(), dates.to_json());
3751
map.insert("counts".to_owned(), crate_counts.to_json());
52+
map.insert("failures".to_owned(), failure_counts.to_json());
3853
map.to_json()
3954
};
4055

src/web/mod.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,25 @@ impl CratesfyiHandler {
100100
router.get("/robots.txt", sitemap::robots_txt_handler, "robots_txt");
101101
router.get("/sitemap.xml", sitemap::sitemap_handler, "sitemap_xml");
102102
router.get("/opensearch.xml", opensearch_xml_handler, "opensearch_xml");
103-
router.get("/releases", releases::releases_handler, "releases");
103+
router.get("/releases", releases::recent_releases_handler, "releases");
104104
router.get("/releases/feed",
105105
releases::releases_feed_handler,
106106
"releases_feed");
107107
router.get("/releases/recent/:page",
108-
releases::releases_handler,
108+
releases::recent_releases_handler,
109109
"releases_recent_page");
110-
router.get("/releases/stars", releases::stars_handler, "releases_stars");
110+
router.get("/releases/stars", releases::releases_by_stars_handler, "releases_stars");
111111
router.get("/releases/stars/:page",
112-
releases::stars_handler,
112+
releases::releases_by_stars_handler,
113113
"releases_stars_page");
114+
router.get("/releases/recent-failures", releases::releases_recent_failures_handler, "releases_recent_failures");
115+
router.get("/releases/recent-failures/:page",
116+
releases::releases_recent_failures_handler,
117+
"releases_recent_failures_page");
118+
router.get("/releases/failures", releases::releases_failures_by_stars_handler, "releases_failures_by_stars");
119+
router.get("/releases/failures/:page",
120+
releases::releases_failures_by_stars_handler,
121+
"releases_failures_by_starts_page");
114122
router.get("/releases/:author",
115123
releases::author_handler,
116124
"releases_author");

src/web/releases.rs

Lines changed: 61 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ impl ToJson for Release {
6969
enum Order {
7070
ReleaseTime, // this is default order
7171
GithubStars,
72+
RecentFailures,
73+
FailuresByGithubStars,
7274
}
7375

7476

@@ -105,6 +107,34 @@ fn get_releases(conn: &Connection, page: i64, limit: i64, order: Order) -> Vec<R
105107
ORDER BY crates.github_stars DESC
106108
LIMIT $1 OFFSET $2"
107109
}
110+
Order::RecentFailures => {
111+
"SELECT crates.name,
112+
releases.version,
113+
releases.description,
114+
releases.target_name,
115+
releases.release_time,
116+
releases.rustdoc_status,
117+
crates.github_stars
118+
FROM crates
119+
INNER JOIN releases ON crates.id = releases.crate_id
120+
WHERE releases.build_status = FALSE AND releases.is_library = TRUE
121+
ORDER BY releases.release_time DESC
122+
LIMIT $1 OFFSET $2"
123+
}
124+
Order::FailuresByGithubStars => {
125+
"SELECT crates.name,
126+
releases.version,
127+
releases.description,
128+
releases.target_name,
129+
releases.release_time,
130+
releases.rustdoc_status,
131+
crates.github_stars
132+
FROM crates
133+
INNER JOIN releases ON releases.id = crates.latest_version_id
134+
WHERE releases.build_status = FALSE AND releases.is_library = TRUE
135+
ORDER BY crates.github_stars DESC
136+
LIMIT $1 OFFSET $2"
137+
}
108138
};
109139

110140
let mut packages = Vec::new();
@@ -300,13 +330,11 @@ pub fn releases_feed_handler(req: &mut Request) -> IronResult<Response> {
300330
}
301331

302332

303-
pub fn releases_handler(req: &mut Request) -> IronResult<Response> {
304-
// page number of releases
305-
let page_number: i64 = extension!(req, Router).find("page").unwrap_or("1").parse().unwrap_or(1);
306-
307-
let conn = extension!(req, Pool);
308-
let packages = get_releases(conn, page_number, RELEASES_IN_RELEASES, Order::ReleaseTime);
309-
333+
pub fn releases_handler(packages: Vec<Release>,
334+
page_number: i64,
335+
release_type: &str,
336+
tab: &str,
337+
title: &str) -> IronResult<Response> {
310338
if packages.is_empty() {
311339
return Err(IronError::new(Nope::CrateNotFound, status::NotFound));
312340
}
@@ -318,10 +346,10 @@ pub fn releases_handler(req: &mut Request) -> IronResult<Response> {
318346

319347
Page::new(packages)
320348
.title("Releases")
321-
.set("description", "Recently uploaded crates")
322-
.set("release_type", "recent")
349+
.set("description", title)
350+
.set("release_type", release_type)
323351
.set_true("show_releases_navigation")
324-
.set_true("releases_navigation_recent_tab")
352+
.set_true(tab)
325353
.set_bool("show_next_page_button", show_next_page)
326354
.set_int("next_page", page_number + 1)
327355
.set_bool("show_previous_page_button", show_previous_page)
@@ -330,35 +358,36 @@ pub fn releases_handler(req: &mut Request) -> IronResult<Response> {
330358
}
331359

332360

333-
// TODO: This function is almost identical to previous one
334-
pub fn stars_handler(req: &mut Request) -> IronResult<Response> {
335-
// page number of releases
361+
// Following functions caused a code repeat due to design of our /releases/ URL routes
362+
pub fn recent_releases_handler(req: &mut Request) -> IronResult<Response> {
336363
let page_number: i64 = extension!(req, Router).find("page").unwrap_or("1").parse().unwrap_or(1);
364+
let conn = extension!(req, Pool);
365+
let packages = get_releases(conn, page_number, RELEASES_IN_RELEASES, Order::ReleaseTime);
366+
releases_handler(packages, page_number, "recent", "releases_navigation_recent_tab", "Recently uploaded crates")
367+
}
337368

369+
370+
pub fn releases_by_stars_handler(req: &mut Request) -> IronResult<Response> {
371+
let page_number: i64 = extension!(req, Router).find("page").unwrap_or("1").parse().unwrap_or(1);
338372
let conn = extension!(req, Pool);
339373
let packages = get_releases(conn, page_number, RELEASES_IN_RELEASES, Order::GithubStars);
374+
releases_handler(packages, page_number, "stars", "releases_navigation_stars_tab", "Crates with most stars")
375+
}
340376

341-
if packages.is_empty() {
342-
return Err(IronError::new(Nope::CrateNotFound, status::NotFound));
343-
}
344377

345-
// Show next and previous page buttons
346-
// This is a temporary solution to avoid expensive COUNT(*)
347-
let (show_next_page, show_previous_page) = (packages.len() == RELEASES_IN_RELEASES as usize,
348-
page_number != 1);
378+
pub fn releases_recent_failures_handler(req: &mut Request) -> IronResult<Response> {
379+
let page_number: i64 = extension!(req, Router).find("page").unwrap_or("1").parse().unwrap_or(1);
380+
let conn = extension!(req, Pool);
381+
let packages = get_releases(conn, page_number, RELEASES_IN_RELEASES, Order::RecentFailures);
382+
releases_handler(packages, page_number, "recent-failures", "releases_navigation_recent_failures_tab", "Recent crates failed to build")
383+
}
349384

350-
Page::new(packages)
351-
.title("Releases")
352-
.set("description", "Most starred crates")
353-
.set("release_type", "stars")
354-
.set_true("show_releases_navigation")
355-
.set_true("releases_navigation_stars_tab")
356-
.set_true("show_stars")
357-
.set_bool("show_next_page_button", show_next_page)
358-
.set_int("next_page", page_number + 1)
359-
.set_bool("show_previous_page_button", show_previous_page)
360-
.set_int("previous_page", page_number - 1)
361-
.to_resp("releases")
385+
386+
pub fn releases_failures_by_stars_handler(req: &mut Request) -> IronResult<Response> {
387+
let page_number: i64 = extension!(req, Router).find("page").unwrap_or("1").parse().unwrap_or(1);
388+
let conn = extension!(req, Pool);
389+
let packages = get_releases(conn, page_number, RELEASES_IN_RELEASES, Order::FailuresByGithubStars);
390+
releases_handler(packages, page_number, "failures", "releases_navigation_failures_by_stars_tab", "Crates with most stars failed to build")
362391
}
363392

364393

templates/navigation.hbs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
<ul class="pure-menu-list">
6868
<li class="pure-menu-item"><a href="/releases" class="pure-menu-link{{#if varsb.releases_navigation_recent_tab}} pure-menu-active{{/if}}"><i class="fa fa-fw fa-leaf"></i><span class="title"> Recent</span></a></li>
6969
<li class="pure-menu-item"><a href="/releases/stars" class="pure-menu-link{{#if varsb.releases_navigation_stars_tab}} pure-menu-active{{/if}}"><i class="fa fa-fw fa-star"></i><span class="title"> Stars</span></a></li>
70+
<li class="pure-menu-item"><a href="/releases/recent-failures" class="pure-menu-link{{#if varsb.releases_navigation_recent_failures_tab}} pure-menu-active{{/if}}"><i class="fa fa-fw fa-warning"></i><span class="title"> Recent Failures</span></a></li>
71+
<li class="pure-menu-item"><a href="/releases/failures" class="pure-menu-link{{#if varsb.releases_navigation_failures_by_stars_tab}} pure-menu-active{{/if}}"><i class="fa fa-fw fa-star-o"></i><span class="title"> Failures By Stars</span></a></li>
7072
<li class="pure-menu-item"><a href="/releases/activity" class="pure-menu-link{{#if varsb.releases_navigation_activity_tab}} pure-menu-active{{/if}}"><i class="fa fa-fw fa-line-chart"></i><span class="title"> Activity</span></a></li>
7173
<li class="pure-menu-item"><a href="/releases/queue" class="pure-menu-link{{#if varsb.releases_queue_tab}} pure-menu-active{{/if}}"><i class="fa fa-fw fa-list-ol"></i><span class="title"> Queue</span></a></li>
7274
{{#if varss.author}}

templates/releases_activity.hbs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ new Highcharts.Chart({
3131
series: [{
3232
name: 'Releases',
3333
data: [{{#each counts}}{{this}},{{/each}}]
34+
},{
35+
name: 'Build Failures',
36+
data: [{{#each failures}}{{this}},{{/each}}]
3437
}]
3538
});
3639
</script>

0 commit comments

Comments
 (0)