cli: move more self update logic into self_update module
This commit is contained in:
@@ -3,8 +3,6 @@
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::Display;
|
||||
use std::fs;
|
||||
#[cfg(not(windows))]
|
||||
use std::io::ErrorKind;
|
||||
use std::io::{BufRead, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, LazyLock, Mutex};
|
||||
@@ -15,7 +13,6 @@ use git_testament::{git_testament, render_testament};
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
use tracing_subscriber::{EnvFilter, Registry, reload::Handle};
|
||||
|
||||
use super::self_update;
|
||||
use crate::{
|
||||
cli::download_tracker::DownloadTracker,
|
||||
config::Cfg,
|
||||
@@ -303,67 +300,6 @@ pub(crate) async fn update_all_channels(
|
||||
Ok(exit_code)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub(crate) enum SelfUpdatePermission {
|
||||
HardFail,
|
||||
#[cfg(not(windows))]
|
||||
Skip,
|
||||
Permit,
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub(crate) fn self_update_permitted(_explicit: bool) -> Result<SelfUpdatePermission> {
|
||||
Ok(SelfUpdatePermission::Permit)
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub(crate) fn self_update_permitted(explicit: bool) -> Result<SelfUpdatePermission> {
|
||||
// Detect if rustup is not meant to self-update
|
||||
let current_exe = env::current_exe()?;
|
||||
let current_exe_dir = current_exe.parent().expect("Rustup isn't in a directory‽");
|
||||
if let Err(e) = tempfile::Builder::new()
|
||||
.prefix("updtest")
|
||||
.tempdir_in(current_exe_dir)
|
||||
{
|
||||
match e.kind() {
|
||||
ErrorKind::PermissionDenied => {
|
||||
trace!("Skipping self-update because we cannot write to the rustup dir");
|
||||
if explicit {
|
||||
return Ok(SelfUpdatePermission::HardFail);
|
||||
} else {
|
||||
return Ok(SelfUpdatePermission::Skip);
|
||||
}
|
||||
}
|
||||
_ => return Err(e.into()),
|
||||
}
|
||||
}
|
||||
Ok(SelfUpdatePermission::Permit)
|
||||
}
|
||||
|
||||
/// Performs all of a self-update: check policy, download, apply and exit.
|
||||
pub(crate) async fn self_update(process: &Process) -> Result<utils::ExitCode> {
|
||||
match self_update_permitted(false)? {
|
||||
SelfUpdatePermission::HardFail => {
|
||||
error!("Unable to self-update. STOP");
|
||||
return Ok(utils::ExitCode(1));
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
SelfUpdatePermission::Skip => return Ok(utils::ExitCode(0)),
|
||||
SelfUpdatePermission::Permit => {}
|
||||
}
|
||||
|
||||
let setup_path = self_update::prepare_update(process).await?;
|
||||
|
||||
if let Some(setup_path) = &setup_path {
|
||||
return self_update::run_update(setup_path);
|
||||
} else {
|
||||
// Try again in case we emitted "tool `{}` is already installed" last time.
|
||||
self_update::install_proxies(process)?;
|
||||
}
|
||||
|
||||
Ok(utils::ExitCode(0))
|
||||
}
|
||||
|
||||
/// Print a list of items (targets or components) to stdout.
|
||||
///
|
||||
/// `items` represents the list of items, with the name and a boolean
|
||||
|
||||
@@ -996,7 +996,7 @@ async fn update(
|
||||
}
|
||||
}
|
||||
if self_update {
|
||||
exit_code &= common::self_update(cfg.process).await?;
|
||||
exit_code &= self_update::self_update(cfg.process).await?;
|
||||
}
|
||||
} else if ensure_active_toolchain {
|
||||
let (toolchain, reason) = cfg.ensure_active_toolchain(force_non_host, true).await?;
|
||||
@@ -1005,7 +1005,7 @@ async fn update(
|
||||
} else {
|
||||
exit_code &= common::update_all_channels(cfg, opts.force).await?;
|
||||
if self_update {
|
||||
exit_code &= common::self_update(cfg.process).await?;
|
||||
exit_code &= self_update::self_update(cfg.process).await?;
|
||||
}
|
||||
|
||||
info!("cleaning up downloads & tmp directories");
|
||||
|
||||
@@ -32,12 +32,13 @@
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::env::{self, consts::EXE_SUFFIX};
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
#[cfg(not(windows))]
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::path::{Component, MAIN_SEPARATOR, Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
use std::{fmt, fs};
|
||||
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use cfg_if::cfg_if;
|
||||
@@ -1071,6 +1072,67 @@ pub(crate) fn uninstall(no_prompt: bool, process: &Process) -> Result<utils::Exi
|
||||
Ok(utils::ExitCode(0))
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub(crate) enum SelfUpdatePermission {
|
||||
HardFail,
|
||||
#[cfg(not(windows))]
|
||||
Skip,
|
||||
Permit,
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub(crate) fn self_update_permitted(_explicit: bool) -> Result<SelfUpdatePermission> {
|
||||
Ok(SelfUpdatePermission::Permit)
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub(crate) fn self_update_permitted(explicit: bool) -> Result<SelfUpdatePermission> {
|
||||
// Detect if rustup is not meant to self-update
|
||||
let current_exe = env::current_exe()?;
|
||||
let current_exe_dir = current_exe.parent().expect("Rustup isn't in a directory‽");
|
||||
if let Err(e) = tempfile::Builder::new()
|
||||
.prefix("updtest")
|
||||
.tempdir_in(current_exe_dir)
|
||||
{
|
||||
match e.kind() {
|
||||
io::ErrorKind::PermissionDenied => {
|
||||
trace!("Skipping self-update because we cannot write to the rustup dir");
|
||||
if explicit {
|
||||
return Ok(SelfUpdatePermission::HardFail);
|
||||
} else {
|
||||
return Ok(SelfUpdatePermission::Skip);
|
||||
}
|
||||
}
|
||||
_ => return Err(e.into()),
|
||||
}
|
||||
}
|
||||
Ok(SelfUpdatePermission::Permit)
|
||||
}
|
||||
|
||||
/// Performs all of a self-update: check policy, download, apply and exit.
|
||||
pub(crate) async fn self_update(process: &Process) -> Result<utils::ExitCode> {
|
||||
match self_update_permitted(false)? {
|
||||
SelfUpdatePermission::HardFail => {
|
||||
error!("Unable to self-update. STOP");
|
||||
return Ok(utils::ExitCode(1));
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
SelfUpdatePermission::Skip => return Ok(utils::ExitCode(0)),
|
||||
SelfUpdatePermission::Permit => {}
|
||||
}
|
||||
|
||||
let setup_path = prepare_update(process).await?;
|
||||
|
||||
if let Some(setup_path) = &setup_path {
|
||||
return run_update(setup_path);
|
||||
} else {
|
||||
// Try again in case we emitted "tool `{}` is already installed" last time.
|
||||
install_proxies(process)?;
|
||||
}
|
||||
|
||||
Ok(utils::ExitCode(0))
|
||||
}
|
||||
|
||||
/// Self update downloads rustup-init to `CARGO_HOME`/bin/rustup-init
|
||||
/// and runs it.
|
||||
///
|
||||
@@ -1089,11 +1151,11 @@ pub(crate) fn uninstall(no_prompt: bool, process: &Process) -> Result<utils::Exi
|
||||
pub(crate) async fn update(cfg: &Cfg<'_>) -> Result<utils::ExitCode> {
|
||||
common::warn_if_host_is_emulated(cfg.process);
|
||||
|
||||
use common::SelfUpdatePermission::*;
|
||||
use SelfUpdatePermission::*;
|
||||
let update_permitted = if cfg!(feature = "no-self-update") {
|
||||
HardFail
|
||||
} else {
|
||||
common::self_update_permitted(true)?
|
||||
self_update_permitted(true)?
|
||||
};
|
||||
match update_permitted {
|
||||
HardFail => {
|
||||
|
||||
Reference in New Issue
Block a user