diff --git a/Cargo.lock b/Cargo.lock index ef9899f..683f47a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -238,15 +238,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "tinyvec", -] - [[package]] name = "bumpalo" version = "3.19.0" @@ -457,16 +448,13 @@ version = "0.1.0" dependencies = [ "askama", "axum", - "bs58", "color-eyre", "futures", "jiff", "jsonwebtoken", "octocrab", "reqwest", - "rootcause", "serde", - "sha2", "sqlx", "tempfile", "tokio", @@ -557,7 +545,7 @@ checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" dependencies = [ "futures-core", "futures-sink", - "spin 0.9.8", + "spin", ] [[package]] @@ -1169,7 +1157,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.9.8", + "spin", ] [[package]] @@ -1803,30 +1791,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rootcause" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12e6b4d9966d17c1e58cd682656e9e1551f19f421b07d7618723009445f06099" -dependencies = [ - "hashbrown 0.16.0", - "indexmap", - "rootcause-internals", - "rustc-hash", - "spin 0.10.0", - "triomphe", - "unsize", -] - -[[package]] -name = "rootcause-internals" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac64da7400123d25e3603dfd91a0ce7a78a3ad6e2d9400e6cdbb1aef0574c0d7" -dependencies = [ - "triomphe", -] - [[package]] name = "rsa" version = "0.9.8" @@ -2168,12 +2132,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "spin" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" - [[package]] name = "spki" version = "0.7.3" @@ -2706,15 +2664,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "triomphe" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39" -dependencies = [ - "unsize", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -2754,15 +2703,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" -[[package]] -name = "unsize" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa7a7a734c1a5664a662ddcea0b6c9472a21da8888c957c7f1eaa09dba7a939" -dependencies = [ - "autocfg", -] - [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 96026d1..fa7bd18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ axum = { version = "0.8.6", default-features = false, features = [ "tracing", "macros", ] } +color-eyre = "0.6.3" futures = "0.3.30" jiff = "0.2.16" jsonwebtoken = { version = "9.3.1" } @@ -22,7 +23,6 @@ reqwest = { version = "0.12.7", features = [ "rustls-tls", "http2", ], default-features = false } -rootcause = "0.10.0" serde = { version = "1.0.210", features = ["derive"] } sqlx = { version = "0.8.2", features = ["runtime-tokio", "sqlite"] } tempfile = "3.12.0" @@ -31,6 +31,4 @@ tracing = { version = "0.1.40", features = ["attributes"] } tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } [build-dependencies] -bs58 = "0.5.1" color-eyre = "0.6.3" -sha2 = "0.10.9" diff --git a/build.rs b/build.rs index d5d1eb6..945d25a 100644 --- a/build.rs +++ b/build.rs @@ -1,29 +1,6 @@ -use std::path::PathBuf; - -use sha2::Digest; - fn main() { // Always rerun. - let index_css = include_str!("static/index.css"); - let index_js = include_str!("static/index.js"); - - let index_css_name = get_file_ref("css", index_css); - let index_js_name = get_file_ref("js", index_js); - - let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap()); - - std::fs::write( - out_dir.join("revs.rs"), - format!( - r#" -pub const INDEX_CSS_NAME: &str = "{index_css_name}"; -pub const INDEX_JS_NAME: &str = "{index_js_name}"; - "# - ), - ) - .unwrap(); - let version = if let Ok(commit) = try_get_commit() { match has_no_changes() { Ok(true) => commit, @@ -43,15 +20,6 @@ pub const INDEX_JS_NAME: &str = "{index_js_name}"; println!("cargo:rustc-env=GIT_COMMIT_SHORT={version_short}"); } -fn get_file_ref(ext: &str, content: &str) -> String { - let mut hash = sha2::Sha256::new(); - hash.update(content); - let digest = hash.finalize(); - let rev = bs58::encode(digest).into_string(); - let rev = &rev[..16]; - format!("/{rev}.{ext}") -} - fn try_get_commit() -> color_eyre::Result { if let Ok(overridden) = std::env::var("DOES_IT_BUILD_OVERRIDE_VERSION") { return Ok(overridden); diff --git a/src/build.rs b/src/build.rs index bae70b1..ea74e3b 100644 --- a/src/build.rs +++ b/src/build.rs @@ -6,8 +6,11 @@ use std::{ time::{Duration, Instant, SystemTime}, }; +use color_eyre::{ + eyre::{bail, Context}, + Result, +}; use futures::StreamExt; -use rootcause::{prelude::ResultExt, report}; use tokio::process::Command; use tracing::{debug, error, info}; @@ -15,7 +18,6 @@ use crate::{ db::{BuildMode, Db, FullBuildInfo, Status}, nightlies::Nightlies, notification::GitHubClient, - Result, }; struct CustomBuildFlags { @@ -71,11 +73,11 @@ pub async fn background_builder(db: Db, github_client: GitHubClient) -> Result<( } async fn background_builder_inner(db: &Db, github_client: &GitHubClient) -> Result<()> { - let nightlies = Nightlies::fetch().await.context("fetching nightlies")?; + let nightlies = Nightlies::fetch().await.wrap_err("fetching nightlies")?; let already_finished = db .finished_nightlies() .await - .context("fetching finished nightlies")?; + .wrap_err("fetching finished nightlies")?; let next = nightlies.select_latest_to_build(&already_finished); match next { @@ -83,12 +85,12 @@ async fn background_builder_inner(db: &Db, github_client: &GitHubClient) -> Resu info!(%nightly, %mode, "Building next nightly"); let result = build_every_target_for_toolchain(db, &nightly, mode, github_client) .await - .context_with(|| format!("building targets for toolchain {nightly}")); + .wrap_err_with(|| format!("building targets for toolchain {nightly}")); if let Err(err) = result { error!(%nightly, %mode, ?err, "Failed to build nightly"); db.finish_nightly_as_broken(&nightly, mode, &format!("{err:?}")) .await - .context("marking nightly as broken")?; + .wrap_err("marking nightly as broken")?; } } None => { @@ -106,16 +108,16 @@ async fn targets_for_toolchain(toolchain: &Toolchain) -> Result> { .arg("target-list") .output() .await - .context("failed to spawn rustc")?; + .wrap_err("failed to spawn rustc")?; if !output.status.success() { - return Err(report!( + bail!( "failed to get target-list from rustc: {:?}", String::from_utf8(output.stderr) - )); + ); } Ok(String::from_utf8(output.stdout) - .context("rustc target-list is invalid UTF-8")? + .wrap_err("rustc target-list is invalid UTF-8")? .split_whitespace() .map(ToOwned::to_owned) .collect()) @@ -133,12 +135,9 @@ async fn install_toolchain(toolchain: &Toolchain, mode: BuildMode) -> Result<()> .arg("minimal") .output() .await - .context("failed to spawn rustup")?; + .wrap_err("failed to spawn rustup")?; if !result.status.success() { - return Err(report!( - "rustup failed: {:?}", - String::from_utf8(result.stderr) - )); + bail!("rustup failed: {:?}", String::from_utf8(result.stderr)); } let result = Command::new("rustup") .arg("component") @@ -148,12 +147,9 @@ async fn install_toolchain(toolchain: &Toolchain, mode: BuildMode) -> Result<()> .arg(&toolchain.0) .output() .await - .context("failed to spawn rustup")?; + .wrap_err("failed to spawn rustup")?; if !result.status.success() { - return Err(report!( - "rustup failed: {:?}", - String::from_utf8(result.stderr) - )); + bail!("rustup failed: {:?}", String::from_utf8(result.stderr)); } Ok(()) @@ -169,12 +165,12 @@ async fn uninstall_toolchain(toolchain: &Toolchain) -> Result<()> { .arg(&toolchain.0) .output() .await - .context("failed to spawn rustup")?; + .wrap_err("failed to spawn rustup")?; if !result.status.success() { - return Err(report!( + bail!( "rustup toolchain remove failed: {:?}", String::from_utf8(result.stderr) - )); + ); } Ok(()) } @@ -195,7 +191,7 @@ pub async fn build_every_target_for_toolchain( let targets = targets_for_toolchain(&toolchain) .await - .context("failed to get targets")?; + .wrap_err("failed to get targets")?; let results = futures::stream::iter( targets @@ -212,7 +208,7 @@ pub async fn build_every_target_for_toolchain( for target in targets { build_single_target(db, nightly, &target, mode, github_client) .await - .context_with(|| format!("building target {target} for toolchain {toolchain}"))?; + .wrap_err_with(|| format!("building target {target} for toolchain {toolchain}"))?; } // Mark it as finished, so we never have to build it again. @@ -234,7 +230,7 @@ async fn build_single_target( let existing = db .build_status_full(nightly, target, mode) .await - .context("getting existing build")?; + .wrap_err("getting existing build")?; if existing.is_some() { debug!("Build already exists"); return Ok(()); @@ -242,13 +238,13 @@ async fn build_single_target( info!("Building target"); - let tmpdir = tempfile::tempdir().context("creating temporary directory")?; + let tmpdir = tempfile::tempdir().wrap_err("creating temporary directory")?; let start_time = Instant::now(); let result = build_target(tmpdir.path(), &Toolchain::from_nightly(nightly), target) .await - .context("running build")?; + .wrap_err("running build")?; let full_build_info = FullBuildInfo { nightly: nightly.into(), @@ -302,14 +298,14 @@ async fn build_target(tmpdir: &Path, toolchain: &Toolchain, target: &str) -> Res .current_dir(tmpdir) .output() .await - .context("spawning cargo init")?; + .wrap_err("spawning cargo init")?; if !init.status.success() { - return Err(report!("init failed: {}", String::from_utf8(init.stderr)?)); + bail!("init failed: {}", String::from_utf8(init.stderr)?); } let librs = tmpdir.join("src").join("lib.rs"); std::fs::write(&librs, "#![no_std]\n") - .context_with(|| format!("writing to {}", librs.display()))?; + .wrap_err_with(|| format!("writing to {}", librs.display()))?; async fn run( toolchain: &Toolchain, @@ -334,16 +330,14 @@ async fn build_target(tmpdir: &Path, toolchain: &Toolchain, target: &str) -> Res *rustflags = Some(flags); } - let output = cmd - .current_dir(tmpdir) + cmd.current_dir(tmpdir) .output() .await - .context("spawning cargo build")?; - Ok(output) + .wrap_err("spawning cargo build") } let mut output = run(toolchain, target, &mut rustflags, tmpdir, "-Zbuild-std").await?; - let mut stderr = String::from_utf8(output.stderr).context("cargo stderr utf8")?; + let mut stderr = String::from_utf8(output.stderr).wrap_err("cargo stderr utf8")?; let status = if output.status.success() { Status::Pass @@ -358,7 +352,7 @@ async fn build_target(tmpdir: &Path, toolchain: &Toolchain, target: &str) -> Res "-Zbuild-std=core", ) .await?; - stderr = String::from_utf8(output.stderr).context("cargo stderr utf8")?; + stderr = String::from_utf8(output.stderr).wrap_err("cargo stderr utf8")?; if output.status.success() { Status::Pass diff --git a/src/db.rs b/src/db.rs index 22bcd53..66f20f2 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,11 +1,12 @@ use std::{fmt::Display, str::FromStr}; -use rootcause::{prelude::ResultExt, report}; +use color_eyre::{ + eyre::{bail, Context}, + Result, +}; use serde::{Deserialize, Serialize}; use sqlx::{migrate::Migrator, sqlite::SqliteConnectOptions, Pool, Sqlite}; -use crate::Result; - #[derive(Clone)] pub struct Db { pub conn: Pool, @@ -111,13 +112,12 @@ pub struct NotificationIssue { impl Db { pub async fn open(path: &str) -> Result { let db_opts = SqliteConnectOptions::from_str(path) - .context("parsing database URL") - .attach(format!("url: {path}"))? + .wrap_err("parsing database URL")? .create_if_missing(true); let conn = Pool::connect_with(db_opts) .await - .context_with(|| format!("opening db from `{path}`"))?; + .wrap_err_with(|| format!("opening db from `{path}`"))?; Ok(Self { conn }) } @@ -137,44 +137,38 @@ impl Db { .bind(info.build_duration_ms) .execute(&self.conn) .await - .context("inserting build info into database")?; + .wrap_err("inserting build info into database")?; Ok(()) } pub async fn history_for_target(&self, target: &str) -> Result> { - let history = sqlx::query_as::<_, BuildInfo>( + sqlx::query_as::<_, BuildInfo>( "SELECT nightly, target, status, mode FROM build_info WHERE target = ?", ) .bind(target) .fetch_all(&self.conn) .await - .context("getting history for single target") - .attach(format!("target: {target}"))?; - Ok(history) + .wrap_err("getting history for single target") } pub async fn history_for_nightly(&self, nightly: &str) -> Result> { - let history = sqlx::query_as::<_, BuildInfo>( + sqlx::query_as::<_, BuildInfo>( "SELECT nightly, target, status, mode FROM build_info WHERE nightly = ?", ) .bind(nightly) .fetch_all(&self.conn) .await - .context("getting history for single nightly") - .attach(format!("nightly: {nightly}"))?; - Ok(history) + .wrap_err("getting history for single nightly") } pub async fn nightly_info(&self, nightly: &str) -> Result> { - let info = sqlx::query_as::<_, FinishedNightlyWithBroken>( + sqlx::query_as::<_, FinishedNightlyWithBroken>( "SELECT nightly, mode, is_broken, broken_error FROM finished_nightly WHERE nightly = ?", ) .bind(nightly) .fetch_all(&self.conn) .await - .context("getting finished_nightly for single nightly") - .attach(format!("nightly: {nightly}"))?; - Ok(info) + .wrap_err("getting finished_nightly for single nightly") } pub async fn target_list(&self) -> Result> { @@ -183,14 +177,11 @@ impl Db { target: String, } - let list = sqlx::query_as::<_, TargetName>( - "SELECT DISTINCT target FROM build_info ORDER BY target", - ) - .fetch_all(&self.conn) - .await - .context("getting list of all targets")?; - - Ok(list.into_iter().map(|elem| elem.target).collect()) + 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 nightly_list(&self) -> Result> { @@ -199,14 +190,13 @@ impl Db { nightly: String, } - let list = sqlx::query_as::<_, NightlyName>( + sqlx::query_as::<_, NightlyName>( "SELECT DISTINCT nightly FROM build_info ORDER BY nightly DESC", ) .fetch_all(&self.conn) .await - .context("getting list of all nightlies")?; - - Ok(list.into_iter().map(|elem| elem.nightly).collect()) + .wrap_err("getting list of all targets") + .map(|elems| elems.into_iter().map(|elem| elem.nightly).collect()) } pub async fn build_count(&self) -> Result { @@ -221,7 +211,7 @@ impl Db { ) .fetch_all(&self.conn) .await - .context("getting total count of builds")?; + .wrap_err("getting list of all targets")?; let count = |status| { results @@ -252,8 +242,7 @@ impl Db { .bind(mode) .fetch_all(&self.conn) .await - .context("getting build status from DB") - .attach(format!("nightly: {nightly}, target: {target}"))?; + .wrap_err("getting build status from DB")?; Ok(result.first().cloned()) } @@ -262,7 +251,7 @@ impl Db { sqlx::query_as::<_, FinishedNightly>("SELECT nightly, mode from finished_nightly") .fetch_all(&self.conn) .await - .context("getting finished nightlies")?; + .wrap_err("fetching finished nightlies")?; Ok(result) } @@ -275,10 +264,10 @@ impl Db { .bind(mode) .fetch_all(&self.conn) .await - .context("checking whether a nightly is finished")?; + .wrap_err("checking whether a nightly is finished")?; if result.len() > 1 { - return Err(report!("found more than one result for {nightly} {mode}")); + bail!("found more than one result for {nightly} {mode}"); } Ok(result.len() == 1) @@ -290,7 +279,7 @@ impl Db { .bind(mode) .execute(&self.conn) .await - .context("inserting finished nightly")?; + .wrap_err("inserting finished nightly")?; Ok(()) } @@ -306,7 +295,7 @@ impl Db { .bind(error) .execute(&self.conn) .await - .context("inserting finished broken nightly")?; + .wrap_err("inserting finished broken nightly")?; Ok(()) } @@ -314,14 +303,13 @@ impl Db { &self, target: &str, ) -> Result> { - let notification = sqlx::query_as::<_, NotificationIssue>( + sqlx::query_as::<_, NotificationIssue>( "SELECT * FROM notification_issues WHERE status = 'open' AND target = ?", ) .bind(target) .fetch_optional(&self.conn) .await - .context("finding existing notification")?; - Ok(notification) + .wrap_err("finding existing notification") } pub async fn insert_notification(&self, notification: NotificationIssue) -> Result<()> { @@ -337,7 +325,7 @@ impl Db { .bind(notification.last_update_date) .execute(&self.conn) .await - .context("inserting new notification")?; + .wrap_err("inserting new notification")?; Ok(()) } @@ -347,7 +335,7 @@ impl Db { .bind(issue_number) .execute(&self.conn) .await - .context("marking notification as closed")?; + .wrap_err("marking notification as closed")?; Ok(()) } @@ -361,7 +349,7 @@ impl Db { .bind(issue_number) .execute(&self.conn) .await - .context("marking notification as closed")?; + .wrap_err("marking notification as closed")?; Ok(()) } } diff --git a/src/main.rs b/src/main.rs index c4e7a4d..d8bd3b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,15 +4,13 @@ mod nightlies; mod notification; mod web; +use color_eyre::{eyre::WrapErr, Result}; use db::Db; -use rootcause::{prelude::ResultExt, Report}; use tracing_subscriber::EnvFilter; const VERSION: &str = env!("GIT_COMMIT"); const VERSION_SHORT: &str = env!("GIT_COMMIT_SHORT"); -type Result = std::result::Result; - #[tokio::main] async fn main() -> Result<()> { main_inner().await @@ -27,25 +25,25 @@ async fn main_inner() -> Result<()> { db::MIGRATOR .run(&db.conn) .await - .context("running migrations")?; + .wrap_err("running migrations")?; let send_pings = std::env::var("GITHUB_SEND_PINGS") .map(|_| true) .unwrap_or(false); - let github_owner = std::env::var("GITHUB_OWNER").context("missing GITHUB_OWNER env var")?; - let github_repo = std::env::var("GITHUB_REPO").context("missing GITHUB_REPO env var")?; + let github_owner = std::env::var("GITHUB_OWNER").wrap_err("missing GITHUB_OWNER env var")?; + let github_repo = std::env::var("GITHUB_REPO").wrap_err("missing GITHUB_REPO env var")?; let app_id = std::env::var("GITHUB_APP_ID") - .context("missing GITHUB_APP_ID env var")? + .wrap_err("missing GITHUB_APP_ID env var")? .parse::() - .context("invalid GITHUB_APP_ID")?; + .wrap_err("invalid GITHUB_APP_ID")?; let key = std::env::var("GITHUB_APP_PRIVATE_KEY") - .context("missing GITHUB_APP_PRIVATE_KEY env var")?; + .wrap_err("missing GITHUB_APP_PRIVATE_KEY env var")?; let key = jsonwebtoken::EncodingKey::from_rsa_pem(key.as_bytes()).unwrap(); let github_client = octocrab::Octocrab::builder() .app(app_id.into(), key) .build() - .context("failed to create client")?; + .wrap_err("failed to create client")?; let github_client = notification::GitHubClient::new( send_pings, diff --git a/src/nightlies.rs b/src/nightlies.rs index 76f4f7a..ab78e04 100644 --- a/src/nightlies.rs +++ b/src/nightlies.rs @@ -1,11 +1,11 @@ use std::collections::HashSet; use std::hash::RandomState; -use rootcause::prelude::ResultExt; +use color_eyre::eyre::Context; +use color_eyre::Result; use tracing::debug; use crate::db::{BuildMode, FinishedNightly}; -use crate::Result; const EARLIEST_CUTOFF_DATE: &str = "2023-01-01"; @@ -15,21 +15,13 @@ pub struct Nightlies { } impl Nightlies { - async fn get_body(url: &str) -> Result { - Ok(reqwest::get(url) + pub async fn fetch() -> Result { + let manifests = reqwest::get("https://static.rust-lang.org/manifests.txt") .await - .context("executing GET request")? + .wrap_err("fetching https://static.rust-lang.org/manifests.txt")? .text() .await - .context("fetching body")?) - } - - pub async fn fetch() -> Result { - let url = "https://static.rust-lang.org/manifests.txt"; - let manifests = Nightlies::get_body(url) - .await - .context(format!("Fetching manifests.txt")) - .attach(format!("url: {url}"))?; + .wrap_err("fetching body of https://static.rust-lang.org/manifests.txt")?; let mut all = nightlies_from_manifest(&manifests) .into_iter() .filter(|date| date.as_str() > EARLIEST_CUTOFF_DATE) diff --git a/src/notification.rs b/src/notification.rs index ee4a709..9eb5636 100644 --- a/src/notification.rs +++ b/src/notification.rs @@ -1,10 +1,9 @@ +use color_eyre::eyre::{Context, Result}; use octocrab::models::issues::IssueStateReason; use octocrab::models::IssueState; -use rootcause::prelude::ResultExt; use tracing::info; use crate::db::{Db, FullBuildInfo, NotificationIssue, NotificationStatus, Status}; -use crate::Result; pub const TABLE_FILE: &str = file!(); pub const TABLE_LINE: u32 = line!() + 1; @@ -56,11 +55,11 @@ impl GitHubClient { .apps() .get_repository_installation(&owner, &repo) .await - .context_with(|| format!("getting installation for {owner}/{repo}"))?; + .wrap_err_with(|| format!("getting installation for {owner}/{repo}"))?; let client = client .installation(installation.id) - .context("getting client for installation")?; + .wrap_err("getting client for installation")?; Ok(Self { send_pings, @@ -144,11 +143,11 @@ This update is sent after a month of inactivity. ), ) .await - .context("creating update comment")?; + .wrap_err("creating update comment")?; db.set_notification_last_update(issue.issue_number, jiff::Timestamp::now()) .await - .context("updating last_update_date in DB")?; + .wrap_err("updating last_update_date in DB")?; } else { info!("Not sending update for {target}, since not enough time has elapsed since the last one"); } @@ -167,13 +166,9 @@ This update is sent after a month of inactivity. .issues() .create_label(target, "d73a4a", format!("Target: {target}")) .await - .context("creating label")?; - } - Err(err) => { - return Err(err) - .context("failed to fetch label label") - .map_err(Into::into) + .wrap_err("creating label")?; } + Err(err) => return Err(err).wrap_err("failed to fetch label label"), } let pings = notify_usernames @@ -212,7 +207,7 @@ This issue will be closed automatically when this target works again!" )) .send() .await - .context("failed to create issue")?; + .wrap_err("failed to create issue")?; db.insert_notification(NotificationIssue { first_failed_nightly: nightly.into(), @@ -222,7 +217,7 @@ This issue will be closed automatically when this target works again!" last_update_date: Some(jiff::Timestamp::now().as_millisecond()), }) .await - .context("inserting issue into DB")?; + .wrap_err("inserting issue into DB")?; Ok(()) } @@ -258,7 +253,7 @@ pub async fn notify_build_pass( thanks for playing this round of Tier 3 rustc target breakage fixing! See y'all next time :3!\n\n<{url}>"), ) .await - .context("creating update comment")?; + .wrap_err("creating update comment")?; github_client .issues() @@ -267,7 +262,7 @@ pub async fn notify_build_pass( .state_reason(IssueStateReason::Completed) .send() .await - .context("closing issue")?; + .wrap_err("closing issue")?; db.finish_notification(issue.issue_number).await?; } diff --git a/src/web.rs b/src/web.rs index be07855..a667a51 100644 --- a/src/web.rs +++ b/src/web.rs @@ -7,19 +7,15 @@ use axum::{ routing::get, Router, }; -use rootcause::{prelude::ResultExt, Report}; +use color_eyre::{eyre::Context, Result}; use serde::Deserialize; use tracing::{error, info}; use crate::{ db::{BuildInfo, BuildMode, BuildStats, Db, Status}, - notification, Result, + notification, }; -mod revs { - include!(concat!(env!("OUT_DIR"), "/revs.rs")); -} - #[derive(Clone)] pub struct AppState { pub db: Db, @@ -32,8 +28,8 @@ pub async fn webserver(db: Db, notification_repo: String) -> Result<()> { .route("/build", get(web_build)) .route("/target", get(web_target)) .route("/nightly", get(web_nightly)) - .route(revs::INDEX_CSS_NAME, get(index_css)) - .route(revs::INDEX_JS_NAME, get(index_js)) + .route("/index.css", get(index_css)) + .route("/index.js", get(index_js)) .with_state(AppState { db, notification_repo, @@ -42,10 +38,7 @@ pub async fn webserver(db: Db, notification_repo: String) -> Result<()> { info!("Serving website on port 3000 (commit {})", crate::VERSION); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); - axum::serve(listener, app) - .await - .context("failed to serve")?; - Ok(()) + axum::serve(listener, app).await.wrap_err("failed to serve") } #[derive(Debug, Clone, Copy)] @@ -332,39 +325,31 @@ async fn web_root(State(state): State) -> impl IntoResponse { Ok(Html(page.render().unwrap()).into_response()) } - render(state).await.unwrap_or_else(|err: Report| { - error!(?err, "Error loading data for root page"); - StatusCode::INTERNAL_SERVER_ERROR.into_response() - }) -} - -fn reply_static(body: &'static str, content_type: &'static str) -> impl IntoResponse { - ( - [ - ( - axum::http::header::CONTENT_TYPE, - axum::http::HeaderValue::from_static(content_type), - ), - ( - axum::http::header::CACHE_CONTROL, - axum::http::HeaderValue::from_static("public, max-age=31556952, immutable"), - ), - ], - body, - ) + 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 { - reply_static( + ( + [( + axum::http::header::CONTENT_TYPE, + axum::http::HeaderValue::from_static("text/css; charset=utf-8"), + )], include_str!("../static/index.css"), - "text/css; charset=utf-8", ) } async fn index_js() -> impl IntoResponse { - reply_static( + ( + [( + axum::http::header::CONTENT_TYPE, + axum::http::HeaderValue::from_static("application/javascript; charset=utf-8"), + )], include_str!("../static/index.js"), - "application/javascript; charset=utf-8", ) } diff --git a/templates/build.html b/templates/build.html index 2e1ad85..3a5389d 100644 --- a/templates/build.html +++ b/templates/build.html @@ -4,8 +4,8 @@ Build {{nightly}} {{target}} - - + +

diff --git a/templates/index.html b/templates/index.html index 6fa97d9..e6084c0 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,8 +4,8 @@ Does it build? - - + +

Does it build?

diff --git a/templates/nightly.html b/templates/nightly.html index e793744..cc5d5f1 100644 --- a/templates/nightly.html +++ b/templates/nightly.html @@ -4,7 +4,7 @@ {{nightly}} build history - +

Nightly build state for {{nightly}}

diff --git a/templates/target.html b/templates/target.html index c94c06e..b2df511 100644 --- a/templates/target.html +++ b/templates/target.html @@ -4,7 +4,7 @@ {{target}} build history - +

Target build history for {{target}}