Skip to content

Commit

Permalink
Do not download self update if it is the same version (#576)
Browse files Browse the repository at this point in the history
* Do not download self update if it is the same version

Fixes #555

* cargo fmt

* Update tests and fixed fmt issues
  • Loading branch information
crodas authored Feb 21, 2024
1 parent 13d2d12 commit 276ba1e
Show file tree
Hide file tree
Showing 13 changed files with 119 additions and 159 deletions.
9 changes: 5 additions & 4 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ serde_json = "1.0"
sha2 = "0.10"
tar = "0.4"
tempfile = "3"
thiserror = "1.0.57"
time = { version = "0.3", features = ["macros", "parsing", "formatting", "serde-well-known"] }
toml_edit = { version = "0.13", features = ["serde", "easy"] }
tracing = "0.1"
Expand Down
11 changes: 7 additions & 4 deletions src/commands/fuelup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ use crate::ops::fuelup_self::self_update;
#[derive(Debug, Parser)]
pub enum FuelupCommand {
/// Updates fuelup
Update,
Update(UpdateCommand),
}

#[derive(Debug, Parser)]
struct UpdateCommand {}
pub struct UpdateCommand {
#[clap(long, short)]
pub force: bool,
}

pub fn exec() -> Result<()> {
if let Err(e) = self_update() {
pub fn exec(force: bool) -> Result<()> {
if let Err(e) = self_update(force) {
bail!("fuelup failed to update itself: {}", e)
};

Expand Down
32 changes: 28 additions & 4 deletions src/file.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
use anyhow::{Context, Result};
use std::fs;
use std::io;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use semver::Version;
use std::{fs, io, os::unix::fs::PermissionsExt, path::Path};

#[cfg(unix)]
pub(crate) fn is_executable(file: &Path) -> bool {
file.is_file() && file.metadata().unwrap().permissions().mode() & 0o111 != 0
}

#[derive(Debug, thiserror::Error)]
pub(crate) enum BinError {
#[error("not found")]
NotFound,

#[error("Could not parse version ({0})")]
SemVer(#[from] semver::Error),

#[error("{0}")]
Io(#[from] io::Error),
}

pub(crate) fn get_bin_version(exec_path: &Path) -> Result<Version, BinError> {
if !exec_path.is_file() {
return Err(BinError::NotFound);
}
let output = std::process::Command::new(exec_path)
.arg("--version")
.output()?;

let stdout = String::from_utf8_lossy(&output.stdout).into_owned();
Ok(Version::parse(
stdout.split_whitespace().last().unwrap_or_default(),
)?)
}

pub(crate) fn hardlink(original: &Path, link: &Path) -> io::Result<()> {
let _ = fs::remove_file(link);
fs::hard_link(original, link)
Expand Down
2 changes: 1 addition & 1 deletion src/fuelup_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub fn fuelup_cli() -> Result<()> {
Commands::Component(command) => component::exec(command),
Commands::Default_(command) => default::exec(command),
Commands::Fuelup(command) => match command {
FuelupCommand::Update => fuelup::exec(),
FuelupCommand::Update(update) => fuelup::exec(update.force),
},
Commands::Show(_command) => show::exec(),
Commands::Toolchain(command) => toolchain::exec(command),
Expand Down
76 changes: 13 additions & 63 deletions src/ops/fuelup_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
commands::check::CheckCommand,
config::Config,
download::DownloadCfg,
file::get_bin_version,
fmt::{bold, colored_bold},
target_triple::TargetTriple,
toolchain::{DistToolchainDescription, Toolchain},
Expand All @@ -11,12 +12,12 @@ use ansiterm::Color;
use anyhow::Result;
use component::{self, Components};
use semver::Version;
use std::collections::HashMap;
use std::str::FromStr;
use std::{
cmp::Ordering::{Equal, Greater, Less},
path::Path,
};
use std::{collections::HashMap, process::Command};
use tracing::{error, info};

fn collect_package_versions(channel: Channel) -> HashMap<String, Version> {
Expand Down Expand Up @@ -55,38 +56,12 @@ fn format_version_comparison(current_version: &Version, latest_version: &Version
}
}

fn check_plugin(plugin_executable: &Path, plugin: &str, latest_version: &Version) -> Result<()> {
match std::process::Command::new(plugin_executable)
.arg("--version")
.output()
{
Ok(o) => {
let output = String::from_utf8_lossy(&o.stdout).into_owned();
match output.split_whitespace().last() {
Some(v) => {
let version = Version::parse(v)?;
info!(
"{:>4}- {} - {}",
"",
bold(plugin),
format_version_comparison(&version, latest_version)
);
}
None => {
info!("{:>4}- {} - Error getting version string", "", plugin);
}
};
}
Err(e) => {
let error_text = if plugin_executable.exists() {
format!("execution error - {e}")
} else {
"not found".into()
};
info!("{:>4}- {} - {}", "", bold(plugin), error_text);
}
}
Ok(())
fn check_plugin(plugin_executable: &Path, plugin: &str, latest_version: &Version) {
let version_or_err = match get_bin_version(plugin_executable) {
Ok(version) => format_version_comparison(&version, latest_version),
Err(err) => err.to_string(),
};
info!("{:>4}- {} - {}", "", plugin, version_or_err);
}

fn check_fuelup() -> Result<()> {
Expand Down Expand Up @@ -121,36 +96,11 @@ fn check_toolchain(toolchain: &str, verbose: bool) -> Result<()> {
for component in Components::collect_exclude_plugins()? {
if let Some(latest_version) = latest_package_versions.get(&component.name) {
let component_executable = toolchain.bin_path.join(&component.name);
match Command::new(component_executable).arg("--version").output() {
Ok(o) => {
let output = String::from_utf8_lossy(&o.stdout).into_owned();

match output.split_whitespace().last() {
Some(v) => {
let version = Version::parse(v)?;
info!(
"{:>2}{} - {}",
"",
bold(&component.name),
format_version_comparison(&version, latest_version)
);
}
None => {
error!(
"{:>2}{} - Error getting version string",
"",
bold(&component.name)
);
}
}
}
Err(_) => error!(
"{:>2}{} - Error getting version string",
"",
bold(&component.name)
),
let version_text = match get_bin_version(&component_executable) {
Ok(version) => format_version_comparison(&version, latest_version),
Err(err) => err.to_string(),
};

info!("{:>2}{} - {}", "", bold(&component.name), version_text);
if verbose && component.name == component::FORC {
for plugin in component::Components::collect_plugins()? {
if !plugin.is_main_executable() {
Expand All @@ -173,7 +123,7 @@ fn check_toolchain(toolchain: &str, verbose: bool) -> Result<()> {
);

if let Some(latest_version) = maybe_latest_version {
check_plugin(&plugin_executable, plugin_name, latest_version)?;
check_plugin(&plugin_executable, plugin_name, latest_version);
}
}
}
Expand Down
19 changes: 3 additions & 16 deletions src/ops/fuelup_component/list.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::{
commands::component::ListCommand, download::get_latest_version, fmt::bold, toolchain::Toolchain,
commands::component::ListCommand, download::get_latest_version, file::get_bin_version,
fmt::bold, toolchain::Toolchain,
};
use anyhow::Result;
use component::Components;
use semver::Version;
use std::fmt::Write;
use tracing::info;

Expand Down Expand Up @@ -46,20 +46,7 @@ pub fn list(_command: ListCommand) -> Result<()> {
);
if toolchain.has_component(&component.name) {
let exec_path = toolchain.bin_path.join(&component.name);

let current_version = if let Ok(o) = std::process::Command::new(exec_path)
.arg("--version")
.output()
{
let output = String::from_utf8_lossy(&o.stdout).into_owned();
output.split_whitespace().last().map_or_else(
|| None,
|v| Version::parse(v).map_or_else(|_| None, |v| Some(v.to_string())),
)
} else {
None
};

let current_version = get_bin_version(&exec_path).map(|v| v.to_string()).ok();
let version_info = match Some(&latest_version) == current_version.as_ref() {
true => "up-to-date".to_string(),
false => format!("latest: {}", &latest_version),
Expand Down
15 changes: 12 additions & 3 deletions src/ops/fuelup_self.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use tracing::{error, info};

use crate::{
download::{download_file_and_unpack, unpack_bins, DownloadCfg},
file::hard_or_symlink_file,
file::{get_bin_version, hard_or_symlink_file},
path::{fuelup_bin, fuelup_bin_dir},
target_triple::TargetTriple,
};
Expand All @@ -18,7 +18,7 @@ pub fn attempt_install_self(download_cfg: DownloadCfg, dst: &Path) -> Result<()>
Ok(())
}

pub fn self_update() -> Result<()> {
pub fn self_update(force: bool) -> Result<()> {
let download_cfg = DownloadCfg::new(
component::FUELUP,
TargetTriple::from_component(component::FUELUP)?,
Expand All @@ -27,6 +27,14 @@ pub fn self_update() -> Result<()> {

let fuelup_bin = fuelup_bin();

if !force && get_bin_version(&fuelup_bin).ok() == Some(download_cfg.version.clone()) {
info!(
"Already up to date (fuelup v{})",
download_cfg.version.to_string()
);
return Ok(());
}

let fuelup_new_dir = tempfile::tempdir()?;
let fuelup_new_dir_path = fuelup_new_dir.path();
let fuelup_backup = fuelup_new_dir_path.join("fuelup-backup");
Expand Down Expand Up @@ -67,7 +75,8 @@ pub fn self_update() -> Result<()> {
"Failed to replace old fuelup with new fuelup: {}. Attempting to restore backup fuelup.",
e);
// If we have failed to replace the old fuelup for whatever reason, we want the backup.
// Although unlikely, should this last step fail, we will recommend to re-install fuelup using fuelup-init.
// Although unlikely, should this last step fail, we will recommend to re-install fuelup
// using fuelup-init.
if let Err(e) = fs::copy(&fuelup_backup, &fuelup_bin) {
bail!(
"Could not restore backup fuelup. {}
Expand Down
Loading

0 comments on commit 276ba1e

Please sign in to comment.