Skip to content

Commit e901829

Browse files
fix: pass project root to ServiceDetector so filesystem walk runs during enrich
EnrichCommand called the 3-arg overload of ServiceDetector.detect(), which set projectRoot=null and skipped the filesystem walk entirely. Multi-module projects (e.g. .NET eShop with 20+ .csproj files) only received the single root-fallback SERVICE node because their build files were never parsed into CodeNodes by any detector. Passing `root` as the 4th argument enables the filesystem scan, so all modules are discovered regardless of whether a detector created a node for their build file. Added ServiceDetectorTest#filesystemWalkFindsModulesNotPresentAsNodes to verify this path with a simulated .NET monorepo (3 .csproj files, no matching CodeNodes). Co-Authored-By: Paperclip <noreply@paperclip.ing>
1 parent d963ab0 commit e901829

2 files changed

Lines changed: 33 additions & 1 deletion

File tree

src/main/java/io/github/randomcodespace/iq/cli/EnrichCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ private int enrichFromCache(AnalysisCache cache, Path root, NumberFormat nf, Ins
145145
CliOutput.step("\uD83C\uDFD7\uFE0F", "Detecting service boundaries...");
146146
var serviceDetector = new io.github.randomcodespace.iq.analyzer.ServiceDetector();
147147
String projectName = root.getFileName().toString();
148-
var serviceResult = serviceDetector.detect(enrichedNodes, enrichedEdges, projectName);
148+
var serviceResult = serviceDetector.detect(enrichedNodes, enrichedEdges, projectName, root);
149149
if (!serviceResult.serviceNodes().isEmpty()) {
150150
// Add service nodes and edges to the builder
151151
builder.addNodes(serviceResult.serviceNodes());

src/test/java/io/github/randomcodespace/iq/analyzer/ServiceDetectorTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,38 @@ void deterministicWithContentExtraction(@TempDir Path tempDir) throws IOExceptio
523523
}
524524
}
525525

526+
@Test
527+
void filesystemWalkFindsModulesNotPresentAsNodes(@TempDir Path tempDir) throws IOException {
528+
// Simulate a .NET monorepo: .csproj files exist on disk but NO detector created CodeNodes for them
529+
Files.createDirectories(tempDir.resolve("src/Basket.API"));
530+
Files.writeString(tempDir.resolve("src/Basket.API/Basket.API.csproj"),
531+
"<Project Sdk=\"Microsoft.NET.Sdk.Web\" />", StandardCharsets.UTF_8);
532+
533+
Files.createDirectories(tempDir.resolve("src/Catalog.API"));
534+
Files.writeString(tempDir.resolve("src/Catalog.API/Catalog.API.csproj"),
535+
"<Project Sdk=\"Microsoft.NET.Sdk.Web\" />", StandardCharsets.UTF_8);
536+
537+
Files.createDirectories(tempDir.resolve("src/Ordering.API"));
538+
Files.writeString(tempDir.resolve("src/Ordering.API/Ordering.API.csproj"),
539+
"<Project Sdk=\"Microsoft.NET.Sdk.Web\" />", StandardCharsets.UTF_8);
540+
541+
// No nodes have build file paths — they are only on the filesystem
542+
List<CodeNode> nodes = new ArrayList<>();
543+
nodes.add(makeNode("cls:BasketCtrl", NodeKind.CLASS, "BasketController",
544+
"src/Basket.API/Controllers/BasketController.cs"));
545+
nodes.add(makeNode("cls:CatalogCtrl", NodeKind.CLASS, "CatalogController",
546+
"src/Catalog.API/Controllers/CatalogController.cs"));
547+
548+
var result = detector.detect(nodes, List.of(), "eShop", tempDir);
549+
550+
// Should detect 3 services via filesystem walk (not from node paths)
551+
assertEquals(3, result.serviceNodes().size());
552+
var names = result.serviceNodes().stream().map(CodeNode::getLabel).sorted().toList();
553+
assertEquals(List.of("Basket.API", "Catalog.API", "Ordering.API"), names);
554+
result.serviceNodes().forEach(svc ->
555+
assertEquals("dotnet", svc.getProperties().get("build_tool")));
556+
}
557+
526558
private static CodeNode makeNode(String id, NodeKind kind, String label, String filePath) {
527559
CodeNode node = new CodeNode(id, kind, label);
528560
node.setFilePath(filePath);

0 commit comments

Comments
 (0)