use crate::cli::args::ToolArg;
use crate::config::Config;
use crate::config::settings::Settings;
use crate::duration::parse_into_timestamp;
use crate::install_context::InstallContext;
use crate::toolset::tool_request::effective_before_date;
use crate::toolset::{ResolveOptions, ToolsetBuilder};
use crate::ui::multi_progress_report::MultiProgressReport;
use clap::ValueHint;
use eyre::{Result, eyre};
use std::{path::PathBuf, sync::Arc};
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)]
pub struct InstallInto {
#[clap(value_name = "TOOL@VERSION")]
tool: ToolArg,
#[clap(value_hint = ValueHint::DirPath)]
path: PathBuf,
}
impl InstallInto {
pub async fn run(self) -> Result<()> {
let config = Config::get().await?;
let before_date = match self.tool.tvr.as_ref() {
Some(tvr) => effective_before_date(tvr, &Default::default())?,
None => Settings::get()
.install_before
.as_deref()
.map(parse_into_timestamp)
.transpose()?,
};
let ts = Arc::new(
ToolsetBuilder::new()
.with_args(std::slice::from_ref(&self.tool))
.with_resolve_options(ResolveOptions {
before_date,
..Default::default()
})
.build(&config)
.await?,
);
let mut tv = ts
.versions
.get(self.tool.ba.as_ref())
.ok_or_else(|| eyre!("Tool not found"))?
.versions
.first()
.unwrap()
.clone();
let backend = tv.backend()?;
let mpr = MultiProgressReport::get();
let install_ctx = InstallContext {
config: config.clone(),
ts: ts.clone(),
pr: mpr.add(&tv.style()),
force: true,
dry_run: false,
locked: false, before_date,
};
tv.install_path = Some(self.path.clone());
backend.install_version(install_ctx, tv).await?;
Ok(())
}
}
static AFTER_LONG_HELP: &str = color_print::cstr!(
r#"<bold><underline>Examples:</underline></bold>
# install node@20.0.0 into ./mynode
$ <bold>mise install-into node@20.0.0 ./mynode && ./mynode/bin/node -v</bold>
20.0.0
"#
);