Skip to content

Commit

Permalink
uninstall: added --all and --dry-run features (#989)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx authored Nov 9, 2023
1 parent 9084a69 commit 7f2197d
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 26 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ v20.0.0
- [`rtx sync node <--brew|--nvm|--nodenv>`](#rtx-sync-node---brew--nvm--nodenv)
- [`rtx sync python --pyenv`](#rtx-sync-python---pyenv)
- [`rtx trust [OPTIONS] [CONFIG_FILE]`](#rtx-trust-options-config_file)
- [`rtx uninstall <TOOL@VERSION>...`](#rtx-uninstall-toolversion)
- [`rtx uninstall [OPTIONS] <TOOL@VERSION>...`](#rtx-uninstall-options-toolversion)
- [`rtx upgrade [TOOL@VERSION]...`](#rtx-upgrade-toolversion)
- [`rtx use [OPTIONS] [TOOL@VERSION]...`](#rtx-use-options-toolversion)
- [`rtx version`](#rtx-version)
Expand Down Expand Up @@ -2455,20 +2455,28 @@ Examples:
# trusts .rtx.toml in the current or parent directory
$ rtx trust
```
### `rtx uninstall <TOOL@VERSION>...`
### `rtx uninstall [OPTIONS] <TOOL@VERSION>...`
```
Removes runtime versions

Usage: uninstall <TOOL@VERSION>...
Usage: uninstall [OPTIONS] <TOOL@VERSION>...

Arguments:
<TOOL@VERSION>...
Tool(s) to remove

Options:
-a, --all
Delete all installed versions

-n, --dry-run
Do not actually delete anything

Examples:
$ rtx uninstall [email protected] # will uninstall specific version
$ rtx uninstall node # will uninstall current node version
$ rtx uninstall --all [email protected] # will uninstall all node versions
```
### `rtx upgrade [TOOL@VERSION]...`
Expand Down
4 changes: 4 additions & 0 deletions completions/_rtx
Original file line number Diff line number Diff line change
Expand Up @@ -1608,6 +1608,10 @@ _arguments "${_arguments_options[@]}" \
'--jobs=[Number of plugins and runtimes to install in parallel
\[default\: 4\]]: : ' \
'--log-level=[Set the log output verbosity]:LEVEL: ' \
'-a[Delete all installed versions]' \
'--all[Delete all installed versions]' \
'-n[Do not actually delete anything]' \
'--dry-run[Do not actually delete anything]' \
'--debug[Sets log level to debug]' \
'--install-missing[Automatically install missing tools]' \
'-r[Directly pipe stdin/stdout/stderr to user.
Expand Down
2 changes: 1 addition & 1 deletion completions/rtx.bash
Original file line number Diff line number Diff line change
Expand Up @@ -3301,7 +3301,7 @@ _rtx() {
return 0
;;
rtx__uninstall)
opts="-j -r -y -v -h --debug --install-missing --jobs --log-level --raw --yes --trace --verbose --help <TOOL@VERSION>..."
opts="-a -n -j -r -y -v -h --all --dry-run --debug --install-missing --jobs --log-level --raw --yes --trace --verbose --help <TOOL@VERSION>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
Expand Down
2 changes: 2 additions & 0 deletions completions/rtx.fish
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,8 @@ complete -c rtx -n "__fish_seen_subcommand_from trust" -s h -l help -d 'Print he
complete -c rtx -n "__fish_seen_subcommand_from uninstall" -s j -l jobs -d 'Number of plugins and runtimes to install in parallel
[default: 4]' -r
complete -c rtx -n "__fish_seen_subcommand_from uninstall" -l log-level -d 'Set the log output verbosity' -r
complete -c rtx -n "__fish_seen_subcommand_from uninstall" -s a -l all -d 'Delete all installed versions'
complete -c rtx -n "__fish_seen_subcommand_from uninstall" -s n -l dry-run -d 'Do not actually delete anything'
complete -c rtx -n "__fish_seen_subcommand_from uninstall" -l debug -d 'Sets log level to debug'
complete -c rtx -n "__fish_seen_subcommand_from uninstall" -l install-missing -d 'Automatically install missing tools'
complete -c rtx -n "__fish_seen_subcommand_from uninstall" -s r -l raw -d 'Directly pipe stdin/stdout/stderr to user.
Expand Down
17 changes: 16 additions & 1 deletion e2e/test_uninstall
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,19 @@ source "$(dirname "$0")/assert.sh"
rtx i
rtx uninstall tiny
export CLICOLOR=0
assert_contains "rtx ls" "3.1.0 (missing)"
assert_contains "rtx ls tiny" "3.1.0 (missing)"

rtx i tiny@1 [email protected] [email protected]
assert_contains "rtx ls tiny" "1.0.1"
assert_contains "rtx ls tiny" "2.0.1"
assert_contains "rtx ls tiny" "2.1.0"

rtx rm -a tiny@2
assert_contains "rtx ls tiny" "1.0.1"
assert_not_contains "rtx ls tiny" "2.0.1"
assert_not_contains "rtx ls tiny" "2.1.0"

rtx rm -a tiny
assert_not_contains "rtx ls tiny" "1.0.1"
assert_not_contains "rtx ls tiny" "2.0.1"
assert_not_contains "rtx ls tiny" "2.1.0"
81 changes: 60 additions & 21 deletions src/cli/uninstall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::cli::args::tool::{ToolArg, ToolArgParser};
use crate::cli::command::Command;
use crate::config::Config;
use crate::output::Output;
use crate::toolset::ToolsetBuilder;
use crate::toolset::{ToolVersion, ToolVersionRequest, ToolsetBuilder};
use crate::ui::multi_progress_report::MultiProgressReport;
use crate::{runtime_symlinks, shims};

Expand All @@ -16,30 +16,68 @@ pub struct Uninstall {
/// Tool(s) to remove
#[clap(required = true, value_name="TOOL@VERSION", value_parser = ToolArgParser)]
tool: Vec<ToolArg>,

/// Delete all installed versions
#[clap(long, short = 'a')]
all: bool,

/// Do not actually delete anything
#[clap(long, short = 'n')]
dry_run: bool,
}

impl Command for Uninstall {
fn run(self, mut config: Config, _out: &mut Output) -> Result<()> {
let runtimes = ToolArg::double_tool_condition(&self.tool);
let tool_versions = runtimes
.iter()
.map(|a| {
let tool = config.get_or_create_tool(&a.plugin);
let tv = match &a.tvr {
Some(tvr) => tvr.resolve(&config, &tool, Default::default(), false)?,
None => {
let ts = ToolsetBuilder::new().build(&mut config)?;
let tv = ts
.versions
.get(&a.plugin)
.and_then(|v| v.versions.first())
.expect("no version found");
tv.clone()
}
};
Ok((tool, tv))
})
.collect::<Result<Vec<_>>>()?;

let mut tool_versions = vec![];
if self.all {
for runtime in runtimes {
let tool = config.get_or_create_tool(&runtime.plugin);
let query = runtime.tvr.map(|tvr| tvr.version()).unwrap_or_default();
let tvs = tool
.list_installed_versions()?
.into_iter()
.filter(|v| v.starts_with(&query))
.map(|v| {
let tvr = ToolVersionRequest::new(tool.name.clone(), &v);
let tv = ToolVersion::new(&tool, tvr, Default::default(), v);
(tool.clone(), tv)
})
.collect::<Vec<_>>();
if tvs.is_empty() {
warn!(
"no versions found for {}",
style(&tool.name).cyan().for_stderr()
);
}
tool_versions.extend(tvs);
}
} else {
tool_versions = runtimes
.into_iter()
.map(|a| {
let tool = config.get_or_create_tool(&a.plugin);
let tvs = match a.tvr {
Some(tvr) => {
vec![tvr.resolve(&config, &tool, Default::default(), false)?]
}
None => {
let ts = ToolsetBuilder::new().build(&mut config)?;
let tvl = ts.versions.get(&a.plugin).expect("no versions found");
tvl.versions.clone()
}
};
Ok(tvs
.into_iter()
.map(|tv| (tool.clone(), tv))
.collect::<Vec<_>>())
})
.collect::<Result<Vec<_>>>()?
.into_iter()
.flatten()
.collect::<Vec<_>>();
}

let mpr = MultiProgressReport::new(config.show_progress_bars());
for (plugin, tv) in tool_versions {
Expand All @@ -50,7 +88,7 @@ impl Command for Uninstall {

let mut pr = mpr.add();
plugin.decorate_progress_bar(&mut pr, Some(&tv));
if let Err(err) = plugin.uninstall_version(&config, &tv, &pr, false) {
if let Err(err) = plugin.uninstall_version(&config, &tv, &pr, self.dry_run) {
pr.error(err.to_string());
return Err(eyre!(err).wrap_err(format!("failed to uninstall {}", &tv)));
}
Expand All @@ -69,5 +107,6 @@ static AFTER_LONG_HELP: &str = color_print::cstr!(
r#"<bold><underline>Examples:</underline></bold>
$ <bold>rtx uninstall [email protected]</bold> # will uninstall specific version
$ <bold>rtx uninstall node</bold> # will uninstall current node version
$ <bold>rtx uninstall --all [email protected]</bold> # will uninstall all node versions
"#
);

0 comments on commit 7f2197d

Please sign in to comment.