From f48a790f6a57507f6bcf2e1ee1bcfc19d90d3224 Mon Sep 17 00:00:00 2001 From: rami3l Date: Tue, 16 Jul 2024 12:56:53 +0800 Subject: [PATCH 1/3] refactor(rustup-mode)!: remove redundant `ExitCode` in `self_update()`'s callback --- src/cli/common.rs | 7 ++++--- src/cli/rustup_mode.rs | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cli/common.rs b/src/cli/common.rs index 4a272b19bc..44f9b8aacf 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -308,13 +308,14 @@ pub(crate) async fn update_all_channels( .collect(); show_channel_updates(cfg, t)?; } - Ok(utils::ExitCode(0)) + Ok(()) }; if do_self_update { self_update(show_channel_updates, cfg.process).await } else { - show_channel_updates() + show_channel_updates()?; + Ok(utils::ExitCode(0)) } } @@ -358,7 +359,7 @@ pub(crate) fn self_update_permitted(explicit: bool) -> Result(before_restart: F, process: &Process) -> Result where - F: FnOnce() -> Result, + F: FnOnce() -> Result<()>, { match self_update_permitted(false)? { SelfUpdatePermission::HardFail => { diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index 5d482e046c..257c0355ba 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -862,7 +862,7 @@ async fn update(cfg: &mut Cfg<'_>, opts: UpdateOpts) -> Result } } if self_update { - common::self_update(|| Ok(utils::ExitCode(0)), cfg.process).await?; + common::self_update(|| Ok(()), cfg.process).await?; } } else { common::update_all_channels(cfg, self_update, opts.force).await?; From 43f62a4d25e5da0eb4fc0ce27fa864fa2fb67f80 Mon Sep 17 00:00:00 2001 From: rami3l Date: Tue, 16 Jul 2024 19:43:43 +0800 Subject: [PATCH 2/3] fix(rustup-mode): return `ExitCode(1)` when `update()` fails --- src/cli/common.rs | 9 +++++++-- src/cli/rustup_mode.rs | 6 ++++-- src/utils/utils.rs | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/cli/common.rs b/src/cli/common.rs index 44f9b8aacf..8fc03b632f 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -293,6 +293,8 @@ pub(crate) async fn update_all_channels( force_update: bool, ) -> Result { let toolchains = cfg.update_all_channels(force_update).await?; + let has_update_error = toolchains.iter().any(|(_, r)| r.is_err()); + let mut exit_code = utils::ExitCode(if has_update_error { 1 } else { 0 }); if toolchains.is_empty() { info!("no updatable toolchains installed"); @@ -312,11 +314,14 @@ pub(crate) async fn update_all_channels( }; if do_self_update { - self_update(show_channel_updates, cfg.process).await + let self_update_exit_code = self_update(show_channel_updates, cfg.process).await?; + if self_update_exit_code != utils::ExitCode(0) { + exit_code = self_update_exit_code; + } } else { show_channel_updates()?; - Ok(utils::ExitCode(0)) } + Ok(exit_code) } #[derive(Clone, Copy, Debug)] diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index 257c0355ba..60db37fe74 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -789,6 +789,8 @@ async fn check_updates(cfg: &Cfg<'_>) -> Result { } async fn update(cfg: &mut Cfg<'_>, opts: UpdateOpts) -> Result { + let mut exit_code = utils::ExitCode(0); + common::warn_if_host_is_emulated(cfg.process); let self_update_mode = cfg.get_self_update_mode()?; // Priority: no-self-update feature > self_update_mode > no-self-update args. @@ -865,7 +867,7 @@ async fn update(cfg: &mut Cfg<'_>, opts: UpdateOpts) -> Result common::self_update(|| Ok(()), cfg.process).await?; } } else { - common::update_all_channels(cfg, self_update, opts.force).await?; + exit_code = common::update_all_channels(cfg, self_update, opts.force).await?; info!("cleaning up downloads & tmp directories"); utils::delete_dir_contents_following_links(&cfg.download_dir); cfg.tmp_cx.clean(); @@ -880,7 +882,7 @@ async fn update(cfg: &mut Cfg<'_>, opts: UpdateOpts) -> Result info!("any updates to rustup will need to be fetched with your system package manager") } - Ok(utils::ExitCode(0)) + Ok(exit_code) } async fn run( diff --git a/src/utils/utils.rs b/src/utils/utils.rs index 4ccddab200..64619f4c91 100644 --- a/src/utils/utils.rs +++ b/src/utils/utils.rs @@ -21,6 +21,7 @@ pub(crate) use crate::utils::utils::raw::is_directory; pub use crate::utils::utils::raw::{is_file, path_exists}; +#[derive(Debug, PartialEq, Eq)] pub struct ExitCode(pub i32); impl From for ExitCode { From ad271f180cd34edbea54830d8b0a4696f5a48571 Mon Sep 17 00:00:00 2001 From: rami3l Date: Tue, 16 Jul 2024 19:52:16 +0800 Subject: [PATCH 3/3] refactor(rustup-mode): introduce `ExitCode::bitand*()` --- src/cli/common.rs | 5 +---- src/cli/rustup_mode.rs | 2 +- src/utils/utils.rs | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/cli/common.rs b/src/cli/common.rs index 8fc03b632f..ea5e38b7e8 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -314,10 +314,7 @@ pub(crate) async fn update_all_channels( }; if do_self_update { - let self_update_exit_code = self_update(show_channel_updates, cfg.process).await?; - if self_update_exit_code != utils::ExitCode(0) { - exit_code = self_update_exit_code; - } + exit_code &= self_update(show_channel_updates, cfg.process).await?; } else { show_channel_updates()?; } diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index 60db37fe74..a82176fb23 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -867,7 +867,7 @@ async fn update(cfg: &mut Cfg<'_>, opts: UpdateOpts) -> Result common::self_update(|| Ok(()), cfg.process).await?; } } else { - exit_code = common::update_all_channels(cfg, self_update, opts.force).await?; + exit_code &= common::update_all_channels(cfg, self_update, opts.force).await?; info!("cleaning up downloads & tmp directories"); utils::delete_dir_contents_following_links(&cfg.download_dir); cfg.tmp_cx.clean(); diff --git a/src/utils/utils.rs b/src/utils/utils.rs index 64619f4c91..40855b35ab 100644 --- a/src/utils/utils.rs +++ b/src/utils/utils.rs @@ -1,6 +1,7 @@ use std::env; use std::fs::{self, File}; use std::io::{self, BufReader, Write}; +use std::ops::{BitAnd, BitAndAssign}; use std::path::{Path, PathBuf}; use std::process::ExitStatus; @@ -24,6 +25,27 @@ pub use crate::utils::utils::raw::{is_file, path_exists}; #[derive(Debug, PartialEq, Eq)] pub struct ExitCode(pub i32); +impl BitAnd for ExitCode { + type Output = Self; + + // If `self` is `0` (success), yield `rhs`. + fn bitand(self, rhs: Self) -> Self::Output { + match self.0 { + 0 => rhs, + _ => self, + } + } +} + +impl BitAndAssign for ExitCode { + // If `self` is `0` (success), set `self` to `rhs`. + fn bitand_assign(&mut self, rhs: Self) { + if self.0 == 0 { + *self = rhs + } + } +} + impl From for ExitCode { fn from(status: ExitStatus) -> Self { Self(match status.success() {