Skip to main content

juliaup/
command_remove.rs

1#[cfg(not(windows))]
2use crate::operations::remove_symlink;
3use crate::utils::{print_juliaup_style, JuliaupMessageType};
4use crate::{
5    config_file::{load_mut_config_db, save_config_db, JuliaupConfigChannel},
6    global_paths::GlobalPaths,
7    operations::garbage_collect_versions,
8};
9use anyhow::{bail, Context, Result};
10
11pub fn run_command_remove(channel: &str, paths: &GlobalPaths) -> Result<()> {
12    let mut config_file = load_mut_config_db(paths)
13        .with_context(|| "`remove` command failed to load configuration data.")?;
14
15    if !config_file.data.installed_channels.contains_key(channel) {
16        bail!(
17            "'{}' cannot be removed because it is not currently installed. Please run `juliaup list` to see available channels.",
18            channel
19        );
20    }
21
22    if let Some(ref default_value) = config_file.data.default {
23        if channel == default_value {
24            bail!(
25                "'{}' cannot be removed because it is currently configured as the default channel.",
26                channel
27            );
28        }
29    }
30
31    if config_file
32        .data
33        .overrides
34        .iter()
35        .any(|i| i.channel == channel)
36    {
37        bail!(
38            "'{}' cannot be removed because it is currently used in a directory override.",
39            channel
40        );
41    }
42
43    let channel_info = config_file.data.installed_channels.get(channel).unwrap();
44
45    // Determine what type of channel is being removed for better messaging
46    let channel_type = match channel_info {
47        JuliaupConfigChannel::DirectDownloadChannel { .. } => "channel".to_string(),
48        JuliaupConfigChannel::SystemChannel { .. } => "channel".to_string(),
49        JuliaupConfigChannel::LinkedChannel { .. } => "linked channel".to_string(),
50        JuliaupConfigChannel::AliasChannel { target, .. } => {
51            format!("alias (pointing to '{target}')")
52        }
53    };
54
55    if let JuliaupConfigChannel::DirectDownloadChannel {
56        path,
57        url: _,
58        local_etag: _,
59        server_etag: _,
60        version: _,
61        binary_path: _,
62    } = channel_info
63    {
64        let path_to_delete = paths.juliauphome.join(path);
65
66        let display = path_to_delete.display();
67
68        if std::fs::remove_dir_all(&path_to_delete).is_err() {
69            eprintln!("WARNING: Failed to delete {display}. You can try to delete at a later point by running `juliaup gc`.")
70        }
71    };
72
73    config_file.data.installed_channels.remove(channel);
74
75    #[cfg(not(windows))]
76    remove_symlink(&format!("julia-{channel}"))?;
77
78    garbage_collect_versions(false, &mut config_file.data, paths)?;
79
80    save_config_db(&mut config_file).with_context(|| {
81        format!(
82            "Failed to save configuration file from `remove` command after '{channel}' was removed."
83        )
84    })?;
85
86    print_juliaup_style(
87        "Remove",
88        &format!("Julia {channel_type} '{channel}' successfully removed."),
89        JuliaupMessageType::Success,
90    );
91
92    Ok(())
93}