-
Notifications
You must be signed in to change notification settings - Fork 115
Maven scala sbt detector first pass #1601
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1601 +/- ##
=======================================
- Coverage 90.0% 89.8% -0.3%
=======================================
Files 437 440 +3
Lines 37181 37497 +316
Branches 2306 2324 +18
=======================================
+ Hits 33499 33688 +189
- Misses 3210 3335 +125
- Partials 472 474 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces a new SBT (Scala Build Tool) detector to enable Component Detection to scan Scala projects. The detector leverages SBT CLI commands to generate dependency trees and reuses the existing Maven infrastructure since SBT dependencies use Maven-style coordinates.
Key changes:
- Implements SbtComponentDetector following the FileComponentDetector pattern
- Reuses MavenStyleDependencyGraphParserService for parsing dependency output
- Registers detected components as MavenComponent types since Scala libraries use Maven coordinates
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Microsoft.ComponentDetection.Detectors/sbt/SbtComponentDetector.cs | Main detector implementation that discovers build.sbt files, executes SBT CLI commands, and orchestrates dependency detection |
| src/Microsoft.ComponentDetection.Detectors/sbt/SbtCommandService.cs | Service layer that executes SBT CLI commands and parses dependency tree output |
| src/Microsoft.ComponentDetection.Detectors/sbt/ISbtCommandService.cs | Interface for the SBT command service to enable dependency injection and testing |
| src/Microsoft.ComponentDetection.Orchestrator/Extensions/ServiceCollectionExtensions.cs | Registers the SBT detector and service in the DI container |
| test/Microsoft.ComponentDetection.Detectors.Tests/SbtDetectorTests.cs | Unit tests covering CLI availability checks, happy path scenarios, and Scala dependency detection |
| docs/detectors/sbt.md | User-facing documentation explaining requirements, detection strategy, and limitations |
| docs/detectors/sbt-technical-deep-dive.md | Technical documentation detailing implementation architecture and design decisions |
| using Microsoft.ComponentDetection.Contracts.TypedComponent; | ||
| using Microsoft.Extensions.Logging; | ||
|
|
||
| public class SbtComponentDetector : FileComponentDetector |
Copilot
AI
Dec 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The SbtComponentDetector class should implement the IDefaultOffComponentDetector interface. According to the coding guidelines, all new detectors must start as IDefaultOffComponentDetector (default-off) until they are promoted by maintainers. The documentation in sbt-technical-deep-dive.md (line 42) also states that this detector is DefaultOff and implements IDefaultOffComponentDetector, but the actual implementation is missing this interface.
| public override IEnumerable<string> SearchPatterns => new[] { "build.sbt" }; | ||
| ``` | ||
|
|
||
| The detector uses the `FileComponentDetectorWithCleanup` base class, which: | ||
| - Automatically discovers files matching `build.sbt` pattern | ||
| - Provides lifecycle hooks: `OnPrepareDetectionAsync`, `OnFileFoundAsync`, `OnDetectionFinished` | ||
| - Handles file stream management and component recording |
Copilot
AI
Dec 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation states that the detector uses FileComponentDetectorWithCleanup base class, but the actual implementation uses FileComponentDetector. Additionally, the code example at line 31 shows the old array syntax 'new[] { "build.sbt" }', but the actual implementation uses the collection expression syntax '[SbtManifest]'. The documentation should be updated to reflect the actual implementation.
| protected override async Task OnPrepareDetectionAsync(IObservableDirectoryWalkerFactory walkerFactory, ...) | ||
| { | ||
| this.sbtCLIExists = await this.sbtCommandService.SbtCLIExistsAsync(); | ||
| if (!this.sbtCLIExists) | ||
| { | ||
| this.Logger.LogInformation("SBT CLI was not found in the system"); | ||
| } | ||
| } |
Copilot
AI
Dec 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation example shows an incorrect method signature. The actual OnPrepareDetectionAsync method signature accepts 'IObservable processRequests' as the first parameter, not 'IObservableDirectoryWalkerFactory walkerFactory'. Additionally, the example references a non-existent field 'this.sbtCLIExists' that doesn't appear in the actual implementation.
| ### 6. Cleanup (`OnDetectionFinished`) | ||
|
|
||
| ```csharp | ||
| protected override Task OnDetectionFinished() | ||
| { | ||
| foreach (var processRequest in this.processedRequests) | ||
| { | ||
| var dependenciesFilePath = Path.Combine( | ||
| Path.GetDirectoryName(processRequest.ComponentStream.Location), | ||
| this.sbtCommandService.BcdeSbtDependencyFileName); | ||
|
|
||
| if (File.Exists(dependenciesFilePath)) | ||
| { | ||
| this.Logger.LogDebug("Deleting {DependenciesFilePath}", dependenciesFilePath); | ||
| File.Delete(dependenciesFilePath); | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| **Temporary File Management**: | ||
| - Each `build.sbt` generates a `bcde.sbtdeps` file in its directory | ||
| - All temporary files are tracked in `processedRequests` | ||
| - Cleanup occurs after all detectors finish (via `FileComponentDetectorWithCleanup` lifecycle) |
Copilot
AI
Dec 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation describes an OnDetectionFinished method that doesn't exist in the actual SbtComponentDetector implementation. The actual implementation performs file deletion directly in OnFileFoundAsync (line 100 of SbtComponentDetector.cs) rather than tracking processed requests and cleaning them up later. The documentation should be updated to reflect the actual cleanup approach.
| .WithFile(fileName, string.Empty) | ||
| .WithFile("bcde.sbtdeps", content, ["bcde.sbtdeps"]); | ||
| } | ||
| } |
Copilot
AI
Dec 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the coding guidelines, end-to-end verification tests should be added to test/Microsoft.ComponentDetection.VerificationTests/resources/sbt/ with real-world examples that fully exercise the detector. These tests run in CI to prevent regressions. Similar verification test resources exist for other detectors like maven, npm, gradle, etc.
|
👋 Hi! It looks like you modified some files in the
If none of the above scenarios apply, feel free to ignore this comment 🙂 |
No description provided.