Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e1d7911
Create BinLogDetector
ericstj Mar 6, 2026
cfd3e1c
Implement dev dependency overrides
ericstj Mar 6, 2026
f34c615
Merge branch 'main' of https://github.com/microsoft/component-detecti…
ericstj Mar 10, 2026
630cd3e
Add more tests, add selfcontained detection
ericstj Mar 10, 2026
d530ef1
Fix environment variable detection
ericstj Mar 10, 2026
fb29c49
Refactor dotnet/nuget/binlog detectors to share as much as possible
ericstj Mar 11, 2026
9218aeb
Fix testing of mocks against internal interfaces
ericstj Mar 11, 2026
ad75ea8
Fix a couple failing tests
ericstj Mar 11, 2026
a2fa655
Address feedback
ericstj Mar 11, 2026
33b0533
Reduce state to just assets to project info map
ericstj Mar 11, 2026
f5e632b
Rebase binlog paths
ericstj Mar 11, 2026
edaa6c0
Add tests for PathRebasingUtility
ericstj Mar 12, 2026
e84c773
Don't run Integration tests in local build
ericstj Mar 13, 2026
53992f9
Try to fix linux tests
ericstj Mar 16, 2026
1599ba5
Merge branch 'main' of https://github.com/microsoft/component-detecti…
ericstj Mar 16, 2026
2cc78bf
Add some test diagnostics
ericstj Mar 17, 2026
434b5e1
More logging
ericstj Mar 17, 2026
007c760
More logging
ericstj Mar 17, 2026
4563877
Save log file
ericstj Mar 17, 2026
d9373da
Add exception handling to binlog reading
ericstj Mar 17, 2026
86ec06f
Workaround binlogger issue with older binlogs
ericstj Mar 18, 2026
e90456b
Address feedback
ericstj Mar 18, 2026
3bc2067
Address feedback
ericstj Mar 18, 2026
d7d7664
Address feedback
ericstj Mar 19, 2026
4bb52e2
Support cancellation of binlog processing
ericstj Mar 20, 2026
5958e0d
Make default off and document
ericstj Mar 20, 2026
09e27d5
Don't catch OperationCanceledException
ericstj Mar 26, 2026
7e82a33
Update docs, refine tests
ericstj Mar 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ jobs:
- name: Run tests
# The '--' separator forwards options to the Microsoft Testing Platform runner.
# After upgrading to .NET 10 SDK, these can be passed directly without '--'.
run: dotnet test --no-build --configuration Debug -- --coverage --coverage-output-format cobertura
# Override the default Integration-test exclusion from test/Directory.Build.props.
run: dotnet test --no-build --configuration Debug -p:TestingPlatformCommandLineArguments="--coverage --coverage-output-format cobertura"

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
Expand Down
18 changes: 16 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,20 @@ Analysis rulesets are defined in [analyzers.ruleset](analyzers.ruleset) and vali

### Testing

L0s are defined in `Microsoft.ComponentDetection.*.Tests`.
**Unit tests (L0s)** are defined in `Microsoft.ComponentDetection.*.Tests` and should be fast, isolated, and free of external process calls.

Verification tests are run on the sample projects defined in [microsoft/componentdetection-verification](https://github.com/microsoft/componentdetection-verification).
**Integration tests** spawn real processes (e.g. `dotnet build`, `dotnet restore`) and are therefore slower and environment-dependent. Tag these with `[TestCategory("Integration")]` so they can be filtered during local development.

By default, `dotnet test` **excludes** Integration tests (configured in `test/Directory.Build.props`). CI runs all tests including Integration (see `.github/workflows/build.yml`).

To run only Integration tests locally:
```bash
dotnet test -- --filter "TestCategory=Integration"
```

To run everything (same as CI):
```bash
dotnet test -p:TestingPlatformCommandLineArguments=""
```

**Verification tests** are run on the sample projects defined in [microsoft/componentdetection-verification](https://github.com/microsoft/componentdetection-verification).
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.1" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="MSBuild.StructuredLogger" Version="2.3.113" />
<PackageVersion Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15" />
<PackageVersion Include="DotNet.Glob" Version="2.1.1" />
<PackageVersion Include="MinVer" Version="7.0.0" />
Expand Down
11 changes: 6 additions & 5 deletions docs/detectors/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@

- [NuGet](nuget.md)

| Detector | Status |
| ------------------------------------------------ | ------ |
| NuGetComponentDetector | Stable |
| NuGetPackagesConfigDetector | Stable |
| NuGetProjectModelProjectCentricComponentDetector | Stable |
| Detector | Status |
| ------------------------------------------------ | ---------- |
| NuGetComponentDetector | Stable |
| NuGetPackagesConfigDetector | Stable |
| NuGetProjectModelProjectCentricComponentDetector | Stable |
| MSBuildBinaryLogComponentDetector | DefaultOff |

- [Pip](pip.md)

Expand Down
43 changes: 43 additions & 0 deletions docs/detectors/nuget.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,49 @@ The `NuGetPackagesConfig` detector raises NuGet components referenced by project

[7]: https://learn.microsoft.com/en-us/nuget/reference/packages-config

## MSBuildBinaryLog

The `MSBuildBinaryLog` detector is a **DefaultOff** detector intended to eventually replace both the `NuGetProjectCentric` and `DotNet` detectors. It combines MSBuild binary log (binlog) information with `project.assets.json` to provide enhanced component detection with project-level classifications.

It looks for `project.assets.json` files and separately discovers `*.binlog` files. The binlog provides build-time context that isn't available from `project.assets.json` alone.

### MSBuild Properties

The detector extracts the following MSBuild properties from binlog data:

| Property | Usage |
| --- | --- |
| `NETCoreSdkVersion` | Registered as the SDK version for the DotNet component. More accurate than `dotnet --version`, which can differ due to `global.json` rollforward. |
| `OutputType` | Classifies projects as "application" (`Exe`, `WinExe`, `AppContainerExe`) or "library" (`Library`, `Module`). The `DotNet` detector uses PE header inspection, which requires compiled output. |
| `ProjectAssetsFile` | Maps binlog project info to the corresponding `project.assets.json` on disk. |
| `TargetFramework` / `TargetFrameworks` | Identifies inner builds for multi-targeted projects and determines per-TFM properties. |
| `IsTestProject` | When `true`, all dependencies of the project are marked as development dependencies. |
| `IsShipping` | When `false`, all dependencies are marked as development dependencies. |
| `IsDevelopment` | When `true`, all dependencies are marked as development dependencies. |
| `IsPackable` | Indicates whether the project produces a NuGet package. |
| `SelfContained` | Detects self-contained deployment. Combined with lock file heuristics. |
| `PublishAot` | When `true`, project is treated as self-contained. Typically only set during publish pass. |

### PackageReference and PackageDownload Metadata

The detector reads `IsDevelopmentDependency` metadata from `PackageReference` and `PackageDownload` items in the binlog:

- **PackageReference**: When `IsDevelopmentDependency` is `true`, the package and **all of its transitive dependencies** are marked as development dependencies. This allows annotating a single top-level dependency to classify its entire closure as dev-only. If a transitive dependency should remain non-dev, reference it directly (or transitively via a non-overridden dependency) so that it is also registered through a non-dev path.
- **PackageReference**: When `IsDevelopmentDependency` is `false`, the package and all of its transitive dependencies are classified using the explicit override rather than the default heuristics.
- **PackageDownload**: Packages are registered as development dependencies by default unless explicitly overridden via `IsDevelopmentDependency` metadata.

### Multi-Targeting and Multi-Pass Merging

For multi-targeted projects, the detector understands the MSBuild outer/inner build structure. Properties from inner builds (per-TFM) are tracked separately, and when a project appears in multiple binlogs (e.g., a build pass and a publish pass), their properties are merged so that values like `PublishAot` (typically only set during publish) are available when processing the shared `project.assets.json`.

### Fallback Mode

When no binlog is available for a project, the detector falls back to standard NuGet detection behavior (equivalent to the `NuGetProjectCentric` detector).

### Enabling the Detector

Pass `--DetectorArgs MSBuildBinaryLog=EnableIfDefaultOff` and ensure a `*.binlog` file is present in the scan directory (e.g., by building with `dotnet build -bl`).

## Known Limitations

- Any components that are only found in `*.nuspec` or `*.nupkg` files will not be detected with the latest NuGet Detector approach, because the NuGet detector that scans `*.nuspec` or `*.nupkg` files overreports. This is due to of NuGet's [restore behaviour][8] which downloads all possible dependencies before [resolving the final dependency graph][9].
Expand Down
2 changes: 1 addition & 1 deletion docs/feature-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
| NPM | <ul><li>package.json</li><li>package-lock.json</li><li>npm-shrinkwrap.json</li><li>lerna.json</li></ul> | - | ✔ (dev-dependencies in package.json, dev flag in package-lock.json) | ✔ |
| Yarn (v1, v2) | <ul><li>package.json</li><li>yarn.lock</li></ul> | - | ✔ (dev-dependencies in package.json) | ✔ |
| Pnpm | <ul><li>shrinkwrap.yaml</li><li>pnpm-lock.yaml</li></ul> | - | ✔ (packages/{package}/dev flag) | ✔ |
| NuGet | <ul><li>project.assets.json</li><li>*.nupkg</li><li>*.nuspec</li><li>packages.config</li><li>nuget.config</li></ul> | - | - | ✔ (required project.assets.json) |
| NuGet | <ul><li>project.assets.json</li><li>*.nupkg</li><li>*.nuspec</li><li>packages.config</li><li>nuget.config</li><li>*.binlog (DefaultOff)</li></ul> | - | - | ✔ (required project.assets.json) |
| Pip (Python) | <ul><li>setup.py</li><li>requirements.txt</li><li>*setup=distutils.core.run_setup({setup.py}); setup.install_requires*</li><li>dist package METADATA file</li></ul> | <ul><li>Python 2 or Python 3</li><li>Internet connection</li></ul> | ❌ | ✔ |
| Poetry (Python) | <ul><li>poetry.lock</li><ul> | - | ✔ | ❌ |
| Ruby | <ul><li>gemfile.lock</li></ul> | - | ❌ | ✔ |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
<InternalsVisibleTo Include="Microsoft.ComponentDetection.Orchestrator.Tests" />
<InternalsVisibleTo Include="Microsoft.ComponentDetection.Detectors.Tests" />
<InternalsVisibleTo Include="Microsoft.ComponentDetection.TestsUtilities" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" Key="0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="DotNet.Glob" />
<PackageReference Include="MSBuild.StructuredLogger" />
<PackageReference Include="Microsoft.Extensions.Logging" />
<PackageReference Include="morelinq" />
<PackageReference Include="NuGet.ProjectModel" />
Expand Down
Loading
Loading