Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cli/rustup_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ pub async fn main(
SelfSubcmd::Uninstall {
no_prompt,
no_modify_path,
} => self_update::uninstall(no_prompt, no_modify_path, process),
} => self_update::uninstall(no_prompt, no_modify_path, cfg),
SelfSubcmd::UpgradeData => cfg.upgrade_data().map(|_| ExitCode::SUCCESS),
},
RustupSubcmd::Set { subcmd } => match subcmd {
Expand Down
25 changes: 14 additions & 11 deletions src/cli/self_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1049,23 +1049,21 @@ async fn maybe_install_rust(opts: InstallOpts<'_>, cfg: &mut Cfg<'_>) -> Result<
}

/// Uninstall process:
/// 1. Remove rustup home.
/// 2. Remove all entries in `$CARGO_HOME` except `bin`.
/// 3. Remove rustup tool links and binary.
/// 4. Try to remove $CARGO_HOME/bin directory if it's empty.
/// 5. Upon successfully removing $CARGO_HOME/bin, clean up $PATH.
/// 6. Try to remove $CARGO_HOME directory if it's empty.
pub(crate) fn uninstall(
no_prompt: bool,
no_modify_path: bool,
process: &Process,
) -> Result<ExitCode> {
/// 1. Remove all installed toolchains.
/// 2. Remove rustup home.
/// 3. Remove all entries in `$CARGO_HOME` except `bin`.
/// 4. Remove rustup tool links and binary.
/// 5. Try to remove $CARGO_HOME/bin directory if it's empty.
/// 6. Upon successfully removing $CARGO_HOME/bin, clean up $PATH.
/// 7. Try to remove $CARGO_HOME directory if it's empty.
pub(crate) fn uninstall(no_prompt: bool, no_modify_path: bool, cfg: &Cfg<'_>) -> Result<ExitCode> {
if cfg!(feature = "no-self-update") {
error!("self-uninstall is disabled for this build of rustup");
error!("you should probably use your system package manager to uninstall rustup");
return Ok(ExitCode::FAILURE);
}

let process = cfg.process;
let cargo_home = process.cargo_home()?;

if !cargo_home.join(format!("bin/rustup{EXE_SUFFIX}")).exists() {
Expand All @@ -1089,6 +1087,11 @@ pub(crate) fn uninstall(
}
}

info!("removing toolchains");
for toolchain in cfg.list_toolchains()? {
Toolchain::ensure_removed(cfg, toolchain.into())?;
}

info!("removing rustup home");

// Delete RUSTUP_HOME
Expand Down
22 changes: 22 additions & 0 deletions tests/suite/cli_self_upd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,28 @@ async fn uninstall_deletes_bins() {
assert!(!rust_gdbgui.exists());
}

#[tokio::test]
async fn uninstall_deletes_installed_toolchains() {
let cx = setup_empty_installed().await;
let path = cx.config.customdir.join("custom-1");
let path = path.to_string_lossy();
cx.config
.expect(["rustup", "toolchain", "link", "custom", &path])
.await
.is_ok();
cx.config
.expect(["rustup", "self", "uninstall", "-y"])
.await
.with_stderr(snapbox::str![[r#"
...
info: uninstalling toolchain custom
info: toolchain custom uninstalled
...
"#]])
.is_ok();
assert!(!cx.config.rustupdir.join("toolchains").exists());
}

#[tokio::test]
async fn uninstall_works_if_some_bins_dont_exist() {
let cx = setup_empty_installed().await;
Expand Down
Loading