use eyre::Result;
use crate::cli::args::ToolArg;
use crate::config::Config;
use crate::dirs::SHIMS;
use crate::toolset::{Toolset, ToolsetBuilder};
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)]
pub struct Which {
#[clap()]
pub bin_name: String,
#[clap(long, conflicts_with = "version")]
pub plugin: bool,
#[clap(long, conflicts_with = "plugin")]
pub version: bool,
#[clap(short, long, value_name = "TOOL@VERSION", verbatim_doc_comment)]
pub tool: Option<ToolArg>,
}
impl Which {
pub fn run(self) -> Result<()> {
let ts = self.get_toolset()?;
match ts.which(&self.bin_name) {
Some((p, tv)) => {
if self.version {
miseprintln!("{}", tv.version);
} else if self.plugin {
miseprintln!("{p}");
} else {
let path = p.which(&tv, &self.bin_name)?;
miseprintln!("{}", path.unwrap().display());
}
Ok(())
}
None => {
if self.has_shim(&self.bin_name) {
bail!("{} is an mise bin however it is not currently active. Use `mise use` to activate it in this directory.", self.bin_name)
} else {
bail!(
"{} is not an mise bin. Perhaps you need to install it first.",
self.bin_name
)
}
}
}
}
fn get_toolset(&self) -> Result<Toolset> {
let config = Config::try_get()?;
let mut tsb = ToolsetBuilder::new();
if let Some(tool) = &self.tool {
tsb = tsb.with_args(&[tool.clone()]);
}
let ts = tsb.build(&config)?;
Ok(ts)
}
fn has_shim(&self, shim: &str) -> bool {
SHIMS.join(shim).exists()
}
}
static AFTER_LONG_HELP: &str = color_print::cstr!(
r#"<bold><underline>Examples:</underline></bold>
$ <bold>mise which node</bold>
/home/username/.local/share/mise/installs/node/20.0.0/bin/node
$ <bold>mise which node --plugin</bold>
node
$ <bold>mise which node --version</bold>
20.0.0
"#
);
#[cfg(test)]
mod tests {
#[test]
fn test_which() {
assert_cli!("use", "dummy@1.0.0");
assert_cli_snapshot!("which", "dummy");
assert_cli!("use", "dummy@ref:master");
assert_cli!("uninstall", "dummy@1.0.0");
assert_cli!("use", "--rm", "dummy");
}
#[test]
fn test_which_plugin() {
assert_cli!("use", "dummy@1.0.0");
assert_cli_snapshot!("which", "--plugin", "dummy");
assert_cli!("use", "dummy@ref:master");
assert_cli!("uninstall", "dummy@1.0.0");
assert_cli!("use", "--rm", "dummy");
}
#[test]
fn test_which_version() {
assert_cli!("use", "dummy@1.0.0");
assert_cli_snapshot!("which", "--version", "dummy");
assert_cli!("use", "dummy@ref:master");
assert_cli!("uninstall", "dummy@1.0.0");
assert_cli!("use", "--rm", "dummy");
}
#[test]
fn test_which_tool() {
assert_cli!("install", "dummy@1.0.1");
assert_cli_snapshot!("which", "dummy", "--tool=dummy@1.0.1");
}
}