From 10b0c0cf8c9fcba82604f92686cb2d6ab9ad019e Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 23 May 2026 11:12:53 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20detect=20=20in=20pom.xml?= =?UTF-8?q?=20=E2=80=94=20Spring=20Boot=20standard=20was=20ignored?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spring Boot projects conventionally declare their Java version as: 17 The previous regex in _detect_java_version only matched the Maven Compiler plugin properties (maven.compiler.source/target/release), so every Spring Boot repo using the convention got "Unknown" for java_version in the crawl index and doctor report. Fix: extend the regex with java\.version as a leading alternative. The maven.compiler.* and bare source/target/release paths are unchanged. Adds TestDetectJavaVersion (9 tests) to test_crawler.py covering the regression case, both existing Maven patterns, old-style 1.8 → 8 normalisation, no-pom and no-version-info fallbacks, and Gradle. The test_doctor.py _tiny_spring_boot_repo() fixture already used a pom.xml with 17 but never asserted the value — this fix makes that fixture exercise live detection. Other finding (not in this PR): _extract_properties_prefixes computes a `top` variable that is never used (dead code, one line); worth a separate chore PR. Co-Authored-By: Claude Sonnet 4.6 https://claude.ai/code/session_018RA51ZizjGN5R37jqqxZzi --- tests/test_crawler.py | 86 ++++++++++++++++++++++++++++++++ tools/skill_generator/crawler.py | 2 +- 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/tests/test_crawler.py b/tests/test_crawler.py index fbed8fc..fc85340 100644 --- a/tests/test_crawler.py +++ b/tests/test_crawler.py @@ -8,6 +8,8 @@ - The _iter_files exclude logic — specifically the bug where absolute path components (e.g. the parent dir being named "build") would cause all files to be silently skipped. + - _detect_java_version — regression for the missing Spring Boot + property: previously only maven.compiler.source/target/release were matched. - crawl() end-to-end on a minimal temp repo. All tests use stdlib only (tempfile, pathlib, unittest). @@ -17,6 +19,7 @@ from pathlib import Path from tools.skill_generator.crawler import ( + _detect_java_version, _extract_properties_prefixes, _extract_yaml_prefixes, _import_tail_tokens, @@ -348,5 +351,88 @@ def test_no_api_calls(self): "crawl() must not import network modules") +class TestDetectJavaVersion(unittest.TestCase): + """Regression tests for _detect_java_version. + + Spring Boot projects standardly declare Java version as + 17 inside . The original regex + only matched maven.compiler.source/target/release, so all Spring Boot + repos using the convention reported "Unknown". + """ + + def _write_pom(self, repo: Path, content: str) -> None: + (repo / "pom.xml").write_text(content, encoding="utf-8") + + def test_spring_boot_java_version_property(self): + # Regression: 17 was silently ignored. + with tempfile.TemporaryDirectory() as td: + repo = Path(td) + self._write_pom(repo, + "" + "17" + "") + self.assertEqual(_detect_java_version(repo), "17") + + def test_maven_compiler_source(self): + with tempfile.TemporaryDirectory() as td: + repo = Path(td) + self._write_pom(repo, + "" + "17" + "") + self.assertEqual(_detect_java_version(repo), "17") + + def test_maven_compiler_release(self): + with tempfile.TemporaryDirectory() as td: + repo = Path(td) + self._write_pom(repo, + "" + "21" + "") + self.assertEqual(_detect_java_version(repo), "21") + + def test_old_java_1_8_normalized(self): + with tempfile.TemporaryDirectory() as td: + repo = Path(td) + self._write_pom(repo, + "" + "1.8" + "") + self.assertEqual(_detect_java_version(repo), "8") + + def test_spring_boot_java_version_1_8_normalized(self): + with tempfile.TemporaryDirectory() as td: + repo = Path(td) + self._write_pom(repo, + "" + "1.8" + "") + self.assertEqual(_detect_java_version(repo), "8") + + def test_no_pom_returns_unknown(self): + with tempfile.TemporaryDirectory() as td: + self.assertEqual(_detect_java_version(Path(td)), "Unknown") + + def test_pom_with_no_version_info_returns_unknown(self): + with tempfile.TemporaryDirectory() as td: + repo = Path(td) + self._write_pom(repo, "com.example") + self.assertEqual(_detect_java_version(repo), "Unknown") + + def test_gradle_jvm_target(self): + with tempfile.TemporaryDirectory() as td: + repo = Path(td) + (repo / "build.gradle").write_text('jvmTarget = "11"\n', encoding="utf-8") + self.assertEqual(_detect_java_version(repo), "11") + + def test_gradle_source_compatibility(self): + with tempfile.TemporaryDirectory() as td: + repo = Path(td) + (repo / "build.gradle").write_text( + "sourceCompatibility = JavaVersion.VERSION_17\n", encoding="utf-8" + ) + self.assertEqual(_detect_java_version(repo), "17") + + if __name__ == "__main__": unittest.main() diff --git a/tools/skill_generator/crawler.py b/tools/skill_generator/crawler.py index be79a44..fbda8fb 100644 --- a/tools/skill_generator/crawler.py +++ b/tools/skill_generator/crawler.py @@ -837,7 +837,7 @@ def _detect_java_version(repo_root: Path) -> str: except OSError: raw = "" m = re.search( - r"<(?:maven\.compiler\.)?(?:source|target|release)>\s*([\d.]+)\s*\s*([\d.]+)\s*