diff --git a/README.md b/README.md index 5bad41ed6..0f997f743 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ v20.0.0 - [`rtx install [OPTIONS] [TOOL@VERSION]...`](#rtx-install-options-toolversion) - [`rtx latest [OPTIONS] `](#rtx-latest-options-toolversion) - [`rtx link [OPTIONS] `](#rtx-link-options-toolversion-path) - - [`rtx ls [OPTIONS] [PLUGIN]`](#rtx-ls-options-plugin) + - [`rtx ls [OPTIONS] [PLUGIN]...`](#rtx-ls-options-plugin) - [`rtx ls-remote [OPTIONS] [TOOL@VERSION] [PREFIX]`](#rtx-ls-remote-options-toolversion-prefix) - [`rtx outdated [TOOL@VERSION]...`](#rtx-outdated-toolversion) - [`rtx plugins install [OPTIONS] [NEW_PLUGIN] [GIT_URL]`](#rtx-plugins-install-options-new_plugin-git_url) @@ -2084,15 +2084,15 @@ Examples: $ rtx use node@brew ``` -### `rtx ls [OPTIONS] [PLUGIN]` +### `rtx ls [OPTIONS] [PLUGIN]...` ```text List installed and/or currently selected tool versions -Usage: ls [OPTIONS] [PLUGIN] +Usage: ls [OPTIONS] [PLUGIN]... Arguments: - [PLUGIN] + [PLUGIN]... Only show tool versions from [PLUGIN] Options: diff --git a/completions/_rtx b/completions/_rtx index fb60bac41..9cddd3dd3 100644 --- a/completions/_rtx +++ b/completions/_rtx @@ -405,7 +405,7 @@ __rtx_local_cmd() { (( $+functions[__rtx_ls_cmd] )) || __rtx_ls_cmd() { _arguments -s -S \ - '::plugin:__rtx_plugins' \ + '*::plugin:__rtx_plugins' \ '(-c --current)'{-c,--current}'[Only show tool versions currently specified in a .tool-versions/.rtx.toml]' \ '(-g --global)'{-g,--global}'[Only show tool versions currently specified in a the global .tool-versions/.rtx.toml]' \ '(-i --installed)'{-i,--installed}'[Only show tool versions that are installed Hides missing ones defined in .tool-versions/.rtx.toml but not yet installed]' \ diff --git a/completions/rtx.bash b/completions/rtx.bash index 3cf07db92..964e1d0d4 100644 --- a/completions/rtx.bash +++ b/completions/rtx.bash @@ -2449,7 +2449,7 @@ _rtx() { return 0 ;; rtx__ls) - opts="-p -c -g -i -J -m -j -q -r -v -y -h --plugin --current --global --installed --parseable --json --missing --prefix --jobs --debug --log-level --trace --quiet --raw --verbose --yes --help [PLUGIN]" + opts="-p -c -g -i -J -m -j -q -r -v -y -h --plugin --current --global --installed --parseable --json --missing --prefix --jobs --debug --log-level --trace --quiet --raw --verbose --yes --help [PLUGIN]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/cli/ls.rs b/src/cli/ls.rs index 7a27e2fa7..79287c6bd 100644 --- a/src/cli/ls.rs +++ b/src/cli/ls.rs @@ -22,10 +22,10 @@ use crate::toolset::{ToolSource, ToolVersion, ToolsetBuilder}; pub struct Ls { /// Only show tool versions from [PLUGIN] #[clap(conflicts_with = "plugin_flag")] - plugin: Option, + plugin: Option>, #[clap(long = "plugin", short, hide = true)] - plugin_flag: Option, + plugin_flag: Option, /// Only show tool versions currently specified in a .tool-versions/.rtx.toml #[clap(long, short)] @@ -61,9 +61,8 @@ impl Ls { pub fn run(mut self, config: Config) -> Result<()> { self.plugin = self .plugin - .clone() - .or(self.plugin_flag.clone()) - .map(|p| PluginName::from(unalias_plugin(&p))); + .or_else(|| self.plugin_flag.clone().map(|p| vec![p])) + .map(|p| p.into_iter().map(|p| unalias_plugin(&p).into()).collect()); self.verify_plugin(&config)?; let mut runtimes = self.get_runtime_list(&config)?; @@ -92,10 +91,12 @@ impl Ls { fn verify_plugin(&self, config: &Config) -> Result<()> { match &self.plugin { - Some(plugin_name) => { - let plugin = config.get_or_create_plugin(plugin_name); - if !plugin.is_installed() { - return Err(PluginNotInstalled(plugin_name.clone()))?; + Some(plugins) => { + for plugin_name in plugins { + let plugin = config.get_or_create_plugin(plugin_name); + if !plugin.is_installed() { + return Err(PluginNotInstalled(plugin_name.clone()))?; + } } } None => {} @@ -104,11 +105,11 @@ impl Ls { } fn display_json(&self, runtimes: Vec) -> Result<()> { - if let Some(plugin) = &self.plugin { + if let Some(plugins) = &self.plugin { // only runtimes for 1 plugin let runtimes: Vec = runtimes .into_iter() - .filter(|(p, _, _)| plugin.eq(&p.name())) + .filter(|(p, _, _)| plugins.contains(&p.name().to_string())) .map(|row| row.into()) .collect(); rtxprintln!("{}", serde_json::to_string_pretty(&runtimes)?); @@ -206,8 +207,9 @@ impl Ls { fn get_runtime_list(&self, config: &Config) -> Result> { let mut tsb = ToolsetBuilder::new().with_global_only(self.global); - if let Some(plugin) = &self.plugin { - tsb = tsb.with_tools(&[plugin]); + if let Some(plugins) = &self.plugin { + let plugins = plugins.iter().map(|p| p.as_str()).collect_vec(); + tsb = tsb.with_tools(&plugins); } let ts = tsb.build(config)?; let mut versions: HashMap<(String, String), (Arc, ToolVersion)> = ts @@ -227,7 +229,7 @@ impl Ls { let rvs: Vec = versions .into_iter() .filter(|((plugin_name, _), _)| match &self.plugin { - Some(p) => p.eq(plugin_name), + Some(p) => p.contains(plugin_name), None => true, }) .sorted_by_cached_key(|((plugin_name, version), _)| {