use anyhow::{Context, Result, bail};
use clap::Args;
use console::style;
use std::path::PathBuf;
use which::which;
use crate::utils::jdk::{detect_java_version, find_jdk_home, find_pom};
#[derive(Args)]
pub struct MvnArgs {
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
pub mvn_args: Vec<String>,
#[arg(short, long, default_value = ".")]
pub dir: PathBuf,
}
pub fn run(args: MvnArgs) -> Result<()> {
let pom = find_pom(&args.dir.canonicalize().unwrap_or_else(|_| args.dir.clone()))
.with_context(|| format!("no pom.xml found under {}", args.dir.display()))?;
let version = detect_java_version(&pom)
.with_context(|| format!("while reading {}", pom.display()))?;
let java_home = find_jdk_home(version)?;
let mvn_bin = which("mvn").with_context(|| {
format!(
"{} mvn not found in PATH",
style("✗").red().bold()
)
})?;
if mvn_bin.as_os_str().is_empty() {
bail!("mvn not found in PATH");
}
eprintln!(
"{} Java {} → {}",
style("▶").blue().bold(),
style(version).cyan(),
style(java_home.display()).dim()
);
eprintln!(
"{} mvn {}",
style("▶").blue().bold(),
style(args.mvn_args.join(" ")).dim()
);
let status = duct::cmd(&mvn_bin, &args.mvn_args)
.env("JAVA_HOME", &java_home)
.run()
.with_context(|| "failed to execute mvn")?;
if !status.status.success() {
std::process::exit(status.status.code().unwrap_or(1));
}
Ok(())
}