mirror of
https://github.com/Noratrieb/does-it-build.git
synced 2026-01-14 10:25:01 +01:00
Remove old link and show number of builds
In the users locale of course. Without any annoying Accept-Language parsing or anything like that, just with the beauty of JavaScript.
This commit is contained in:
parent
3f302c7180
commit
f6fac25c6f
4 changed files with 94 additions and 35 deletions
39
src/db.rs
39
src/db.rs
|
|
@ -82,6 +82,17 @@ pub struct FinishedNightlyWithBroken {
|
|||
pub broken_error: Option<String>,
|
||||
}
|
||||
|
||||
pub struct BuildStats {
|
||||
pub pass_count: u32,
|
||||
pub error_count: u32,
|
||||
}
|
||||
|
||||
impl BuildStats {
|
||||
pub fn total(&self) -> u32 {
|
||||
self.pass_count + self.error_count
|
||||
}
|
||||
}
|
||||
|
||||
impl Db {
|
||||
pub async fn open(path: &str) -> Result<Self> {
|
||||
let db_opts = SqliteConnectOptions::from_str(path)
|
||||
|
|
@ -168,6 +179,34 @@ impl Db {
|
|||
.map(|elems| elems.into_iter().map(|elem| elem.nightly).collect())
|
||||
}
|
||||
|
||||
pub async fn build_count(&self) -> Result<BuildStats> {
|
||||
#[derive(sqlx::FromRow)]
|
||||
struct BuildStat {
|
||||
build_count: u32,
|
||||
status: Status,
|
||||
}
|
||||
|
||||
let results = sqlx::query_as::<_, BuildStat>(
|
||||
"SELECT COUNT(status) as build_count, status FROM build_info GROUP BY status",
|
||||
)
|
||||
.fetch_all(&self.conn)
|
||||
.await
|
||||
.wrap_err("getting list of all targets")?;
|
||||
|
||||
let count = |status| {
|
||||
results
|
||||
.iter()
|
||||
.find(|row| row.status == status)
|
||||
.map(|row| row.build_count)
|
||||
.unwrap_or(0)
|
||||
};
|
||||
|
||||
Ok(BuildStats {
|
||||
pass_count: count(Status::Pass),
|
||||
error_count: count(Status::Error),
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn build_status_full(
|
||||
&self,
|
||||
nightly: &str,
|
||||
|
|
|
|||
67
src/web.rs
67
src/web.rs
|
|
@ -11,7 +11,7 @@ use color_eyre::{eyre::Context, Result};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::db::{BuildInfo, BuildMode, Db, Status};
|
||||
use crate::db::{BuildInfo, BuildMode, BuildStats, Db, Status};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
|
|
@ -25,6 +25,7 @@ pub async fn webserver(db: Db) -> Result<()> {
|
|||
.route("/target", get(web_target))
|
||||
.route("/nightly", get(web_nightly))
|
||||
.route("/index.css", get(index_css))
|
||||
.route("/index.js", get(index_js))
|
||||
.with_state(AppState { db });
|
||||
|
||||
info!("Serving website on port 3000 (commit {})", crate::VERSION);
|
||||
|
|
@ -257,35 +258,37 @@ async fn web_nightly(State(state): State<AppState>, Query(query): Query<NightlyQ
|
|||
|
||||
async fn web_root(State(state): State<AppState>) -> impl IntoResponse {
|
||||
use askama::Template;
|
||||
#[derive(askama::Template)]
|
||||
#[template(path = "index.html")]
|
||||
struct RootPage {
|
||||
targets: Vec<String>,
|
||||
nightlies: Vec<String>,
|
||||
version: &'static str,
|
||||
}
|
||||
|
||||
match state.db.target_list().await {
|
||||
Ok(targets) => match state.db.nightly_list().await {
|
||||
Ok(nightlies) => {
|
||||
let page = RootPage {
|
||||
targets,
|
||||
nightlies,
|
||||
version: crate::VERSION,
|
||||
};
|
||||
|
||||
Html(page.render().unwrap()).into_response()
|
||||
}
|
||||
Err(err) => {
|
||||
error!(?err, "Error loading nightly state");
|
||||
StatusCode::INTERNAL_SERVER_ERROR.into_response()
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
error!(?err, "Error loading target state");
|
||||
StatusCode::INTERNAL_SERVER_ERROR.into_response()
|
||||
async fn render(state: AppState) -> Result<Response> {
|
||||
#[derive(askama::Template)]
|
||||
#[template(path = "index.html")]
|
||||
struct RootPage {
|
||||
targets: Vec<String>,
|
||||
nightlies: Vec<String>,
|
||||
version: &'static str,
|
||||
build_count: BuildStats,
|
||||
}
|
||||
|
||||
let targets = state.db.target_list().await?;
|
||||
let nightlies = state.db.nightly_list().await?;
|
||||
let build_count = state.db.build_count().await?;
|
||||
|
||||
let page = RootPage {
|
||||
targets,
|
||||
nightlies,
|
||||
version: crate::VERSION,
|
||||
build_count,
|
||||
};
|
||||
|
||||
Ok(Html(page.render().unwrap()).into_response())
|
||||
}
|
||||
|
||||
render(state)
|
||||
.await
|
||||
.unwrap_or_else(|err: color_eyre::eyre::Error| {
|
||||
error!(?err, "Error loading data for root page");
|
||||
StatusCode::INTERNAL_SERVER_ERROR.into_response()
|
||||
})
|
||||
}
|
||||
|
||||
async fn index_css() -> impl IntoResponse {
|
||||
|
|
@ -298,6 +301,16 @@ async fn index_css() -> impl IntoResponse {
|
|||
)
|
||||
}
|
||||
|
||||
async fn index_js() -> impl IntoResponse {
|
||||
(
|
||||
[(
|
||||
axum::http::header::CONTENT_TYPE,
|
||||
axum::http::HeaderValue::from_static("application/javascript; charset=utf-8"),
|
||||
)],
|
||||
include_str!("../static/index.js"),
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct TriggerBuildBody {
|
||||
nightly: String,
|
||||
|
|
|
|||
4
static/index.js
Normal file
4
static/index.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
// Do some fancy number formatting in your locale, so you can't blame me if the numbers look ass.
|
||||
document.querySelectorAll(".number").forEach((elem) => {
|
||||
elem.textContent = new Intl.NumberFormat().format(Number(elem.textContent));
|
||||
});
|
||||
|
|
@ -5,21 +5,24 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Does it build?</title>
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
<style></style>
|
||||
<script type="module" defer src="index.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Does it build?</h1>
|
||||
<p>
|
||||
This website builds every rustc target on many nightlies to check which
|
||||
ones work and which ones do not.
|
||||
This website builds the standard libary for every rustc target on every
|
||||
nightly to check whether it builds or not.
|
||||
</p>
|
||||
<p>
|
||||
There are currently
|
||||
<span class="number">{{build_count.total()}}</span> build results stored,
|
||||
with <span class="number">{{build_count.pass_count}}</span> passing and
|
||||
<span class="number">{{build_count.error_count}}</span> erroring.
|
||||
</p>
|
||||
|
||||
<p>You can select a target from the list below and check its history.</p>
|
||||
<p>
|
||||
If that is not what you want, you can visit the
|
||||
<a href="full-table">full table</a> to see
|
||||
<strong>all</strong> information at once (which will really stress test
|
||||
your browser).
|
||||
You can select a nightly or target from the list below and check its
|
||||
history.
|
||||
</p>
|
||||
|
||||
<h1>Nightlies</h1>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue