Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions task_helper/src/build_tool/maven.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ impl Maven {
is_debug().then(|| "-Dmaven.surefire.debug".to_string())
}

fn application_args(full_name: &str) -> String {
let mut args = vec![];
if is_debug() {
args.push(get_jdwp_args());
}
args.extend([
"-classpath".to_string(),
"%classpath".to_string(),
full_name.to_string(),
]);
format!("-Dexec.args={}", args.join(" "))
}

fn test_filter(
package: &str,
class: &str,
Expand Down Expand Up @@ -82,12 +95,15 @@ impl BuildTool for Maven {
let compile_goal = if is_test { "test-compile" } else { "compile" };
let classpath_scope = if is_test { "test" } else { "runtime" };

let mut args = vec![compile_goal.to_string(), "exec:java".to_string()];
let mut args = vec![compile_goal.to_string(), "exec:exec".to_string()];
args.extend(Self::module_prefix(&module));
args.push(format!("-Dexec.mainClass={}", full_name));
args.push("-Dexec.executable=java".to_string());
args.push(Self::application_args(&full_name));
args.push(format!("-Dexec.classpathScope={}", classpath_scope));
args.push("-Dexec.inheritIo=true".to_string());
args.push("-Dexec.longClasspath=true".to_string());

task(self.command(), args, self.cwd(), Self::debug_env())
task(self.command(), args, self.cwd(), vec![])
}

fn run_test_method(
Expand Down
65 changes: 53 additions & 12 deletions tests/task_verification_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ impl<'a> TaskRunner<'a> {
.push(("ZED_CUSTOM_java_outer_class_name", o.to_string()));
self
}
fn env(mut self, key: &'static str, value: &str) -> Self {
self.extra_env.push((key, value.to_string()));
self
}

fn run(self) -> String {
let mut cmd = std::process::Command::new("sh");
Expand All @@ -236,7 +240,11 @@ impl<'a> TaskRunner<'a> {

// Create a temporary ZED_EXT directory structure matching what tasks.json expects
let zed_ext_base = self.project.temp_dir.join("mock_zed_ext");
let zed_ext_dir = zed_ext_base.join("zed/extensions/work/java/task-bin");
let zed_ext_dir = if cfg!(target_os = "macos") {
zed_ext_base.join("Library/Application Support/Zed/extensions/work/java/task-bin")
} else {
zed_ext_base.join("zed/extensions/work/java/task-bin")
};
fs::create_dir_all(&zed_ext_dir).unwrap();
let dest_bin = zed_ext_dir.join("java-task-helper");
fs::copy(&found_bin, &dest_bin).unwrap();
Expand All @@ -253,6 +261,7 @@ impl<'a> TaskRunner<'a> {
.env("ZED_CUSTOM_java_package_name", &self.package)
.env("ZED_CUSTOM_java_class_name", &self.class)
.env("PATH", &self.project.new_path)
.env("HOME", &zed_ext_base)
.env("XDG_DATA_HOME", zed_ext_base.to_string_lossy().to_string())
.current_dir(&self.project.temp_dir);

Expand Down Expand Up @@ -286,18 +295,26 @@ fn test_maven_single_module_command_logic() {
.run();

assert!(
stdout.contains("MVN_CALLED: compile exec:java"),
stdout.contains("MVN_CALLED: compile exec:exec"),
"Should run as single module. Got: {}",
stdout
);
assert!(
stdout.contains("-Dexec.executable=java")
&& stdout.contains("-Dexec.args=-classpath %classpath com.example.Main")
&& stdout.contains("-Dexec.inheritIo=true")
&& stdout.contains("-Dexec.longClasspath=true"),
"Should launch the main class in a standalone JVM. Got: {}",
stdout
);
assert!(
stdout.contains("-Dexec.classpathScope=runtime"),
"Should use runtime classpath scope. Got: {}",
stdout
);
assert!(
stdout_test
.contains("MVN_CALLED: test-compile exec:java -Dexec.mainClass=com.example.Main"),
stdout_test.contains("MVN_CALLED: test-compile exec:exec")
&& stdout_test.contains("-Dexec.args=-classpath %classpath com.example.Main"),
"Should run as single module. Got: {}",
stdout_test
);
Expand All @@ -319,12 +336,12 @@ fn test_maven_multi_module_command_logic() {
.run();

assert!(
stdout.contains("MVN_CALLED: compile exec:java -pl module-a -am"),
stdout.contains("MVN_CALLED: compile exec:exec -pl module-a -am"),
"Should build submodule with dependencies. Got: {}",
stdout
);
assert!(
stdout.contains("-Dexec.mainClass=com.example.Main"),
stdout.contains("-Dexec.args=-classpath %classpath com.example.Main"),
"Should run only the submodule. Got: {}",
stdout
);
Expand All @@ -335,12 +352,12 @@ fn test_maven_multi_module_command_logic() {
);

assert!(
stdout_test.contains("MVN_CALLED: test-compile exec:java -pl module-a -am"),
stdout_test.contains("MVN_CALLED: test-compile exec:exec -pl module-a -am"),
"Should build submodule with dependencies. Got: {}",
stdout_test
);
assert!(
stdout_test.contains("-Dexec.mainClass=com.example.Main"),
stdout_test.contains("-Dexec.args=-classpath %classpath com.example.Main"),
"Should run only the submodule. Got: {}",
stdout_test
);
Expand All @@ -361,12 +378,12 @@ fn test_maven_nested_module_command_logic() {
.run();

assert!(
stdout.contains("MVN_CALLED: test-compile exec:java -pl nested/module-b -am"),
stdout.contains("MVN_CALLED: test-compile exec:exec -pl nested/module-b -am"),
"Should build nested submodule with dependencies. Got: {}",
stdout
);
assert!(
stdout.contains("-Dexec.mainClass=com.example.Main"),
stdout.contains("-Dexec.args=-classpath %classpath com.example.Main"),
"Should run only the nested submodule. Got: {}",
stdout
);
Expand Down Expand Up @@ -463,7 +480,7 @@ fn test_maven_single_level_package_logic() {
.run();

assert!(
stdout.contains("-Dexec.mainClass=example.Main"),
stdout.contains("-Dexec.args=-classpath %classpath example.Main"),
"Should include the single-level package in Maven. Got: {}",
stdout
);
Expand All @@ -475,12 +492,36 @@ fn test_maven_default_package_command_logic() {
let stdout = project.task("java-main").package("").class("Main").run();

assert!(
stdout.contains("-Dexec.mainClass=Main"),
stdout.contains("-Dexec.args=-classpath %classpath Main"),
"Should not include leading dot for default package in Maven. Got: {}",
stdout
);
}

#[test]
fn test_maven_debugs_standalone_jvm() {
let project = TestProject::new("maven_debug", "maven", None);
let stdout = project
.task("java-main")
.env("ZED_JAVA_DEBUG", "1")
.env("ZED_JAVA_DEBUG_PORT", "6123")
.run();

assert!(
stdout.contains(
"-Dexec.args=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=6123 \
-classpath %classpath com.example.Main"
),
"Should pass JDWP options to the standalone JVM. Got: {}",
stdout
);
assert!(
!stdout.contains("MAVEN_OPTS"),
"Should not debug the Maven process. Got: {}",
stdout
);
}

#[test]
fn test_maven_default_package_test_method_logic() {
let project = TestProject::new("maven_default_test", "maven", None);
Expand Down