use std::sync::Arc;
use color_eyre::eyre::Result;
use rayon::prelude::*;
use crate::cli::args::tool::ToolArg;
use crate::cli::args::tool::ToolArgParser;
use crate::config::Config;
use crate::output::Output;
use crate::plugins::Plugin;
use crate::toolset::ToolVersionRequest;
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, after_long_help = AFTER_LONG_HELP, aliases = ["list-all", "list-remote"])]
pub struct LsRemote {
#[clap(value_name = "TOOL@VERSION", value_parser = ToolArgParser, required_unless_present = "all")]
plugin: Option<ToolArg>,
#[clap(long, verbatim_doc_comment, conflicts_with_all = ["plugin", "prefix"])]
all: bool,
#[clap(verbatim_doc_comment)]
prefix: Option<String>,
}
impl LsRemote {
pub fn run(self, mut config: Config, out: &mut Output) -> Result<()> {
if let Some(plugin) = self.get_plugin(&mut config)? {
self.run_single(config, out, plugin)
} else {
self.run_all(config, out)
}
}
fn run_single(self, config: Config, out: &mut Output, plugin: Arc<dyn Plugin>) -> Result<()> {
let prefix = match &self.plugin {
Some(tool_arg) => match &tool_arg.tvr {
Some(ToolVersionRequest::Version(_, v)) => Some(v.clone()),
_ => self.prefix.clone(),
},
_ => self.prefix.clone(),
};
let versions = plugin.list_remote_versions(&config.settings)?;
let versions = match prefix {
Some(prefix) => versions
.into_iter()
.filter(|v| v.starts_with(&prefix))
.collect(),
None => versions,
};
for version in versions {
rtxprintln!(out, "{}", version);
}
Ok(())
}
fn run_all(self, config: Config, out: &mut Output) -> Result<()> {
let versions = config
.plugins
.values()
.par_bridge()
.map(|p| {
let versions = p.list_remote_versions(&config.settings)?;
Ok((p, versions))
})
.collect::<Result<Vec<_>>>()?;
for (plugin, versions) in versions {
for v in versions {
rtxprintln!(out, "{}@{v}", plugin);
}
}
Ok(())
}
fn get_plugin(&self, config: &mut Config) -> Result<Option<Arc<dyn Plugin>>> {
match &self.plugin {
Some(tool_arg) => {
let plugin = config.get_or_create_plugin(&tool_arg.plugin);
plugin.ensure_installed(config, None, false)?;
Ok(Some(plugin))
}
None => Ok(None),
}
}
}
static AFTER_LONG_HELP: &str = color_print::cstr!(
r#"<bold><underline>Examples:</underline></bold>
$ <bold>rtx ls-remote node</bold>
18.0.0
20.0.0
$ <bold>rtx ls-remote node@20</bold>
20.0.0
20.1.0
$ <bold>rtx ls-remote node 20</bold>
20.0.0
20.1.0
"#
);
#[cfg(test)]
mod tests {
use crate::assert_cli_snapshot;
#[test]
fn test_list_remote() {
assert_cli_snapshot!("list-remote", "dummy");
}
#[test]
fn test_ls_remote_prefix() {
assert_cli_snapshot!("list-remote", "dummy", "1");
assert_cli_snapshot!("list-remote", "dummy@2");
}
}