From 7ba75c814c50272c3c9bd5407d1e4d5c70d65974 Mon Sep 17 00:00:00 2001 From: arookieofc Date: Fri, 30 Oct 2026 19:04:06 +0800 Subject: [PATCH] fix(maven): resolve the configured Maven launcher for saved goal configurations (#424) Goal configurations saved from the Maven tool window kept the literal mvn / mvn.cmd, which could not start when Maven lives in a configured home or a version manager's shims. Saved configurations with a bare mvn launcher now take the configured Maven; custom paths and the wrapper are left alone. Co-authored-by: a-rookie-of-C-language <186315048+a-rookie-of-C-language@users.noreply.github.com> --- crates/ide-sdk/src/apply.rs | 11 +++++++++++ crates/ide-sdk/src/tests.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/crates/ide-sdk/src/apply.rs b/crates/ide-sdk/src/apply.rs index 5e0d685bd..9d258204d 100644 --- a/crates/ide-sdk/src/apply.rs +++ b/crates/ide-sdk/src/apply.rs @@ -662,6 +662,17 @@ pub fn apply_to_run_configs(configs: &mut [RunConfig], root: &Path, s: &Settings if !c.args.starts_with(&mvn_options) { c.args.splice(0..0, mvn_options.iter().cloned()); } + } else if c.kind == "maven" + && matches!(c.command.as_str(), "mvn" | "mvn.cmd" | "mvn.bat") + && let Some(mvn) = &mvn + { + // A goal configuration saved from the tool window keeps the + // literal `mvn` / `mvn.cmd` the launcher resolved to; without a + // wrapper it cannot start when Maven lives on a version + // manager's shims or a configured home (#328). Detected configs + // take the Maven options too, but the saved ones already baked + // them into `args`. + c.command = mvn.to_string_lossy().into_owned(); } } _ => {} diff --git a/crates/ide-sdk/src/tests.rs b/crates/ide-sdk/src/tests.rs index 7af792e02..b71cf73a1 100644 --- a/crates/ide-sdk/src/tests.rs +++ b/crates/ide-sdk/src/tests.rs @@ -208,6 +208,37 @@ fn project_jdk_and_maven_settings() { assert_eq!(project_jdk(tmp.path(), &s), None); } +#[test] +fn saved_maven_goal_configs_take_the_configured_launcher() { + if cfg!(windows) { + return; // Unix paths + } + let tmp = tempfile::tempdir().unwrap(); + let maven = tmp.path().join("maven"); + std::fs::create_dir_all(maven.join("bin")).unwrap(); + std::fs::write(maven.join("bin/mvn"), "").unwrap(); + let mut s = Settings::default(); + s.languages.java.maven.home = maven.to_string_lossy().into_owned(); + s.languages.java.maven.user_settings = "/m2/settings.xml".into(); + + // A goal configuration saved from the tool window (`mvn -s … clean`): + // the bare launcher resolves to the configured Maven home (#328) and its + // own args are left alone. + let mut saved = run("maven", "mvn", &["-s", "/m2/settings.xml", "clean"]); + saved.detected = false; + // A custom path / the wrapper stay as configured. + let mut custom = run("maven", "/opt/other/bin/mvn", &["package"]); + custom.detected = false; + let mut wrapper = run("maven", "./mvnw", &["package"]); + wrapper.detected = false; + let mut configs = vec![saved, custom, wrapper]; + apply_to_run_configs(&mut configs, tmp.path(), &s); + assert_eq!(configs[0].command, maven.join("bin/mvn").to_string_lossy()); + assert_eq!(configs[0].args, ["-s", "/m2/settings.xml", "clean"], "saved args are kept"); + assert_eq!(configs[1].command, "/opt/other/bin/mvn"); + assert_eq!(configs[2].command, "./mvnw"); +} + #[test] fn language_server_settings_disable_add_and_override() { use crate::apply::{language_servers, server_launch_overrides, server_protocol_overrides, with_custom_servers};