From 65950f79747a8c2d7b76e0ade0408024bef04170 Mon Sep 17 00:00:00 2001 From: Stuart Lang Date: Mon, 13 May 2024 22:36:09 +0100 Subject: [PATCH] Fix hang if build does not start (#272) --- src/Buildalyzer/ProjectAnalyzer.cs | 27 ++++++++++++++++++- .../Integration/SimpleProjectsFixture.cs | 17 ++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Buildalyzer/ProjectAnalyzer.cs b/src/Buildalyzer/ProjectAnalyzer.cs index 501c0511..776daaca 100644 --- a/src/Buildalyzer/ProjectAnalyzer.cs +++ b/src/Buildalyzer/ProjectAnalyzer.cs @@ -9,6 +9,7 @@ using Buildalyzer.Logger; using Buildalyzer.Logging; using Microsoft.Build.Construction; +using Microsoft.Build.Framework; using Microsoft.Build.Logging; using Microsoft.Extensions.Logging; using MsBuildPipeLogger; @@ -153,6 +154,14 @@ private IAnalyzerResults BuildTargets( using (CancellationTokenSource cancellation = new CancellationTokenSource()) { using var pipeLogger = new AnonymousPipeLoggerServer(cancellation.Token); + bool receivedAnyEvent = false; + + void OnPipeLoggerOnAnyEventRaised(object o, BuildEventArgs buildEventArgs) + { + receivedAnyEvent = true; + } + + pipeLogger.AnyEventRaised += OnPipeLoggerOnAnyEventRaised; using var eventProcessor = new EventProcessor(Manager, this, BuildLoggers, pipeLogger, results != null); // Run MSBuild @@ -170,8 +179,24 @@ private IAnalyzerResults BuildTargets( GetEffectiveEnvironmentVariables(buildEnvironment), Manager.LoggerFactory)) { + void OnProcessRunnerExited() + { + if (!receivedAnyEvent && processRunner.ExitCode != 0) + { + pipeLogger.Dispose(); + } + } + + processRunner.Exited += OnProcessRunnerExited; processRunner.Start(); - pipeLogger.ReadAll(); + try + { + pipeLogger.ReadAll(); + } + catch (ObjectDisposedException) + { + // Ignore + } processRunner.WaitForExit(); exitCode = processRunner.ExitCode; } diff --git a/tests/Buildalyzer.Tests/Integration/SimpleProjectsFixture.cs b/tests/Buildalyzer.Tests/Integration/SimpleProjectsFixture.cs index 42fae3f0..81cd2cfe 100644 --- a/tests/Buildalyzer.Tests/Integration/SimpleProjectsFixture.cs +++ b/tests/Buildalyzer.Tests/Integration/SimpleProjectsFixture.cs @@ -709,6 +709,23 @@ public void GetsAdditionalFile() .Should().BeEquivalentTo("message.txt"); } + [Test] + public void HandlesProcessFailure() + { + // Given + StringWriter log = new StringWriter(); + IProjectAnalyzer analyzer = GetProjectAnalyzer(@"SdkNet6Exe\SdkNet6Exe.csproj", log); + + // When + IAnalyzerResults results = analyzer.Build(new EnvironmentOptions + { + Arguments = { "/unknown" } // This argument will cause msbuild to immediately fail + }); + + // Then + results.OverallSuccess.ShouldBeFalse(); + } + private static IProjectAnalyzer GetProjectAnalyzer(string projectFile, StringWriter log) { IProjectAnalyzer analyzer = new AnalyzerManager(