refactor: make SelfUpdate a step (#585)

This commit is contained in:
SteveLauC
2023-10-18 12:19:53 +08:00
committed by GitHub
parent e1754707d8
commit a2fbe92a25
3 changed files with 56 additions and 52 deletions

View File

@@ -127,6 +127,7 @@ pub enum Step {
Rustup, Rustup,
Scoop, Scoop,
Sdkman, Sdkman,
SelfUpdate,
Sheldon, Sheldon,
Shell, Shell,
Snap, Snap,

View File

@@ -108,7 +108,7 @@ fn run() -> Result<()> {
debug!("OS: {}", env!("TARGET")); debug!("OS: {}", env!("TARGET"));
debug!("{:?}", std::env::args()); debug!("{:?}", std::env::args());
debug!("Binary path: {:?}", std::env::current_exe()); debug!("Binary path: {:?}", std::env::current_exe());
debug!("Self Update: {:?}", cfg!(feature = "self-update")); debug!("self-update Feature Enabled: {:?}", cfg!(feature = "self-update"));
debug!("Configuration: {:?}", config); debug!("Configuration: {:?}", config);
if config.run_in_tmux() && env::var("TOPGRADE_INSIDE_TMUX").is_err() { if config.run_in_tmux() && env::var("TOPGRADE_INSIDE_TMUX").is_err() {
@@ -132,22 +132,15 @@ fn run() -> Result<()> {
let ctx = execution_context::ExecutionContext::new(run_type, sudo, &git, &config); let ctx = execution_context::ExecutionContext::new(run_type, sudo, &git, &config);
let mut runner = runner::Runner::new(&ctx); let mut runner = runner::Runner::new(&ctx);
// Self-Update step, this will execute only if:
// 1. the `self-update` feature is enabled
// 2. it is not disabled from configuration (env var/CLI opt/file)
#[cfg(feature = "self-update")] #[cfg(feature = "self-update")]
{ {
let config_self_upgrade = env::var("TOPGRADE_NO_SELF_UPGRADE").is_err() && !config.no_self_update(); let should_self_update = env::var("TOPGRADE_NO_SELF_UPGRADE").is_err() && !config.no_self_update();
if !run_type.dry() && config_self_upgrade { if should_self_update {
let result = self_update::self_update(); runner.execute(Step::SelfUpdate, "Self Update", || self_update::self_update(&ctx))?;
if let Err(e) = &result {
#[cfg(windows)]
{
if e.downcast_ref::<Upgraded>().is_some() {
return result;
}
}
print_warning(format!("Self update error: {e}"));
}
} }
} }

View File

@@ -3,6 +3,7 @@ use std::env;
use std::os::unix::process::CommandExt as _; use std::os::unix::process::CommandExt as _;
use std::process::Command; use std::process::Command;
use crate::config::Step;
use color_eyre::eyre::{bail, Result}; use color_eyre::eyre::{bail, Result};
use self_update_crate::backends::github::Update; use self_update_crate::backends::github::Update;
use self_update_crate::update::UpdateStatus; use self_update_crate::update::UpdateStatus;
@@ -11,52 +12,61 @@ use super::terminal::*;
#[cfg(windows)] #[cfg(windows)]
use crate::error::Upgraded; use crate::error::Upgraded;
pub fn self_update() -> Result<()> { use crate::execution_context::ExecutionContext;
pub fn self_update(ctx: &ExecutionContext) -> Result<()> {
print_separator("Self update"); print_separator("Self update");
let current_exe = env::current_exe();
let target = self_update_crate::get_target(); if ctx.run_type().dry() {
let result = Update::configure() println!("Would self-update");
.repo_owner("topgrade-rs") Ok(())
.repo_name("topgrade")
.target(target)
.bin_name(if cfg!(windows) { "topgrade.exe" } else { "topgrade" })
.show_output(false)
.show_download_progress(true)
.current_version(self_update_crate::cargo_crate_version!())
.no_confirm(true)
.build()?
.update_extended()?;
if let UpdateStatus::Updated(release) = &result {
println!("\nTopgrade upgraded to {}:\n", release.version);
if let Some(body) = &release.body {
println!("{body}");
}
} else { } else {
println!("Topgrade is up-to-date"); let assume_yes = ctx.config().yes(Step::SelfUpdate);
} let current_exe = env::current_exe();
{ let target = self_update_crate::get_target();
if result.updated() { let result = Update::configure()
print_warning("Respawning..."); .repo_owner("topgrade-rs")
let mut command = Command::new(current_exe?); .repo_name("topgrade")
command.args(env::args().skip(1)).env("TOPGRADE_NO_SELF_UPGRADE", ""); .target(target)
.bin_name(if cfg!(windows) { "topgrade.exe" } else { "topgrade" })
.show_output(true)
.show_download_progress(true)
.current_version(self_update_crate::cargo_crate_version!())
.no_confirm(assume_yes)
.build()?
.update_extended()?;
#[cfg(unix)] if let UpdateStatus::Updated(release) = &result {
{ println!("\nTopgrade upgraded to {}:\n", release.version);
let err = command.exec(); if let Some(body) = &release.body {
bail!(err); println!("{body}");
} }
} else {
println!("Topgrade is up-to-date");
}
#[cfg(windows)] {
{ if result.updated() {
#[allow(clippy::disallowed_methods)] print_info("Respawning...");
let status = command.status()?; let mut command = Command::new(current_exe?);
bail!(Upgraded(status)); command.args(env::args().skip(1)).env("TOPGRADE_NO_SELF_UPGRADE", "");
#[cfg(unix)]
{
let err = command.exec();
bail!(err);
}
#[cfg(windows)]
{
#[allow(clippy::disallowed_methods)]
let status = command.status()?;
bail!(Upgraded(status));
}
} }
} }
}
Ok(()) Ok(())
}
} }