diff --git a/src/Build.UnitTests/BinaryLogger_Tests.cs b/src/Build.UnitTests/BinaryLogger_Tests.cs index 97fe6342c62..98fada5f84f 100644 --- a/src/Build.UnitTests/BinaryLogger_Tests.cs +++ b/src/Build.UnitTests/BinaryLogger_Tests.cs @@ -680,6 +680,37 @@ public void BinlogFileNameWildcardGeneration() File.Create(_logFile).Dispose(); } + [Fact] + public void BinaryLogReplayEventSource_ShouldAllowForwardCompatibility() + { + // This test verifies that BinaryLogReplayEventSource can be configured + // to allow forward compatibility with newer binlog versions + // The fact that this compiles and doesn't throw verifies the feature works + var replayEventSource = new BinaryLogReplayEventSource + { + AllowForwardCompatibility = true + }; + + // If we got here without exception, the property setter works + replayEventSource.ShouldNotBeNull(); + + // Create the required binlog file for test cleanup + File.Create(_logFile).Dispose(); + } + + [Fact] + public void BinaryLogger_FileFormatVersion_ShouldBePublic() + { + // This test verifies that the FileFormatVersion constant is publicly accessible + // This is needed for version comparison in command-line tools + int version = BinaryLogger.FileFormatVersion; + version.ShouldBeGreaterThan(0); + version.ShouldBe(25); // Current version as of this test + + // Create the required binlog file for test cleanup + File.Create(_logFile).Dispose(); + } + public void Dispose() { _env.Dispose(); diff --git a/src/Build/Logging/BinaryLogger/BinaryLogger.cs b/src/Build/Logging/BinaryLogger/BinaryLogger.cs index 5cbc5c4f5e8..b0250d68cff 100644 --- a/src/Build/Logging/BinaryLogger/BinaryLogger.cs +++ b/src/Build/Logging/BinaryLogger/BinaryLogger.cs @@ -90,9 +90,10 @@ public sealed class BinaryLogger : ILogger // The minimum version of the binary log reader that can read log of above version. internal const int ForwardCompatibilityMinimalVersion = 18; - // The current version of the binary log representation. - // Changes with each update of the binary log format. - internal const int FileFormatVersion = 25; + /// + /// The current version of the binary log file format that this version of MSBuild supports. + /// + public const int FileFormatVersion = 25; // The minimum version of the binary log reader that can read log of above version. // This should be changed only when the binary log format is changed in a way that would prevent it from being diff --git a/src/MSBuild/XMake.cs b/src/MSBuild/XMake.cs index f38ae7ac2af..842a2a0cf49 100644 --- a/src/MSBuild/XMake.cs +++ b/src/MSBuild/XMake.cs @@ -3889,7 +3889,17 @@ private static void ReplayBinaryLog( bool isBuildCheckEnabled) { - var replayEventSource = new BinaryLogReplayEventSource(); + var replayEventSource = new BinaryLogReplayEventSource() + { + AllowForwardCompatibility = true + }; + + // Subscribe to RecoverableReadError to handle forward compatibility issues + replayEventSource.RecoverableReadError += e => + { + // Output recoverable errors as warnings to the console + Console.WriteLine(e.GetFormattedMessage()); + }; var eventSource = isBuildCheckEnabled ? BuildCheckReplayModeConnector.GetMergedEventSource(BuildManager.DefaultBuildManager, replayEventSource) : @@ -3922,7 +3932,16 @@ private static void ReplayBinaryLog( try { - replayEventSource.Replay(binaryLogFilePath, s_buildCancellationSource.Token); + // Use the BinaryReader overload to ensure AllowForwardCompatibility is respected + using var binaryReader = BinaryLogReplayEventSource.OpenReader(binaryLogFilePath); + replayEventSource.Replay(binaryReader, s_buildCancellationSource.Token); + + // Emit a warning if the log file version is newer than what we support + if (replayEventSource.FileFormatVersion > BinaryLogger.FileFormatVersion) + { + var warningMessage = $"The log file format version is {replayEventSource.FileFormatVersion} with minimum required reader version {replayEventSource.MinimumReaderVersion}, whereas this version of MSBuild only supports versions up to {BinaryLogger.FileFormatVersion}."; + Console.WriteLine(warningMessage); + } } catch (Exception ex) {