Skip to content

Conversation

@zhenghao104
Copy link

No description provided.

Copilot AI review requested due to automatic review settings December 23, 2025 23:16
@codecov
Copy link

codecov bot commented Dec 23, 2025

Codecov Report

❌ Patch coverage is 59.81013% with 127 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.8%. Comparing base (601ebcd) to head (bc21f08).

Files with missing lines Patch % Lines
...ponentDetection.Detectors/sbt/SbtCommandService.cs 8.2% 122 Missing ⚠️
...entDetection.Detectors/sbt/SbtComponentDetector.cs 95.5% 3 Missing and 2 partials ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

Copilot AI left a 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
Copy link

Copilot AI Dec 23, 2025

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.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +31 to +37
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
Copy link

Copilot AI Dec 23, 2025

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.

Copilot uses AI. Check for mistakes.
Comment on lines +49 to +56
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");
}
}
Copy link

Copilot AI Dec 23, 2025

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.

Copilot uses AI. Check for mistakes.
Comment on lines 187 to 210
### 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)
Copy link

Copilot AI Dec 23, 2025

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.

Copilot uses AI. Check for mistakes.
.WithFile(fileName, string.Empty)
.WithFile("bcde.sbtdeps", content, ["bcde.sbtdeps"]);
}
}
Copy link

Copilot AI Dec 23, 2025

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.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link

👋 Hi! It looks like you modified some files in the Detectors folder.
You may need to bump the detector versions if any of the following scenarios apply:

  • The detector detects more or fewer components than before
  • The detector generates different parent/child graph relationships than before
  • The detector generates different devDependencies values than before

If none of the above scenarios apply, feel free to ignore this comment 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants