Skip to content

Commit

Permalink
chore: refactor release update checker
Browse files Browse the repository at this point in the history
  • Loading branch information
EverlastingBugstopper committed Jun 30, 2021
1 parent ca2cdde commit 52459cf
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 47 deletions.
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ opener = "0.5.0"
os_info = "3.0"
prettytable-rs = "0.8.0"
regex = "1"
semver = "1"
serde = "1.0"
serde_json = "1.0"
serde_yaml = "0.8"
Expand Down
2 changes: 1 addition & 1 deletion crates/rover-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ git2 = { version = "0.13.20", default-features = false, features = ["vendored-op
graphql-parser = "0.3.0"
graphql_client = "0.9"
http = "0.2"
regex = "1.5.4"
reqwest = {version = "0.11", default-features = false, features = ["json", "blocking", "rustls-tls", "gzip"]}
sdl-encoder = {path = "../sdl-encoder"}
semver = "1"
serde = "1"
serde_json = "1"
thiserror = "1"
Expand Down
10 changes: 7 additions & 3 deletions crates/rover-client/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,13 @@ pub enum RoverClientError {
#[error("The registry did not recognize the provided API key")]
InvalidKey,

/// could not parse the latest version
#[error("Could not get the latest release version")]
UnparseableReleaseVersion,
/// Could not parse the latest version
#[error("Could not parse the latest release version")]
UnparseableReleaseVersion { source: semver::Error },

/// Encountered an error while processing the request for the latest version
#[error("There's something wrong with the latest GitHub release URL")]
BadReleaseUrl,

#[error("This endpoint doesn't support subgraph introspection via the Query._service field")]
SubgraphIntrospectionNotAvailable,
Expand Down
3 changes: 2 additions & 1 deletion crates/rover-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

//! HTTP client for making GraphQL requests for the Rover CLI tool.

mod error;

/// Module related to blocking http client.
pub mod blocking;
mod error;

/// Module for client related errors.
pub use error::RoverClientError;
Expand Down
40 changes: 21 additions & 19 deletions crates/rover-client/src/releases.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
use crate::RoverClientError;
use regex::Regex;
use reqwest::blocking;

use reqwest::blocking::Client;
pub use semver::Version;

const LATEST_RELEASE_URL: &str = "https://github.com/apollographql/rover/releases/latest";

/// Looks up the latest release version, and returns it as a string
pub fn get_latest_release() -> Result<String, RoverClientError> {
let res = blocking::Client::new().head(LATEST_RELEASE_URL).send()?;
/// Looks up and parses the latest release version
pub fn get_latest_release() -> Result<Version, RoverClientError> {
// send a request to the latest GitHub release
let response = Client::new().head(LATEST_RELEASE_URL).send()?;

// this will return a response with a redirect to the latest tagged release
let url_path_segments = response
.url()
.path_segments()
.ok_or(RoverClientError::BadReleaseUrl)?;

let release_url = res.url().to_string();
let release_url_parts: Vec<&str> = release_url.split('/').collect();
// the last section of the URL will have the latest version in `v0.1.1` format
let version_string = url_path_segments
.last()
.ok_or(RoverClientError::BadReleaseUrl)?
.to_string();

match release_url_parts.last() {
Some(version) => {
// Parse out the semver version (ex. v1.0.0 -> 1.0.0)
let re = Regex::new(r"^v[0-9]*\.[0-9]*\.[0-9]*$").unwrap();
if re.is_match(version) {
Ok(version.to_string().replace('v', ""))
} else {
Err(RoverClientError::UnparseableReleaseVersion)
}
}
None => Err(RoverClientError::UnparseableReleaseVersion),
}
// strip the `v` prefix from the last section of the URL before parsing
Version::parse(&version_string[1..])
.map_err(|source| RoverClientError::UnparseableReleaseVersion { source })
}
7 changes: 6 additions & 1 deletion installers/binstall/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@ use thiserror::Error;

use std::io;

/// InstallerError is the type of Error that occured while installing.
/// InstallerError is the type of Error that occurred while installing.
#[derive(Error, Debug)]
pub enum InstallerError {
/// Something went wrong with system I/O
#[error(transparent)]
IoError(#[from] io::Error),

/// Couldn't find a valid install location on Unix
#[error("Could not find the home directory of the current user")]
NoHomeUnix,

/// Couldn't find a valid install location on Windows
#[error("Could not find the user profile folder")]
NoHomeWindows,

/// Something went wrong while adding the executable to zsh config
#[error("Zsh setup failed")]
ZshSetup,

/// A specified path was not valid UTF-8
#[error(transparent)]
PathNotUtf8(#[from] camino::FromPathBufError),
}
12 changes: 7 additions & 5 deletions installers/binstall/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,19 @@ pub struct Installer {
}

impl Installer {
/// Installs the executable and returns the location it was installed.
pub fn install(&self) -> Result<Option<Utf8PathBuf>, InstallerError> {
let install_path = self.do_install()?;

Ok(install_path)
}

/// Gets the location the executable will be installed to
pub fn get_bin_dir_path(&self) -> Result<Utf8PathBuf, InstallerError> {
let bin_dir = self.get_base_dir_path()?.join("bin");
Ok(bin_dir)
}

fn do_install(&self) -> Result<Option<Utf8PathBuf>, InstallerError> {
let bin_destination = self.get_bin_path()?;

Expand Down Expand Up @@ -52,11 +59,6 @@ impl Installer {
Ok(base_dir.join(&format!(".{}", &self.binary_name)))
}

pub fn get_bin_dir_path(&self) -> Result<Utf8PathBuf, InstallerError> {
let bin_dir = self.get_base_dir_path()?.join("bin");
Ok(bin_dir)
}

fn create_bin_dir(&self) -> Result<(), InstallerError> {
fs::create_dir_all(self.get_bin_dir_path()?)?;
Ok(())
Expand Down
3 changes: 2 additions & 1 deletion src/error/metadata/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,10 @@ impl From<&mut anyhow::Error> for Metadata {
RoverClientError::ClientError { msg: _ } => (None, Some(Code::E012)),
RoverClientError::InvalidKey => (Some(Suggestion::CheckKey), Some(Code::E013)),
RoverClientError::MalformedKey => (Some(Suggestion::ProperKey), Some(Code::E014)),
RoverClientError::UnparseableReleaseVersion => {
RoverClientError::UnparseableReleaseVersion { source: _ } => {
(Some(Suggestion::SubmitIssue), Some(Code::E015))
}
RoverClientError::BadReleaseUrl => (Some(Suggestion::SubmitIssue), None),
RoverClientError::NoCompositionPublishes {
graph: _,
composition_errors,
Expand Down
18 changes: 5 additions & 13 deletions src/utils/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ use std::{fs, time::SystemTime};
use ansi_term::Colour::{Cyan, Yellow};
use billboard::{Alignment, Billboard};
use camino::Utf8PathBuf;
use semver::Version;

use crate::{Result, PKG_VERSION};
use houston as config;
use rover_client::releases::get_latest_release;
use rover_client::releases::{get_latest_release, Version};

const ONE_HOUR: u64 = 60 * 60;
const ONE_DAY: u64 = ONE_HOUR * 24;
Expand Down Expand Up @@ -50,12 +49,11 @@ pub fn check_for_update(config: config::Config, force: bool) -> Result<()> {
}

fn do_update_check(checked: &mut bool, should_output_if_updated: bool) -> Result<()> {
let latest = get_latest_release()?;
let pretty_latest = Cyan.normal().paint(format!("v{}", latest));
let update_available = is_latest_newer(&latest, PKG_VERSION)?;
if update_available {
let latest_version = get_latest_release()?;
let pretty_latest = Cyan.normal().paint(format!("v{}", latest_version));
if latest_version > Version::parse(PKG_VERSION)? {
let message = format!(
"There is a newer version of Rover available: {} (currently running v{})\n\nFor instructions on how to install, run {}",
"There is a newer version of Rover available: {} (currently running v{})\n\nFor instructions on how to install, run {}",
&pretty_latest,
PKG_VERSION,
Yellow.normal().paint("`rover docs open start`")
Expand Down Expand Up @@ -90,9 +88,3 @@ fn get_last_checked_time_from_disk(version_file: &Utf8PathBuf) -> Option<SystemT
}
}
}

fn is_latest_newer(latest: &str, running: &str) -> Result<bool> {
let latest = Version::parse(latest)?;
let running = Version::parse(running)?;
Ok(latest > running)
}

0 comments on commit 52459cf

Please sign in to comment.