diff --git a/crates/ide-run/src/detect.rs b/crates/ide-run/src/detect.rs index 7f7c714fe..438ccf6ba 100644 --- a/crates/ide-run/src/detect.rs +++ b/crates/ide-run/src/detect.rs @@ -571,7 +571,6 @@ const SPRING_SCAN_FILES: usize = 400; /// modules of the build in `build` that apply the Spring Boot plugin: /// `java -cp ${classpath} ` in the module, the classpath resolved at launch. fn spring_boot_apps(root: &Path, build: &Path, out: &mut Vec) { - let mut budget = SPRING_SCAN_FILES; let mut modules = vec![build.to_path_buf()]; let mut level = vec![build.to_path_buf()]; for _ in 0..ide_core::project_roots::SEARCH_DEPTH { @@ -579,12 +578,11 @@ fn spring_boot_apps(root: &Path, build: &Path, out: &mut Vec) { modules.extend(level.iter().cloned()); } for module in modules { - if budget == 0 { - break; - } if !applies_spring_boot(&module) { continue; } + // A budget per module: a large common library must not starve later app modules. + let mut budget = SPRING_SCAN_FILES; let module_rel = (module != root).then(|| relative(root, &module).to_string_lossy().replace('\\', "/")); for class in spring_boot_classes(&module, &mut budget) { let simple = class.rsplit(['.', '$']).next().unwrap_or(&class).to_owned(); diff --git a/crates/ide-run/tests/detect.rs b/crates/ide-run/tests/detect.rs index 4d6766cf1..73e5d3dc4 100644 --- a/crates/ide-run/tests/detect.rs +++ b/crates/ide-run/tests/detect.rs @@ -279,6 +279,32 @@ fn spring_boot_application_of_a_repository_nested_one_or_two_levels_down() { } } +#[test] +fn a_large_common_module_does_not_starve_later_app_modules() { + // More source files than one scan budget in `a-common` (no app class): the app in `b-app` must still be found. + let mut files: Vec<(String, String)> = vec![ + ("pom.xml".into(), "a-commonb-app".into()), + ("a-common/pom.xml".into(), BOOT_POM.into()), + ("b-app/pom.xml".into(), BOOT_POM.into()), + ( + "b-app/src/main/java/demo/App.java".into(), + "package demo;\n@SpringBootApplication\npublic class App {\n public static void main(String[] args) {}\n}\n".into(), + ), + ]; + for i in 0..401 { + files.push((format!("a-common/src/main/java/demo/C{i}.java"), format!("package demo;\nclass C{i} {{}}\n"))); + } + let dir = tempfile::tempdir().unwrap(); + for (path, content) in &files { + let p = dir.path().join(path); + fs::create_dir_all(p.parent().unwrap()).unwrap(); + fs::write(p, content).unwrap(); + } + let configs = detect(dir.path()); + let app = find(&configs, "application:b-app:demo.App"); + assert_eq!(app.kind, "spring-boot"); +} + #[test] fn nested_builds_of_every_kind_and_depth() { let dir = project(&[