mirror of
https://github.com/Noratrieb/does-it-build.git
synced 2026-01-14 10:25:01 +01:00
rewrite frontend to be less fucked
This commit is contained in:
parent
3012189906
commit
cc4d90e748
13 changed files with 379 additions and 19 deletions
81
Cargo.lock
generated
81
Cargo.lock
generated
|
|
@ -1,6 +1,6 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
|
|
@ -44,6 +44,50 @@ version = "0.2.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "askama"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28"
|
||||||
|
dependencies = [
|
||||||
|
"askama_derive",
|
||||||
|
"askama_escape",
|
||||||
|
"humansize",
|
||||||
|
"num-traits",
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "askama_derive"
|
||||||
|
version = "0.12.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83"
|
||||||
|
dependencies = [
|
||||||
|
"askama_parser",
|
||||||
|
"basic-toml",
|
||||||
|
"mime",
|
||||||
|
"mime_guess",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "askama_escape"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "askama_parser"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.82"
|
version = "0.1.82"
|
||||||
|
|
@ -165,6 +209,15 @@ version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "basic-toml"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "823388e228f614e9558c6804262db37960ec8821856535f5c3f59913140558f8"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
|
|
@ -343,6 +396,7 @@ dependencies = [
|
||||||
name = "does-it-build"
|
name = "does-it-build"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"askama",
|
||||||
"axum",
|
"axum",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"futures",
|
"futures",
|
||||||
|
|
@ -694,6 +748,15 @@ version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humansize"
|
||||||
|
version = "2.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
|
||||||
|
dependencies = [
|
||||||
|
"libm",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
|
|
@ -890,6 +953,16 @@ version = "0.3.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime_guess"
|
||||||
|
version = "2.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
|
||||||
|
dependencies = [
|
||||||
|
"mime",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
|
@ -2107,6 +2180,12 @@ version = "1.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
askama = "0.12.1"
|
||||||
axum = { version = "0.7.5", features = ["macros"] }
|
axum = { version = "0.7.5", features = ["macros"] }
|
||||||
color-eyre = "0.6.3"
|
color-eyre = "0.6.3"
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ It does this in parallel, using half of the available threads (or `DOES_IT_BUILD
|
||||||
- `DB_PATH`: Path to SQlite DB to store the results
|
- `DB_PATH`: Path to SQlite DB to store the results
|
||||||
- `DOES_IT_BUILD_PARALLEL_JOBS`: Parallel build jobs, defaults to cores/2.
|
- `DOES_IT_BUILD_PARALLEL_JOBS`: Parallel build jobs, defaults to cores/2.
|
||||||
|
|
||||||
|
Build configuration: `DOES_IT_BUILD_OVERRIDE_VERSION` to override the git commit.
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
deployed at <https://does-it-build.noratrieb.dev/>
|
deployed at <https://does-it-build.noratrieb.dev/>
|
||||||
|
|
|
||||||
4
build.rs
4
build.rs
|
|
@ -15,6 +15,10 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_get_commit() -> color_eyre::Result<String> {
|
fn try_get_commit() -> color_eyre::Result<String> {
|
||||||
|
if let Ok(overridden) = std::env::var("DOES_IT_BUILD_OVERRIDE_VERSION") {
|
||||||
|
return Ok(overridden);
|
||||||
|
}
|
||||||
|
|
||||||
let stdout = std::process::Command::new("git")
|
let stdout = std::process::Command::new("git")
|
||||||
.arg("rev-parse")
|
.arg("rev-parse")
|
||||||
.arg("HEAD")
|
.arg("HEAD")
|
||||||
|
|
|
||||||
25
src/db.rs
25
src/db.rs
|
|
@ -100,13 +100,36 @@ impl Db {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn build_status(&self) -> Result<Vec<BuildInfo>> {
|
pub async fn full_mega_monster(&self) -> Result<Vec<BuildInfo>> {
|
||||||
sqlx::query_as::<_, BuildInfo>("SELECT nightly, target, status, mode FROM build_info")
|
sqlx::query_as::<_, BuildInfo>("SELECT nightly, target, status, mode FROM build_info")
|
||||||
.fetch_all(&self.conn)
|
.fetch_all(&self.conn)
|
||||||
.await
|
.await
|
||||||
.wrap_err("getting build status from DB")
|
.wrap_err("getting build status from DB")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn history_for_target(&self, target: &str) -> Result<Vec<BuildInfo>> {
|
||||||
|
sqlx::query_as::<_, BuildInfo>(
|
||||||
|
"SELECT nightly, target, status, mode FROM build_info WHERE target = ?",
|
||||||
|
)
|
||||||
|
.bind(target)
|
||||||
|
.fetch_all(&self.conn)
|
||||||
|
.await
|
||||||
|
.wrap_err("getting history for single target")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn target_list(&self) -> Result<Vec<String>> {
|
||||||
|
#[derive(sqlx::FromRow)]
|
||||||
|
struct TargetName {
|
||||||
|
target: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlx::query_as::<_, TargetName>("SELECT DISTINCT target FROM build_info ORDER BY target")
|
||||||
|
.fetch_all(&self.conn)
|
||||||
|
.await
|
||||||
|
.wrap_err("getting list of all targets")
|
||||||
|
.map(|elems| elems.into_iter().map(|elem| elem.target).collect())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn build_status_full(
|
pub async fn build_status_full(
|
||||||
&self,
|
&self,
|
||||||
nightly: &str,
|
nightly: &str,
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ impl Nightlies {
|
||||||
&self,
|
&self,
|
||||||
already_finished: &[FinishedNightly],
|
already_finished: &[FinishedNightly],
|
||||||
) -> Option<(String, BuildMode)> {
|
) -> Option<(String, BuildMode)> {
|
||||||
|
dbg!(&self.all[..20]);
|
||||||
let already_finished = HashSet::<_, RandomState>::from_iter(already_finished.iter());
|
let already_finished = HashSet::<_, RandomState>::from_iter(already_finished.iter());
|
||||||
|
|
||||||
self.all
|
self.all
|
||||||
|
|
|
||||||
137
src/web.rs
137
src/web.rs
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::{cmp::Reverse, collections::HashMap};
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Query, State},
|
extract::{Query, State},
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
|
|
@ -9,7 +11,7 @@ use color_eyre::{eyre::Context, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
|
|
||||||
use crate::db::{BuildMode, Db};
|
use crate::db::{BuildInfo, BuildMode, Db, Status};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
|
|
@ -18,11 +20,13 @@ pub struct AppState {
|
||||||
|
|
||||||
pub async fn webserver(db: Db) -> Result<()> {
|
pub async fn webserver(db: Db) -> Result<()> {
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(root))
|
.route("/", get(web_root))
|
||||||
.route("/build", get(build))
|
.route("/build", get(web_build))
|
||||||
|
.route("/target", get(web_target))
|
||||||
|
.route("/full-table", get(web_full_table))
|
||||||
.route("/index.css", get(index_css))
|
.route("/index.css", get(index_css))
|
||||||
.route("/index.js", get(index_js))
|
.route("/index.js", get(index_js))
|
||||||
.route("/target-state", get(target_state))
|
.route("/full-mega-monster", get(full_mega_monster))
|
||||||
.route("/trigger-build", post(trigger_build))
|
.route("/trigger-build", post(trigger_build))
|
||||||
.with_state(AppState { db });
|
.with_state(AppState { db });
|
||||||
|
|
||||||
|
|
@ -39,7 +43,7 @@ struct BuildQuery {
|
||||||
mode: Option<BuildMode>,
|
mode: Option<BuildMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build(State(state): State<AppState>, Query(query): Query<BuildQuery>) -> Response {
|
async fn web_build(State(state): State<AppState>, Query(query): Query<BuildQuery>) -> Response {
|
||||||
match state
|
match state
|
||||||
.db
|
.db
|
||||||
.build_status_full(
|
.build_status_full(
|
||||||
|
|
@ -68,8 +72,105 @@ async fn build(State(state): State<AppState>, Query(query): Query<BuildQuery>) -
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn root() -> impl IntoResponse {
|
#[derive(Deserialize)]
|
||||||
Html(include_str!("../static/index.html").replace("{{version}}", crate::VERSION))
|
struct TargetQuery {
|
||||||
|
target: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn web_target(State(state): State<AppState>, Query(query): Query<TargetQuery>) -> Response {
|
||||||
|
use askama::Template;
|
||||||
|
#[derive(askama::Template)]
|
||||||
|
#[template(path = "target.html")]
|
||||||
|
struct TargetPage {
|
||||||
|
target: String,
|
||||||
|
status: String,
|
||||||
|
version: &'static str,
|
||||||
|
builds: Vec<(String, Option<BuildInfo>, Option<BuildInfo>)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
match state.db.history_for_target(&query.target).await {
|
||||||
|
Ok(builds) => {
|
||||||
|
let latest_core = builds
|
||||||
|
.iter()
|
||||||
|
.filter(|build| build.mode == BuildMode::Core)
|
||||||
|
.max_by_key(|elem| elem.nightly.clone());
|
||||||
|
let latest_miri = builds
|
||||||
|
.iter()
|
||||||
|
.filter(|build| build.mode == BuildMode::Core)
|
||||||
|
.max_by_key(|elem| elem.nightly.clone());
|
||||||
|
|
||||||
|
let status = match (latest_core, latest_miri) {
|
||||||
|
(Some(core), Some(miri)) => {
|
||||||
|
if core.status == Status::Error || miri.status == Status::Error {
|
||||||
|
Status::Error
|
||||||
|
} else {
|
||||||
|
Status::Pass
|
||||||
|
}
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
(Some(one), None) | (None, Some(one)) => one.status.to_string(),
|
||||||
|
(None, None) => "missing".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut builds_grouped =
|
||||||
|
HashMap::<String, (Option<BuildInfo>, Option<BuildInfo>)>::new();
|
||||||
|
for build in builds {
|
||||||
|
let v = builds_grouped.entry(build.nightly.clone()).or_default();
|
||||||
|
match build.mode {
|
||||||
|
BuildMode::Core => v.0 = Some(build),
|
||||||
|
BuildMode::MiriStd => v.1 = Some(build),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut builds = builds_grouped
|
||||||
|
.into_iter()
|
||||||
|
.map(|(k, (v1, v2))| (k, v1, v2))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
builds.sort_by_cached_key(|build| Reverse(build.0.clone()));
|
||||||
|
|
||||||
|
let page = TargetPage {
|
||||||
|
status,
|
||||||
|
target: query.target,
|
||||||
|
version: crate::VERSION,
|
||||||
|
builds,
|
||||||
|
};
|
||||||
|
|
||||||
|
Html(page.render().unwrap()).into_response()
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!(?err, "Error loading target state");
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR.into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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>,
|
||||||
|
version: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
match state.db.target_list().await {
|
||||||
|
Ok(targets) => {
|
||||||
|
let page = RootPage {
|
||||||
|
targets,
|
||||||
|
version: crate::VERSION,
|
||||||
|
};
|
||||||
|
|
||||||
|
Html(page.render().unwrap()).into_response()
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!(?err, "Error loading target state");
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR.into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn web_full_table() -> impl IntoResponse {
|
||||||
|
Html(include_str!("../static/full-table.html").replace("{{version}}", crate::VERSION))
|
||||||
}
|
}
|
||||||
async fn index_css() -> impl IntoResponse {
|
async fn index_css() -> impl IntoResponse {
|
||||||
(
|
(
|
||||||
|
|
@ -90,8 +191,8 @@ async fn index_js() -> impl IntoResponse {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn target_state(State(state): State<AppState>) -> impl IntoResponse {
|
async fn full_mega_monster(State(state): State<AppState>) -> impl IntoResponse {
|
||||||
state.db.build_status().await.map(Json).map_err(|err| {
|
state.db.full_mega_monster().await.map(Json).map_err(|err| {
|
||||||
error!(?err, "Error loading target state");
|
error!(?err, "Error loading target state");
|
||||||
StatusCode::INTERNAL_SERVER_ERROR
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
})
|
})
|
||||||
|
|
@ -117,3 +218,21 @@ async fn trigger_build(
|
||||||
//
|
//
|
||||||
// StatusCode::ACCEPTED
|
// StatusCode::ACCEPTED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Status {
|
||||||
|
fn to_emoji(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Status::Pass => "✅",
|
||||||
|
Status::Error => "❌",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuildInfo {
|
||||||
|
fn link(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"build?nightly={}&target={}&mode={}",
|
||||||
|
self.nightly, self.target, self.mode
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Build results for nightly-{{nightly}} target-{{target}} {{mode}}</h1>
|
<h1>Build results for nightly-{{nightly}} target {{target}} {{mode}}</h1>
|
||||||
<a href="/">Back</a>
|
|
||||||
<div style="margin-top: 20px" class="{{status}} build-indicator-big">
|
<div style="margin-top: 20px" class="{{status}} build-indicator-big">
|
||||||
{{status}}
|
{{status}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,16 @@ td {
|
||||||
writing-mode: sideways-lr;
|
writing-mode: sideways-lr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.build-cell {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.build-info-a {
|
.build-info-a {
|
||||||
color: black;
|
color: black;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
.build-cell {
|
padding: 5px;
|
||||||
padding-left: 5px;
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.target-name-col {
|
.target-name-col {
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ const miriTable = new Table(
|
||||||
);
|
);
|
||||||
|
|
||||||
function fetchTargets() {
|
function fetchTargets() {
|
||||||
fetch("target-state")
|
fetch("full-mega-monster")
|
||||||
.then((body) => body.json())
|
.then((body) => body.json())
|
||||||
.then((body) => {
|
.then((body) => {
|
||||||
const core = body.filter((info) => info.mode === "core");
|
const core = body.filter((info) => info.mode === "core");
|
||||||
|
|
|
||||||
52
templates/index.html
Normal file
52
templates/index.html
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Does it build?</title>
|
||||||
|
<link rel="stylesheet" href="index.css" />
|
||||||
|
<style></style>
|
||||||
|
</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.
|
||||||
|
</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).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul class="target-list">
|
||||||
|
{% for target in targets %}
|
||||||
|
<li>
|
||||||
|
<a href="target?target={{ target }}">{{ target }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<footer class="footer">
|
||||||
|
<span>does-it-build {{version}}</span>
|
||||||
|
<a href="https://github.com/Noratrieb/does-it-build">
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
aria-labelledby="github-logo-title"
|
||||||
|
>
|
||||||
|
<title id="github-logo-title">GitHub</title>
|
||||||
|
<path
|
||||||
|
fill="black"
|
||||||
|
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
<script src="index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
78
templates/target.html
Normal file
78
templates/target.html
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>{{target}} build history</title>
|
||||||
|
<link rel="stylesheet" href="/index.css" />
|
||||||
|
<style>
|
||||||
|
.build-indicator-big {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Target build history for {{target}}</h1>
|
||||||
|
<a href="/">Back</a>
|
||||||
|
<div style="margin-top: 20px" class="{{status}} build-indicator-big">
|
||||||
|
{{status}}
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
This contains the history of this target. Core is built with
|
||||||
|
<code>cargo build --release -Zbuild-std=core</code>. This checks that
|
||||||
|
codegen/linking of core works, but does not check whether std builds.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
std is being built with <code>cargo miri setup</code>. If a target does
|
||||||
|
not support std, the std column represents core/alloc. This checks that
|
||||||
|
std builds (on targets that have it) but does not check whether
|
||||||
|
codegen/linking works.
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>nightly</th>
|
||||||
|
<th>core</th>
|
||||||
|
<th>std</th>
|
||||||
|
</tr>
|
||||||
|
{% for build in builds %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ build.0 }}</td>
|
||||||
|
{% match build.1 %} {% when Some with (build) %}
|
||||||
|
<td class="build-cell">
|
||||||
|
<a class="build-info-a" href="{{ build.link() }}">
|
||||||
|
{{ build.status.to_emoji() }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
{% when None %}
|
||||||
|
<td class="missing"></td>
|
||||||
|
{% endmatch %} {% match build.2 %} {% when Some with (build) %}
|
||||||
|
<td class="build-cell">
|
||||||
|
<a class="build-info-a" href="{{ build.link() }}">
|
||||||
|
<span> {{ build.status.to_emoji() }} </span>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
{% when None %}
|
||||||
|
<td class="missing"></td>
|
||||||
|
{% endmatch %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<footer class="footer">
|
||||||
|
<span>does-it-build {{version}}</span>
|
||||||
|
<a href="https://github.com/Noratrieb/does-it-build">
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
aria-labelledby="github-logo-title"
|
||||||
|
>
|
||||||
|
<title id="github-logo-title">GitHub</title>
|
||||||
|
<path
|
||||||
|
fill="black"
|
||||||
|
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue