KirillOsenkov / MSBuildStructuredLog

A logger for MSBuild that records a structured representation of executed targets, tasks, property and item values.
MIT License
1.41k stars 188 forks source link

Broken dependency 'chain' when a target in the middle of the chain fails the build #641

Open baronfel opened 1 year ago

baronfel commented 1 year ago

I was just diagnosing a build where there was a long chain of targets. One of the 'internal' targets errors out, stopping the build. Here is a simplified diagram

A
| _ B
    | _ C -> Errors out, stopping the build
        | _ D
            | _ E -> Actual target requested by the build

In the log viewer, I can easily see the results of targets A, B, and C, including a nice link between C and B (and B and A) that shows the dependency relationships. However, the final result of my investigation was that D should not have been called at all, but the log viewer didn't (or wasn't able) to show be why C was triggered (and so on, why D was triggered), because the error at C stopped the rest of the build processing.

Does this information exist today? If so, how should/could it be displayed?

KirillOsenkov commented 1 year ago

Repro:

<Project>

  <Target Name="A">
  </Target>

  <Target Name="B" DependsOnTargets="A">
  </Target>

  <Target Name="C" DependsOnTargets="B">
    <Error Text="BOOM" />
  </Target>

  <Target Name="D" DependsOnTargets="C">
  </Target>

  <Target Name="E" DependsOnTargets="D">
  </Target>

  <Target Name="Build" DependsOnTargets="E">
  </Target>

</Project>
KirillOsenkov commented 1 year ago

We get 30 events during this build:

image

Unfortunately it looks like MSBuild doesn't send us enough information about the "stack" of targets being built.

I'd move this to dotnet/msbuild and we can design how we can send more information on TargetStartedEventArgs (other than the ParentTarget)

KirillOsenkov commented 1 year ago

See also: https://github.com/dotnet/msbuild/issues/4936

One way I see to solve this is when a target fails the build, we could emit a TargetSkippedEventArgs for each target currently on the stack and drain the stack. This would allow us to reconstruct the entire chain of missing links.

See related: https://github.com/dotnet/msbuild/issues/6528

KirillOsenkov commented 1 year ago

This is roughly the area of interest: https://github.com/dotnet/msbuild/blob/9c33693c492a0cb99474dcb703bfd0947056d8a9/src/Build/BackEnd/Components/RequestBuilder/TargetBuilder.cs#L479

See this comment too: https://github.com/dotnet/msbuild/issues/4936#issuecomment-556120766