use anyhow::{Context, bail};
use crate::{
channel::UserChannel, config::Config, paths, publish::JournalEntry, state::LocalState,
};
pub fn uninstall(
config: &Config,
requested: &UserChannel,
state: &mut LocalState,
purge: bool,
) -> anyhow::Result<()> {
let installed = config.local_installation_id(requested).and_then(|id| state.get_by_id(&id));
let Some(installation) = installed else {
bail!("channel {requested} is not installed, nothing to uninstall");
};
let channel = installation.channel.clone();
let home = &config.midenup_home;
let shared_network = match requested {
UserChannel::Named(network)
if crate::networks::links(home)
.into_iter()
.any(|(other, linked)| other != network.as_ref() && linked == channel) =>
{
Some(network.as_ref())
},
_ => None,
};
if let Some(network) = shared_network {
let link = paths::network_link(home, network);
crate::trace!("removing {}", link.display());
std::fs::remove_file(link)?;
} else {
let entry = JournalEntry::uninstall_installation(installation);
crate::publish::journal::prepare(home, &entry)?;
crate::publish::journal::commit_symlink(home, &entry)?;
crate::publish::journal::finish(home, &entry, state)?;
}
let default = paths::toolchains_dir(home).join("default");
if std::fs::symlink_metadata(&default).is_ok() && default.canonicalize().is_err() {
std::fs::remove_file(&default)?;
crate::info!(
"removed the 'default' override, which named {requested}. Set a new one with:\n \
midenup override <channel>"
);
}
let var = paths::var_dir(home, requested);
if var.is_dir() {
if purge {
crate::trace!("removing {}", var.display());
std::fs::remove_dir_all(&var)
.with_context(|| format!("failed to remove '{}'", var.display()))?;
} else {
crate::info!(
"kept your data for {requested} at {}; remove it with `midenup uninstall \
{requested} --purge`",
var.display()
);
}
}
if shared_network.is_some() {
crate::info!(
"removed network '{requested}'; channel '{channel}' stays installed for the other \
networks that name it"
);
} else {
crate::info!("uninstalled toolchain '{requested}'");
}
Ok(())
}