use anyhow::{Context, Result};
use clap::Args;
use console::style;
use std::path::PathBuf;
use crate::utils::jdk::{detect_java_version, find_jdk_home, find_pom};
#[derive(Args)]
pub struct JavaArgs {
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
pub java_args: Vec<String>,
#[arg(short, long, default_value = ".")]
pub dir: PathBuf,
}
pub fn run(args: JavaArgs) -> Result<()> {
let dir = args.dir.canonicalize().unwrap_or_else(|_| args.dir.clone());
let java_home = if let Some(pom) = find_pom(&dir) {
let version = detect_java_version(&pom)?;
eprintln!(
"{} Java {} (from pom.xml)",
style("▶").blue().bold(),
style(version).cyan()
);
find_jdk_home(version)?
} else if let Ok(home) = std::env::var("JAVA_HOME") {
eprintln!(
"{} Java from $JAVA_HOME",
style("▶").blue().bold()
);
PathBuf::from(home)
} else {
eprintln!(
"{} no pom.xml or $JAVA_HOME found, using system java",
style("!").yellow().bold()
);
let java_bin = which::which("java")
.with_context(|| "java not found in PATH")?;
let status = duct::cmd(&java_bin, &args.java_args)
.run()
.with_context(|| "failed to execute java")?;
if !status.status.success() {
std::process::exit(status.status.code().unwrap_or(1));
}
return Ok(());
};
let java_bin = java_home.join("bin/java");
let status = duct::cmd(&java_bin, &args.java_args)
.env("JAVA_HOME", &java_home)
.run()
.with_context(|| "failed to execute java")?;
if !status.status.success() {
std::process::exit(status.status.code().unwrap_or(1));
}
Ok(())
}