use std::sync::Arc;
use color_eyre::eyre::{eyre, Result};
use owo_colors::Stream;
use crate::cli::command::Command;
use crate::config::Config;
use crate::output::Output;
use crate::plugins::Plugin;
use crate::ui::color::cyan;
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, alias = "upgrade", after_long_help = AFTER_LONG_HELP)]
pub struct Update {
#[clap()]
plugin: Option<Vec<String>>,
#[clap(long, short = 'a', conflicts_with = "plugin")]
all: bool,
}
impl Command for Update {
fn run(self, config: Config, out: &mut Output) -> Result<()> {
let plugins: Vec<Arc<Plugin>> = match (self.plugin, self.all) {
(Some(plugins), _) => plugins
.into_iter()
.map(|p| {
config.ts.find_plugin(&p).ok_or_else(|| {
eyre!("plugin {} not found", cyan(Stream::Stderr, p.as_str()))
})
})
.collect::<Result<Vec<Arc<Plugin>>>>()?,
(_, true) => config.ts.list_installed_plugins(),
_ => Err(eyre!("no plugins specified"))?,
};
for plugin in plugins {
rtxprintln!(out, "updating plugin {}", plugin.name);
plugin.update(None)?;
}
Ok(())
}
}
const AFTER_LONG_HELP: &str = r#"
Examples:
rtx plugins update --all # update all plugins
rtx plugins update nodejs # update only nodejs
"#;
#[cfg(test)]
mod test {
use pretty_assertions::assert_str_eq;
use crate::{assert_cli, assert_cli_err};
#[test]
fn test_plugin_update() {
let err = assert_cli_err!("p", "update");
assert_str_eq!(err.to_string(), "no plugins specified");
assert_cli!("plugin", "update", "--all");
assert_cli!("plugins", "update", "nodejs");
}
}