diff --git a/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildBuilderTests.cs b/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildBuilderTests.cs index 59490fa515..ddbcd81a5a 100644 --- a/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildBuilderTests.cs +++ b/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildBuilderTests.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using Cake.Common.Tests.Fixtures.Tools; using Cake.Common.Tests.Fixtures.Tools.DotNet.MSBuild; using Cake.Common.Tools.DotNet; using Cake.Common.Tools.DotNet.MSBuild; @@ -801,6 +802,20 @@ public void Should_Add_Host_Arguments() // Then Assert.Equal("--diagnostics msbuild", result.Args); } + + [Fact] + public void Should_Use_Node_Reuse_If_Specified() + { + // Given + var fixture = new DotNetMSBuildBuilderFixture(); + fixture.Settings.NodeReuse = true; + + // When + var result = fixture.Run(); + + // Then + Assert.Equal("msbuild /nr:true", result.Args); + } } public class TheConsoleLoggerSettingsProperty diff --git a/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildSettingsExtensionsTests.cs b/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildSettingsExtensionsTests.cs index 6bb2d53b12..655125e255 100644 --- a/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildSettingsExtensionsTests.cs +++ b/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildSettingsExtensionsTests.cs @@ -712,6 +712,37 @@ public void Should_Return_The_Same_Configuration() } } + public sealed class TheNodeReuseMethod + { + [Theory] + [InlineData(true)] + [InlineData(false)] + public void Should_Set_Node_Reuse(bool reuse) + { + // Given + var settings = new DotNetMSBuildSettings(); + + // When + settings.SetNodeReuse(reuse); + + // Then + Assert.Equal(reuse, settings.NodeReuse); + } + + [Fact] + public void Should_Return_The_Same_Configuration() + { + // Given + var settings = new DotNetMSBuildSettings(); + + // When + var result = settings.SetNodeReuse(true); + + // Then + Assert.Equal(settings, result); + } + } + public sealed class TheSetConfigurationMethod { private const string Configuration = "TheConfiguration"; diff --git a/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildSettingsTests.cs b/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildSettingsTests.cs index ce42825bb0..0162cbc19c 100644 --- a/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildSettingsTests.cs +++ b/src/Cake.Common.Tests/Unit/Tools/DotNet/MSBuild/DotNetMSBuildSettingsTests.cs @@ -484,5 +484,18 @@ public void Should_Be_Empty_By_Default() Assert.Empty(settings.DistributedLoggers); } } + + public sealed class TheNodeReuseProperty + { + [Fact] + public void Should_Be_Null_By_Default() + { + // Given + var settings = new DotNetMSBuildSettings(); + + // Then + Assert.Null(settings.NodeReuse); + } + } } } \ No newline at end of file diff --git a/src/Cake.Common/Tools/DotNet/MSBuild/DotNetMSBuildSettings.cs b/src/Cake.Common/Tools/DotNet/MSBuild/DotNetMSBuildSettings.cs index 4bfe90d69b..da992f5a46 100644 --- a/src/Cake.Common/Tools/DotNet/MSBuild/DotNetMSBuildSettings.cs +++ b/src/Cake.Common/Tools/DotNet/MSBuild/DotNetMSBuildSettings.cs @@ -214,6 +214,13 @@ public string PackageReleaseNotes /// public IList WarningCodesAsMessage { get; } + /// + /// Gets or sets a value indicating whether or not node reuse is used. + /// When you’re doing multiple builds in a row, this helps reduce your total build time, + /// by avoiding the start up costs of each MSBuild child node. + /// + public bool? NodeReuse { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/src/Cake.Common/Tools/DotNet/MSBuild/DotNetMSBuildSettingsExtensions.cs b/src/Cake.Common/Tools/DotNet/MSBuild/DotNetMSBuildSettingsExtensions.cs index be47afc62c..1194d0509f 100644 --- a/src/Cake.Common/Tools/DotNet/MSBuild/DotNetMSBuildSettingsExtensions.cs +++ b/src/Cake.Common/Tools/DotNet/MSBuild/DotNetMSBuildSettingsExtensions.cs @@ -439,6 +439,20 @@ public static DotNetMSBuildSettings TreatAllWarningsAs(this DotNetMSBuildSetting return settings; } + /// + /// Sets whether or not node reuse should be enabled. + /// + /// The settings. + /// true if node reuse should be enabled; otherwise false. + /// The same instance so that multiple calls can be chained. + public static DotNetMSBuildSettings SetNodeReuse(this DotNetMSBuildSettings settings, bool reuse) + { + EnsureSettings(settings); + + settings.NodeReuse = reuse; + return settings; + } + /// /// Sets the configuration. /// diff --git a/src/Cake.Common/Tools/DotNet/MSBuild/MSBuildArgumentBuilderExtensions.cs b/src/Cake.Common/Tools/DotNet/MSBuild/MSBuildArgumentBuilderExtensions.cs index 68156d416b..f5b85a11c7 100644 --- a/src/Cake.Common/Tools/DotNet/MSBuild/MSBuildArgumentBuilderExtensions.cs +++ b/src/Cake.Common/Tools/DotNet/MSBuild/MSBuildArgumentBuilderExtensions.cs @@ -203,6 +203,12 @@ public static void AppendMSBuildSettings(this ProcessArgumentBuilder builder, Do msBuilder.AppendMSBuildSwitch("property", $"ContinuousIntegrationBuild={continuousIntegrationBuild}"); } + // Re-use of MSBuild nodes? + if (settings.NodeReuse != null) + { + msBuilder.Append(string.Concat("/nr:", settings.NodeReuse.Value ? "true" : "false")); + } + builder.AppendRange( invokeArgumentCustomization ? settings.ArgumentCustomization?.Invoke(msBuilder) ?? msBuilder