Skip to content

fix(manifest): read .NET projects without running their targets - #1694

Merged
Jeppe Fredsgaard Blaabjerg (jfblaa) merged 2 commits into
v1.xfrom
jfblaa/dotnet-evaluation-only
Nov 3, 2026
Merged

Jeppe Fredsgaard Blaabjerg (jfblaa) merged 2 commits into
v1.xfrom
jfblaa/dotnet-evaluation-only

Conversation

@jfblaa

@jfblaa Jeppe Fredsgaard Blaabjerg (jfblaa) commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

LLM Description written by Claude Code:claude-opus-5-5

socket scan create --dynamic-sbom-inference --reach failed on .NET repositories containing a compiler-less project such as a Microsoft.Build.Traversal aggregator (MSB4057: The target "CoreCompile" does not exist). Under --reach, the dotnet facts tool ran a design-time Compile build of every project to collect compiler inputs, which runs the repository's own MSBuild targets and writes generated files into obj/. We don't want to build users' projects at all.

The tool now reads every project by MSBuild evaluation only and runs no targets.

What changes in the facts sidecar:

  • references, analyzers and buildError are gone. Coana reads only targets, sources, classpath and dependencies.
  • sources no longer include target-generated files (AssemblyInfo, GlobalUsings, XAML .g.cs), matching what Coana's non-facts path already analyses.
  • defineConstants no longer include the SDK's implicit framework symbols (NET8_0_OR_GREATER, ...), which only the AddImplicitDefineConstants target adds.
  • A project whose build would fail is no longer reported as a failure.

Testing:

  • dotnet compat smoke tests, including workspaces and exclude-base, pass on SDK 8.0.414, 9.0.315 and 10.0.301. The new evaluation/ fixture is a Traversal-shaped aggregator referencing a project whose InitialTargets canary fails any target run outside restore.
  • On a real repository with a Traversal Build.csproj, --with-files now yields no failures and sources for every project.

🤖 Generated with Claude Code


Note

Medium Risk
Changes how .NET reachability facts are collected and shrinks the sidecar schema Coana consumes, which could affect analysis depth for edge cases but fixes a blocking failure mode for common monorepo layouts.

Overview
Fixes reachability scans failing on repos with compiler-less MSBuild projects (e.g. Microsoft.Build.Traversal aggregators) where running CoreCompile triggered MSB4057.

The dotnet facts tool (Reader.cs) no longer runs design-time Compile (or related) targets. It collects project metadata from MSBuild evaluation only after dotnet restore, so user targets are not executed and nothing is written under obj/ from a scan.

The per-framework facts sidecar drops fields that depended on those builds: references, analyzers, and buildError. sources are evaluation-time Compile items only (no generated AssemblyInfo/GlobalUsings/XAML outputs). defineConstants no longer include SDK implicit symbols like NET8_0_OR_GREATER (those came from AddImplicitDefineConstants). Projects that would fail a real compile are no longer reported as scan failures solely for that reason.

Tests add an evaluation/ Traversal-shaped fixture and retire the old design-time failure case; compat assertions and NuGet failure classification comments are updated accordingly.

Reviewed by Cursor Bugbot for commit 00d157b. Configure here.

The dotnet facts tool ran a design-time Compile build of every project
for --with-files (what --reach uses). That executes the repository's own
MSBuild targets, writes generated files into obj/, and fails outright on
projects without a compiler, such as Microsoft.Build.Traversal
aggregators (MSB4057: CoreCompile does not exist).

Read every project by evaluation alone instead. The sidecar loses
references, analyzers and buildError, which Coana does not read; sources
no longer include target-generated files, and define constants no longer
include the SDK's implicit framework symbols.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A cleanup pass over reuse, simplification and altitude, not a correctness review. The removal itself is clean; these are suggestions, none blocking. The first comment, on classifyNugetFailure, is the one most worth a look.

MSBuild keeps an evaluation error's code out of the exception message, so
evaluation and solution-parse failures reached the resolution report without
it and were grouped as other failures. Prefix the code so they group as
project configuration problems.

Inner builds now come from TargetFrameworks, split as the cross-targeting
targets do, rather than from restore's list, which only mattered while the
tool built projects. Also tidies helpers and tests the evaluation-only change
left with one caller.
@jfblaa
Jeppe Fredsgaard Blaabjerg (jfblaa) merged commit 5390ed4 into v1.x Nov 3, 2026
10 checks passed
@jfblaa
Jeppe Fredsgaard Blaabjerg (jfblaa) deleted the jfblaa/dotnet-evaluation-only branch November 3, 2026 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants