From ec01145de966bf92697c360e8562481576a17a13 Mon Sep 17 00:00:00 2001 From: hana <81144685+2501babe@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:28:05 -0800 Subject: [PATCH] solana-install: check for fixed releases directly (#29365) when initializing, if a specific release is requested, we only need to confirm it exists this can be done with the download url itself, rather than pulling the list of releases (cherry picked from commit 023509ff1ba01961f05398c71be89bb3a23aaaf4) --- install/src/command.rs | 119 ++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 43 deletions(-) diff --git a/install/src/command.rs b/install/src/command.rs index c5d29f47108be8..df2034d2538340 100644 --- a/install/src/command.rs +++ b/install/src/command.rs @@ -851,6 +851,11 @@ pub struct GithubRelease { pub prerelease: bool, } +#[derive(Debug, Deserialize, Serialize)] +pub struct GithubError { + pub message: String, +} + #[derive(Debug, Deserialize, Serialize)] pub struct GithubReleases(Vec); @@ -864,14 +869,41 @@ fn semver_of(string: &str) -> Result { } fn check_for_newer_github_release( - version_filter: Option, + current_release_semver: &str, + semver_update_type: SemverUpdateType, prerelease_allowed: bool, -) -> reqwest::Result> { - let mut page = 1; - const PER_PAGE: usize = 100; +) -> Result, String> { let client = reqwest::blocking::Client::builder() .user_agent("solana-install") - .build()?; + .build() + .map_err(|err| err.to_string())?; + + // If we want a fixed version, we don't need to stress the API to check whether it exists + if semver_update_type == SemverUpdateType::Fixed { + let download_url = github_release_download_url(current_release_semver); + let response = client + .head(download_url.as_str()) + .send() + .map_err(|err| err.to_string())?; + + if response.status() == reqwest::StatusCode::OK { + return Ok(Some(current_release_semver.to_string())); + } + } + + let version_filter = semver::VersionReq::parse(&format!( + "{}{}", + match semver_update_type { + SemverUpdateType::Fixed => "=", + SemverUpdateType::Patch => "~", + SemverUpdateType::_Minor => "^", + }, + current_release_semver + )) + .ok(); + + let mut page = 1; + const PER_PAGE: usize = 100; let mut all_releases = vec![]; let mut releases = vec![]; @@ -884,39 +916,48 @@ fn check_for_newer_github_release( ], ) .unwrap(); - let request = client.get(url).build()?; - let response = client.execute(request)?; - - releases = response - .json::()? - .0 - .into_iter() - .filter_map( - |GithubRelease { - tag_name, - prerelease, - }| { - if let Ok(version) = semver_of(&tag_name) { - if (prerelease_allowed || !prerelease) - && version_filter - .as_ref() - .map_or(true, |version_filter| version_filter.matches(&version)) - { - return Some(version); + let request = client.get(url).build().map_err(|err| err.to_string())?; + let response = client.execute(request).map_err(|err| err.to_string())?; + + if response.status() == reqwest::StatusCode::OK { + releases = response + .json::() + .map_err(|err| err.to_string())? + .0 + .into_iter() + .filter_map( + |GithubRelease { + tag_name, + prerelease, + }| { + if let Ok(version) = semver_of(&tag_name) { + if (prerelease_allowed || !prerelease) + && version_filter + .as_ref() + .map_or(true, |version_filter| version_filter.matches(&version)) + { + return Some(version); + } } - } - None - }, - ) - .collect::>(); - all_releases.extend_from_slice(&releases); - page += 1; + None + }, + ) + .collect::>(); + all_releases.extend_from_slice(&releases); + page += 1; + } else { + return Err(response + .json::() + .map_err(|err| err.to_string())? + .message); + } } all_releases.sort(); Ok(all_releases.pop().map(|r| r.to_string())) } +#[derive(Debug, PartialEq, Eq)] pub enum SemverUpdateType { Fixed, Patch, @@ -945,19 +986,11 @@ pub fn init_or_update(config_file: &str, is_init: bool, check_only: bool) -> Res progress_bar.set_message(format!("{}Checking for updates...", LOOKING_GLASS)); let github_release = check_for_newer_github_release( - semver::VersionReq::parse(&format!( - "{}{}", - match semver_update_type { - SemverUpdateType::Fixed => "=", - SemverUpdateType::Patch => "~", - SemverUpdateType::_Minor => "^", - }, - current_release_semver - )) - .ok(), + current_release_semver, + semver_update_type, is_init, - ) - .map_err(|err| err.to_string())?; + )?; + progress_bar.finish_and_clear(); match github_release {