use anyhow::{Context, bail};
use crate::{
channel::UserChannel,
config::Config,
paths,
publish::JournalEntry,
state::{LocalState, PublicationRef},
};
pub fn uninstall(
config: &Config,
requested: &UserChannel,
state: &mut LocalState,
purge: bool,
) -> anyhow::Result<()> {
let installed = config.local_channel(requested).and_then(|version| state.get(&version));
let Some(installation) = installed else {
bail!("channel {requested} is not installed, nothing to uninstall");
};
let channel = installation.channel.clone();
let publication = match &installation.publication {
PublicationRef::Managed { id, .. } => Some(id.clone()),
PublicationRef::NeedsReinstall => None,
};
let home = &config.midenup_home;
let entry = JournalEntry::uninstall(channel.clone(), publication);
crate::publish::journal::prepare(home, &entry)?;
for (network, linked) in crate::networks::links(home) {
if linked == channel {
let link = paths::network_link(home, &network);
crate::trace!("removing {}", link.display());
std::fs::remove_file(link)?;
}
}
crate::publish::journal::commit_symlink(home, &entry)?;
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 {channel}. Set a new one with:\n \
midenup override <channel>"
);
}
crate::publish::journal::finish(home, &entry, state)?;
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()
);
}
}
crate::info!("uninstalled channel '{channel}'");
Ok(())
}