dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.21k stars 1.35k forks source link

Static graph should report what project referenced a nonexistent project #9850

Open rainersigwald opened 6 months ago

rainersigwald commented 6 months ago

Consider a project:

<Project Sdk="Microsoft.Build.Traversal/4.1.0">
  <ItemGroup>
    <ProjectReference Include="src\nonexistent.proj" />
  </ItemGroup>
</Project>

When restored with static graph, this produces

❯ msbuild -tl:off -v:m .\dirs.proj /t:restore -bl -p:RestoreUseStaticGraphEvaluation=true
MSBuild version 17.10.0-preview-24157-01+9af8ff2f9 for .NET Framework

  Determining projects to restore...
S:\play\lkeatjlkaseytjkl\src\nonexistent.proj : error MSB4025: The project file could not be loaded. Could not find a p
art of the path 'S:\play\lkeatjlkaseytjkl\src\nonexistent.proj'.  S:\play\lkeatjlkaseytjkl\src\nonexistent.proj [S:\pla
y\lkeatjlkaseytjkl\dirs.proj]
  Nothing to do. None of the projects specified contain packages to restore.

In this example, it's pretty clear what caused that reference. But if you add a layer of indirection (Entrypoint.csproj -> ExistentReference.csproj -> NonexistentReference.csproj) you can get an error message that doesn't have any indication of why the graph is trying to resolve NonexistentReference.csproj:

S:\play\staticgraphrestorenonexistent\NonexistentReference\NonexistentReference.csproj : error MSB4025: The project fil
e could not be loaded. Could not find a part of the path 'S:\play\staticgraphrestorenonexistent\NonexistentReference\No
nexistentReference.csproj'.  S:\play\staticgraphrestorenonexistent\NonexistentReference\NonexistentReference.csproj [S:
\play\staticgraphrestorenonexistent\Entrypoint\Entrypoint.csproj]

If we could include some context in that error ("...referenced by Existent.csproj" or similar) that'd help debug errors like the one experienced by an internal dev who thought he'd eliminated all references to a project but wasn't quite right yet.

JanKrivanek commented 4 months ago

@rainersigwald do you have in mind component in MSBuild where we can facilitate adding the extra information?

There is quite a lot layers to this onion. Restore happens to be done by RestoreTaskEx which is extending StaticGraphRestoreTaskBase which runs the restore by spawning a new process, which then probably calls back to MSBuild (as msbuild error code is displayed), however that likely goes through API, as MSBUILDDEBUGONSTART is ignored - so I'm left with blackbox that covers the actual entry of interest within our code

rainersigwald commented 4 months ago

No, not sure where to keep track of and report this. Part of the adventure! My gut says it'd be in the core static graph evaluation stuff.

You're right that NuGet static graph restore uses the API; it does so here: https://github.com/NuGet/NuGet.Client/blob/b83566ec2369c4e9fd07e6f95d734dfe370a1e66/src/NuGet.Core/NuGet.Build.Tasks.Console/MSBuildStaticGraphRestore.cs#L866-L904