Stop guessing nightlies not included in manifests.txt (#3)

The file is now automatically updated after every release!
This commit is contained in:
Pietro Albini 2025-07-04 17:34:41 +02:00 committed by GitHub
parent 5ec24bbfaf
commit 032e023b25
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 7 additions and 76 deletions

View file

@ -15,7 +15,7 @@ use tracing::{debug, error, info};
use crate::{ use crate::{
db::{BuildMode, Db, FullBuildInfo, Status}, db::{BuildMode, Db, FullBuildInfo, Status},
nightlies::{Nightlies, NightlyCache}, nightlies::Nightlies,
}; };
pub struct Toolchain(String); pub struct Toolchain(String);
@ -36,16 +36,15 @@ impl Display for Toolchain {
} }
pub async fn background_builder(db: Db) -> Result<()> { pub async fn background_builder(db: Db) -> Result<()> {
let mut nightly_cache = NightlyCache::default();
loop { loop {
if let Err(err) = background_builder_inner(&db, &mut nightly_cache).await { if let Err(err) = background_builder_inner(&db).await {
error!("error in background builder: {err}"); error!("error in background builder: {err}");
} }
} }
} }
async fn background_builder_inner(db: &Db, nightly_cache: &mut NightlyCache) -> Result<()> { async fn background_builder_inner(db: &Db) -> Result<()> {
let nightlies = Nightlies::fetch(nightly_cache) let nightlies = Nightlies::fetch()
.await .await
.wrap_err("fetching nightlies")?; .wrap_err("fetching nightlies")?;
let already_finished = db let already_finished = db

View file

@ -1,29 +1,21 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::hash::RandomState; use std::hash::RandomState;
use color_eyre::eyre::{Context, OptionExt}; use color_eyre::eyre::Context;
use color_eyre::Result; use color_eyre::Result;
use reqwest::StatusCode;
use time::Duration;
use tracing::debug; use tracing::debug;
use crate::db::{BuildMode, FinishedNightly}; use crate::db::{BuildMode, FinishedNightly};
const EARLIEST_CUTOFF_DATE: &str = "2022-01-01"; const EARLIEST_CUTOFF_DATE: &str = "2022-01-01";
#[derive(Default)]
pub struct NightlyCache {
/// Nightlies that exist.
exists: HashSet<String>,
}
/// All nightlies that exist. /// All nightlies that exist.
pub struct Nightlies { pub struct Nightlies {
all: Vec<String>, all: Vec<String>,
} }
impl Nightlies { impl Nightlies {
pub async fn fetch(cache: &mut NightlyCache) -> Result<Nightlies> { pub async fn fetch() -> Result<Nightlies> {
let manifests = reqwest::get("https://static.rust-lang.org/manifests.txt") let manifests = reqwest::get("https://static.rust-lang.org/manifests.txt")
.await .await
.wrap_err("fetching https://static.rust-lang.org/manifests.txt")? .wrap_err("fetching https://static.rust-lang.org/manifests.txt")?
@ -35,24 +27,7 @@ impl Nightlies {
.filter(|date| date.as_str() > EARLIEST_CUTOFF_DATE) .filter(|date| date.as_str() > EARLIEST_CUTOFF_DATE)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
all.sort(); all.sort_by(|a, b| b.cmp(a)); // Reverse sort.
// The manifests is only updated weekly, which means new nightlies won't be contained.
// We probe for their existence.
let latest = all
.last()
.ok_or_eyre("did not find any nightlies in manifests.txt")?;
for nightly in guess_more_recent_nightlies(latest)? {
if nightly_exists(&nightly, cache)
.await
.wrap_err_with(|| format!("checking whether {nightly} exists"))?
{
all.push(nightly);
}
}
all.reverse();
debug!( debug!(
"Loaded {} nightlies from the manifest and manual additions", "Loaded {} nightlies from the manifest and manual additions",
@ -92,31 +67,6 @@ fn nightlies_from_manifest(manifest: &str) -> Vec<String> {
.collect() .collect()
} }
fn guess_more_recent_nightlies(latest: &str) -> Result<Vec<String>> {
let format = time::macros::format_description!("[year]-[month]-[day]");
let latest = time::Date::parse(latest, format).wrap_err("latest nightly has invalid format")?;
// manifests.txt is updated weekly, so let's try 8 just in case.
Ok((1..=8)
.filter_map(|offset| latest.checked_add(Duration::days(offset)))
.map(|date| date.format(format).unwrap())
.collect())
}
async fn nightly_exists(nightly: &str, cache: &mut NightlyCache) -> Result<bool> {
if cache.exists.contains(nightly) {
return Ok(true);
}
let url = format!("https://static.rust-lang.org/dist/{nightly}/channel-rust-nightly.toml");
let resp = reqwest::get(&url).await.wrap_err("fetching channel")?;
debug!(%nightly, %url, status = %resp.status(), "Checked whether a recent nightly exists");
let exists = resp.status() == StatusCode::OK;
if exists {
cache.exists.insert(nightly.to_owned());
}
Ok(exists)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]
@ -129,22 +79,4 @@ static.rust-lang.org/dist/2024-08-23/channel-rust-nightly.toml";
let nightlies = super::nightlies_from_manifest(&test_manifest); let nightlies = super::nightlies_from_manifest(&test_manifest);
assert_eq!(nightlies, vec!["2024-08-22", "2024-08-23"]); assert_eq!(nightlies, vec!["2024-08-22", "2024-08-23"]);
} }
#[test]
fn guess() {
let nightlies = super::guess_more_recent_nightlies("2024-08-28").unwrap();
assert_eq!(
nightlies,
[
"2024-08-29",
"2024-08-30",
"2024-08-31",
"2024-09-01",
"2024-09-02",
"2024-09-03",
"2024-09-04",
"2024-09-05",
]
);
}
} }