[AI-8th] RRefactor auto-configuration registration migration checks to guard AutoConfiguration.imports#1420
[AI-8th] RRefactor auto-configuration registration migration checks to guard AutoConfiguration.imports#1420pmupkin wants to merge 1 commit intosofastack:masterfrom
Conversation
… guard AutoConfiguration.imports
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1420 +/- ##
=========================================
Coverage 82.94% 82.94%
Complexity 2975 2975
=========================================
Files 340 340
Lines 9833 9833
Branches 1178 1178
=========================================
Hits 8156 8156
Misses 1163 1163
Partials 514 514 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR adds a regression test in the sofa-boot module to enforce the project’s migration away from legacy META-INF/spring.factories EnableAutoConfiguration registration and toward META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports.
Changes:
- Add
AutoConfigurationMigrationTeststo validate every module with*AutoConfigurationclasses provides anAutoConfiguration.importsfile. - Validate each
AutoConfiguration.importsfile matches the discovered*AutoConfigurationclasses. - Validate main-module
spring.factoriesfiles do not registerorg.springframework.boot.autoconfigure.EnableAutoConfiguration.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Set<Path> autoConfigurationModules = findMainSourceDirectories(PROJECT_ROOT).stream() | ||
| .map(this::toModuleDirectory) | ||
| .filter(this::containsAutoConfigurationSource) | ||
| .collect(Collectors.toCollection(TreeSet::new)); |
There was a problem hiding this comment.
modulesWithAutoConfigurationsShouldProvideImportsFile() maps src/main/java directories to the module dir and then calls containsAutoConfigurationSource(moduleDir), which walks the whole module (including src/test/resources). This can produce false positives (e.g., a test-only *AutoConfiguration.java) and does extra IO. Consider scanning only the src/main/java directory (e.g., filter before toModuleDirectory, or have containsAutoConfigurationSource take/resolve the main source directory).
| Set<Path> autoConfigurationModules = findMainSourceDirectories(PROJECT_ROOT).stream() | |
| .map(this::toModuleDirectory) | |
| .filter(this::containsAutoConfigurationSource) | |
| .collect(Collectors.toCollection(TreeSet::new)); | |
| Set<Path> autoConfigurationModules = new TreeSet<>(); | |
| for (Path mainSourceDirectory : findMainSourceDirectories(PROJECT_ROOT)) { | |
| if (!findAutoConfigurationClasses(mainSourceDirectory).isEmpty()) { | |
| autoConfigurationModules.add(toModuleDirectory(mainSourceDirectory)); | |
| } | |
| } |
| private List<Path> findFiles(Path root, String suffix) throws IOException { | ||
| try (Stream<Path> files = Files.walk(root)) { | ||
| return files.filter(Files::isRegularFile) | ||
| .map(Path::toAbsolutePath) | ||
| .map(Path::normalize) | ||
| .filter(path -> path.toString().endsWith(suffix)) | ||
| .sorted() | ||
| .collect(Collectors.toList()); | ||
| } | ||
| } | ||
|
|
||
| private List<Path> findMainSourceDirectories(Path root) throws IOException { | ||
| try (Stream<Path> files = Files.walk(root)) { | ||
| return files.filter(Files::isDirectory) | ||
| .map(Path::toAbsolutePath) | ||
| .map(Path::normalize) | ||
| .filter(path -> path.toString().endsWith("src/main/java")) |
There was a problem hiding this comment.
findFiles(...) uses path.toString().endsWith(suffix) where suffix contains /. This will not match on Windows (which uses \), causing the test to miss files and fail. Use Path-aware matching (e.g., path.endsWith(Path.of(suffix)) or compare path segments) instead of string suffix matching.
| private List<Path> findFiles(Path root, String suffix) throws IOException { | |
| try (Stream<Path> files = Files.walk(root)) { | |
| return files.filter(Files::isRegularFile) | |
| .map(Path::toAbsolutePath) | |
| .map(Path::normalize) | |
| .filter(path -> path.toString().endsWith(suffix)) | |
| .sorted() | |
| .collect(Collectors.toList()); | |
| } | |
| } | |
| private List<Path> findMainSourceDirectories(Path root) throws IOException { | |
| try (Stream<Path> files = Files.walk(root)) { | |
| return files.filter(Files::isDirectory) | |
| .map(Path::toAbsolutePath) | |
| .map(Path::normalize) | |
| .filter(path -> path.toString().endsWith("src/main/java")) | |
| private Path toRelativePath(String suffix) { | |
| return Path.of("", suffix.split("/")); | |
| } | |
| private List<Path> findFiles(Path root, String suffix) throws IOException { | |
| Path suffixPath = toRelativePath(suffix); | |
| try (Stream<Path> files = Files.walk(root)) { | |
| return files.filter(Files::isRegularFile) | |
| .map(Path::toAbsolutePath) | |
| .map(Path::normalize) | |
| .filter(path -> path.endsWith(suffixPath)) | |
| .sorted() | |
| .collect(Collectors.toList()); | |
| } | |
| } | |
| private List<Path> findMainSourceDirectories(Path root) throws IOException { | |
| Path mainSourceDirectory = toRelativePath("src/main/java"); | |
| try (Stream<Path> files = Files.walk(root)) { | |
| return files.filter(Files::isDirectory) | |
| .map(Path::toAbsolutePath) | |
| .map(Path::normalize) | |
| .filter(path -> path.endsWith(mainSourceDirectory)) |
| return files.filter(Files::isDirectory) | ||
| .map(Path::toAbsolutePath) | ||
| .map(Path::normalize) | ||
| .filter(path -> path.toString().endsWith("src/main/java")) |
There was a problem hiding this comment.
findMainSourceDirectories(...) relies on path.toString().endsWith("src/main/java"), which is also path-separator dependent and will fail on Windows. Prefer path.endsWith(Path.of("src","main","java")) (or similar segment-based checks) so the test is platform-independent.
| .filter(path -> path.toString().endsWith("src/main/java")) | |
| .filter(path -> path.endsWith(Path.of("src", "main", "java"))) |
|
@pmupkin Please fix the comment from AI. |
Summary
This PR(Related issue #1401) reinforces the migration from legacy spring.factories auto-configuration registration to META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports.
The current codebase has already moved the actual auto-configuration registrations into .imports files for the relevant modules. This change adds regression coverage to make sure we do not accidentally reintroduce EnableAutoConfiguration entries in spring.factories in the future.
Changes