From cb36aa67d856113cb4e22fc3539734762e9141f4 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Thu, 4 Mar 2021 10:27:55 -0800 Subject: [PATCH] Add functionality to build with global properties (#59) --- .../BuildTests.cs | 32 ++- .../ProjectCreator.Build.cs | 222 ++++++++++++++++-- version.json | 3 +- 3 files changed, 238 insertions(+), 19 deletions(-) diff --git a/src/MSBuildProjectCreator.UnitTests/BuildTests.cs b/src/MSBuildProjectCreator.UnitTests/BuildTests.cs index 46d2249..f0183a3 100644 --- a/src/MSBuildProjectCreator.UnitTests/BuildTests.cs +++ b/src/MSBuildProjectCreator.UnitTests/BuildTests.cs @@ -62,15 +62,39 @@ public void BuildTargetOutputsTest() item.Value.Items.Select(i => i.ItemSpec).ShouldBe(new[] { "E32099C7AF4E481885B624E5600C718A", "7F38E64414104C6182F492B535926187" }); } + [Fact] + public void BuildWithGlobalProperties() + { + Dictionary globalProperties = new Dictionary + { + ["Property1"] = "D7BBABDFB2D142D3A75E0C1A33E33780", + }; + + ProjectCreator + .Create(Path.Combine(TestRootPath, "project1.proj")) + .Target("Build") + .TaskMessage("Value = $(Property1)", MessageImportance.High) + .TryBuild("Build", out bool resultWithoutGlobalProperties, out BuildOutput buildOutputWithoutGlobalProperties) + .TryBuild("Build", globalProperties, out bool resultWithGlobalProperties, out BuildOutput buildOutputWithGlobalProperties); + + resultWithoutGlobalProperties.ShouldBeTrue(); + + buildOutputWithoutGlobalProperties.MessageEvents.High.ShouldHaveSingleItem(buildOutputWithoutGlobalProperties.GetConsoleLog()).Message.ShouldBe("Value = ", buildOutputWithoutGlobalProperties.GetConsoleLog()); + + resultWithGlobalProperties.ShouldBeTrue(); + + buildOutputWithGlobalProperties.MessageEvents.High.ShouldHaveSingleItem(buildOutputWithGlobalProperties.GetConsoleLog()).Message.ShouldBe("Value = D7BBABDFB2D142D3A75E0C1A33E33780", buildOutputWithGlobalProperties.GetConsoleLog()); + } + [Fact] public void CanRestoreAndBuild() { ProjectCreator.Create( path: GetTempFileName(".csproj")) .Target("Restore") - .TaskMessage("Restoring...", Framework.MessageImportance.High) + .TaskMessage("Restoring...", MessageImportance.High) .Target("Build") - .TaskMessage("Building...", Framework.MessageImportance.High) + .TaskMessage("Building...", MessageImportance.High) .Save() .TryBuild(restore: true, "Build", out bool result, out BuildOutput buildOutput); @@ -174,13 +198,13 @@ public void RestoreTargetCanBeRun() ProjectCreator .Create(Path.Combine(TestRootPath, "project1.proj")) .Target("Restore") - .TaskMessage("312D2E6ABDDC4735B437A016CED1A68E", Framework.MessageImportance.High, condition: "'$(MSBuildRestoreSessionId)' != ''") + .TaskMessage("312D2E6ABDDC4735B437A016CED1A68E", MessageImportance.High, condition: "'$(MSBuildRestoreSessionId)' != ''") .TaskError("MSBuildRestoreSessionId was not defined", condition: "'$(MSBuildRestoreSessionId)' == ''") .TryRestore(out bool result, out BuildOutput buildOutput); result.ShouldBeTrue(buildOutput.GetConsoleLog()); - buildOutput.MessageEvents.High.ShouldContain(i => i.Message == "312D2E6ABDDC4735B437A016CED1A68E" && i.Importance == Framework.MessageImportance.High, buildOutput.GetConsoleLog()); + buildOutput.MessageEvents.High.ShouldContain(i => i.Message == "312D2E6ABDDC4735B437A016CED1A68E" && i.Importance == MessageImportance.High, buildOutput.GetConsoleLog()); } } } \ No newline at end of file diff --git a/src/MSBuildProjectCreator/ProjectCreator.Build.cs b/src/MSBuildProjectCreator/ProjectCreator.Build.cs index 26b1253..52dc546 100644 --- a/src/MSBuildProjectCreator/ProjectCreator.Build.cs +++ b/src/MSBuildProjectCreator/ProjectCreator.Build.cs @@ -2,6 +2,7 @@ // // Licensed under the MIT license. +using Microsoft.Build.Evaluation; using Microsoft.Build.Execution; using System; using System.Collections.Generic; @@ -19,7 +20,19 @@ public partial class ProjectCreator /// The current . public ProjectCreator TryBuild(string target, out bool result) { - return TryBuild(restore: false, target, out result); + return TryBuild(target, null, out result); + } + + /// + /// Attempts to build the current project. + /// + /// The name of the target to build. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// The current . + public ProjectCreator TryBuild(string target, Dictionary globalProperties, out bool result) + { + return TryBuild(restore: false, target, globalProperties, out result); } /// @@ -30,6 +43,19 @@ public ProjectCreator TryBuild(string target, out bool result) /// A value indicating the result of the build. /// The current . public ProjectCreator TryBuild(bool restore, string target, out bool result) + { + return TryBuild(restore, target, null, out result); + } + + /// + /// Attempts to build the current project. + /// + /// A value indicating whether or not the project should be restored before building. + /// The name of the target to build. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// The current . + public ProjectCreator TryBuild(bool restore, string target, Dictionary globalProperties, out bool result) { if (restore) { @@ -41,7 +67,7 @@ public ProjectCreator TryBuild(bool restore, string target, out bool result) } } - Build(target.ToArrayWithSingleElement(), out result, out _, out _); + Build(target.ToArrayWithSingleElement(), globalProperties, out result, out _, out _); return this; } @@ -55,7 +81,20 @@ public ProjectCreator TryBuild(bool restore, string target, out bool result) /// The current . public ProjectCreator TryBuild(string target, out bool result, out BuildOutput buildOutput) { - return TryBuild(restore: false, target, out result, out buildOutput); + return TryBuild(target, null, out result, out buildOutput); + } + + /// + /// Attempts to build the current project. + /// + /// The name of the target to build. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// A object that captured the logging from the build. + /// The current . + public ProjectCreator TryBuild(string target, Dictionary globalProperties, out bool result, out BuildOutput buildOutput) + { + return TryBuild(restore: false, target, globalProperties, out result, out buildOutput); } /// @@ -67,10 +106,24 @@ public ProjectCreator TryBuild(string target, out bool result, out BuildOutput b /// A object that captured the logging from the build. /// The current . public ProjectCreator TryBuild(bool restore, string target, out bool result, out BuildOutput buildOutput) + { + return TryBuild(restore, target, null, out result, out buildOutput); + } + + /// + /// Attempts to build the current project. + /// + /// A value indicating whether or not the project should be restored before building. + /// The name of the target to build. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// A object that captured the logging from the build. + /// The current . + public ProjectCreator TryBuild(bool restore, string target, Dictionary globalProperties, out bool result, out BuildOutput buildOutput) { buildOutput = BuildOutput.Create(); - Build(restore, target.ToArrayWithSingleElement(), buildOutput, out result, out _); + Build(restore, target.ToArrayWithSingleElement(), globalProperties, buildOutput, out result, out _); return this; } @@ -82,7 +135,18 @@ public ProjectCreator TryBuild(bool restore, string target, out bool result, out /// The current . public ProjectCreator TryBuild(out bool result) { - return TryBuild(restore: false, out result); + return TryBuild(globalProperties: null, out result); + } + + /// + /// Attempts to build the current project. + /// + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// The current . + public ProjectCreator TryBuild(Dictionary globalProperties, out bool result) + { + return TryBuild(restore: false, globalProperties: globalProperties, out result); } /// @@ -92,6 +156,18 @@ public ProjectCreator TryBuild(out bool result) /// A value indicating the result of the build. /// The current . public ProjectCreator TryBuild(bool restore, out bool result) + { + return TryBuild(restore, globalProperties: null, out result); + } + + /// + /// Attempts to build the current project. + /// + /// A value indicating whether or not the project should be restored before building. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// The current . + public ProjectCreator TryBuild(bool restore, Dictionary globalProperties, out bool result) { if (restore) { @@ -103,7 +179,7 @@ public ProjectCreator TryBuild(bool restore, out bool result) } } - Build(null, out result, out _, out _); + Build(null, globalProperties: globalProperties, out result, out _, out _); return this; } @@ -127,10 +203,23 @@ public ProjectCreator TryBuild(out bool result, out BuildOutput buildOutput) /// A object that captured the logging from the build. /// The current . public ProjectCreator TryBuild(bool restore, out bool result, out BuildOutput buildOutput) + { + return TryBuild(restore, globalProperties: null, out result, out buildOutput); + } + + /// + /// Attempts to build the current project. + /// + /// A value indicating whether or not the project should be restored before building. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// A object that captured the logging from the build. + /// The current . + public ProjectCreator TryBuild(bool restore, Dictionary globalProperties, out bool result, out BuildOutput buildOutput) { buildOutput = BuildOutput.Create(); - Build(restore, null, buildOutput, out result, out _); + Build(restore, null, globalProperties, buildOutput, out result, out _); return this; } @@ -144,6 +233,20 @@ public ProjectCreator TryBuild(bool restore, out bool result, out BuildOutput bu /// A containing the target outputs. /// The current . public ProjectCreator TryBuild(string target, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) + { + return TryBuild(target, null, out result, out buildOutput, out targetOutputs); + } + + /// + /// Attempts to build the current project. + /// + /// The name of the target to build. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// A object that captured the logging from the build. + /// A containing the target outputs. + /// The current . + public ProjectCreator TryBuild(string target, Dictionary globalProperties, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) { return TryBuild(restore: false, target, out result, out buildOutput, out targetOutputs); } @@ -158,6 +261,21 @@ public ProjectCreator TryBuild(string target, out bool result, out BuildOutput b /// A containing the target outputs. /// The current . public ProjectCreator TryBuild(bool restore, string target, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) + { + return TryBuild(restore, target, null, out result, out buildOutput, out targetOutputs); + } + + /// + /// Attempts to build the current project. + /// + /// A value indicating whether or not the project should be restored before building. + /// The name of the target to build. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// A object that captured the logging from the build. + /// A containing the target outputs. + /// The current . + public ProjectCreator TryBuild(bool restore, string target, Dictionary globalProperties, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) { return TryBuild(restore, new[] { target }, out result, out buildOutput, out targetOutputs); } @@ -171,6 +289,20 @@ public ProjectCreator TryBuild(bool restore, string target, out bool result, out /// A containing the target outputs. /// The current . public ProjectCreator TryBuild(string[] targets, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) + { + return TryBuild(targets, null, out result, out buildOutput, out targetOutputs); + } + + /// + /// Attempts to build the current project. + /// + /// The names of the targets to build. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// A object that captured the logging from the build. + /// A containing the target outputs. + /// The current . + public ProjectCreator TryBuild(string[] targets, Dictionary globalProperties, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) { return TryBuild(restore: false, targets, out result, out buildOutput, out targetOutputs); } @@ -185,10 +317,25 @@ public ProjectCreator TryBuild(string[] targets, out bool result, out BuildOutpu /// A containing the target outputs. /// The current . public ProjectCreator TryBuild(bool restore, string[] targets, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) + { + return TryBuild(restore, targets, null, out result, out buildOutput, out targetOutputs); + } + + /// + /// Attempts to build the current project. + /// + /// A value indicating whether or not the project should be restored before building. + /// The names of the targets to build. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// A object that captured the logging from the build. + /// A containing the target outputs. + /// The current . + public ProjectCreator TryBuild(bool restore, string[] targets, Dictionary globalProperties, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) { buildOutput = BuildOutput.Create(); - Build(restore, targets, buildOutput, out result, out targetOutputs); + Build(restore, targets, globalProperties, buildOutput, out result, out targetOutputs); return this; } @@ -203,7 +350,21 @@ public ProjectCreator TryBuild(bool restore, string[] targets, out bool result, /// The current . public ProjectCreator TryBuild(IEnumerable targets, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) { - return TryBuild(restore: false, targets, out result, out buildOutput, out targetOutputs); + return TryBuild(targets, null, out result, out buildOutput, out targetOutputs); + } + + /// + /// Attempts to build the current project. + /// + /// The names of the targets to build. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// A object that captured the logging from the build. + /// A containing the target outputs. + /// The current . + public ProjectCreator TryBuild(IEnumerable targets, Dictionary globalProperties, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) + { + return TryBuild(restore: false, targets, globalProperties, out result, out buildOutput, out targetOutputs); } /// @@ -216,6 +377,21 @@ public ProjectCreator TryBuild(IEnumerable targets, out bool result, out /// A containing the target outputs. /// The current . public ProjectCreator TryBuild(bool restore, IEnumerable targets, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) + { + return TryBuild(restore, targets, null, out result, out buildOutput, out targetOutputs); + } + + /// + /// Attempts to build the current project. + /// + /// A value indicating whether or not the project should be restored before building. + /// The names of the targets to build. + /// Global properties to use when building the target. + /// A value indicating the result of the build. + /// A object that captured the logging from the build. + /// A containing the target outputs. + /// The current . + public ProjectCreator TryBuild(bool restore, IEnumerable targets, Dictionary globalProperties, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) { return TryBuild(restore, targets.ToArray(), out result, out buildOutput, out targetOutputs); } @@ -274,14 +450,14 @@ public ProjectCreator TryRestore(out bool result, out BuildOutput buildOutput, o return this; } - private void Build(string[] targets, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) + private void Build(string[] targets, Dictionary globalProperties, out bool result, out BuildOutput buildOutput, out IDictionary targetOutputs) { buildOutput = BuildOutput.Create(); - Build(restore: false, targets, buildOutput, out result, out targetOutputs); + Build(restore: false, targets, globalProperties, buildOutput, out result, out targetOutputs); } - private void Build(bool restore, string[] targets, BuildOutput buildOutput, out bool result, out IDictionary targetOutputs) + private void Build(bool restore, string[] targets, Dictionary globalProperties, BuildOutput buildOutput, out bool result, out IDictionary targetOutputs) { targetOutputs = null; @@ -292,6 +468,11 @@ private void Build(bool restore, string[] targets, BuildOutput buildOutput, out Loggers = new List(ProjectCollection.Loggers.Concat(buildOutput.AsEnumerable())), }; + if (globalProperties != null) + { + buildParameters.GlobalProperties = globalProperties; + } + BuildManager.DefaultBuildManager.BeginBuild(buildParameters); try { @@ -305,9 +486,22 @@ private void Build(bool restore, string[] targets, BuildOutput buildOutput, out } } + ProjectInstance projectInstance; + + if (globalProperties != null) + { + TryGetProject(out Project project, globalProperties); + + projectInstance = project.CreateProjectInstance(); + } + else + { + projectInstance = ProjectInstance; + } + BuildRequestData buildRequestData = new BuildRequestData( - ProjectInstance, - targetsToBuild: targets ?? ProjectInstance.DefaultTargets.ToArray(), + projectInstance, + targetsToBuild: targets ?? projectInstance.DefaultTargets.ToArray(), hostServices: null, flags: BuildRequestDataFlags.ReplaceExistingProjectInstance); diff --git a/version.json b/version.json index 6ad652f..3ca326d 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,7 @@ { - "version": "2.0", + "version": "2.1", "assemblyVersion": "1.0", + "buildNumberOffset": -1, "nugetPackageVersion": { "semVer": 1 },