aboutsummaryrefslogtreecommitdiff
path: root/src/internal/WixInternal.MSTestSupport/MsbuildUtilities.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/WixInternal.MSTestSupport/MsbuildUtilities.cs')
-rw-r--r--src/internal/WixInternal.MSTestSupport/MsbuildUtilities.cs99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/internal/WixInternal.MSTestSupport/MsbuildUtilities.cs b/src/internal/WixInternal.MSTestSupport/MsbuildUtilities.cs
new file mode 100644
index 00000000..4776e6f1
--- /dev/null
+++ b/src/internal/WixInternal.MSTestSupport/MsbuildUtilities.cs
@@ -0,0 +1,99 @@
1// Copyright(c) .NET Foundation and contributors.All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixInternal.MSTestSupport
4{
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9
10 public enum BuildSystem
11 {
12 DotNetCoreSdk,
13 MSBuild,
14 MSBuild64,
15 }
16
17 public static class MsbuildUtilities
18 {
19 public static MsbuildRunnerResult BuildProject(BuildSystem buildSystem, string projectPath, string[] arguments = null, string configuration = "Release", string verbosityLevel = "normal", bool suppressValidation = true)
20 {
21 var allArgs = new List<string>
22 {
23 $"-verbosity:{verbosityLevel}",
24 $"-p:Configuration={configuration}",
25 $"-p:SuppressValidation={suppressValidation}",
26 // Node reuse means that child msbuild processes can stay around after the build completes.
27 // Under that scenario, the root msbuild does not reliably close its streams which causes us to hang.
28 "-nr:false",
29 MsbuildUtilities.GetQuotedSwitch(buildSystem, "bl", Path.ChangeExtension(projectPath, ".binlog"))
30 };
31
32 if (arguments != null)
33 {
34 allArgs.AddRange(arguments);
35 }
36
37 switch (buildSystem)
38 {
39 case BuildSystem.DotNetCoreSdk:
40 {
41 allArgs.Add(projectPath);
42 var result = DotnetRunner.Execute("msbuild", allArgs.ToArray());
43 return new MsbuildRunnerResult
44 {
45 ExitCode = result.ExitCode,
46 Output = result.StandardOutput,
47 };
48 }
49 case BuildSystem.MSBuild:
50 case BuildSystem.MSBuild64:
51 {
52 return MsbuildRunner.Execute(projectPath, allArgs.ToArray(), buildSystem == BuildSystem.MSBuild64);
53 }
54 default:
55 {
56 throw new NotImplementedException();
57 }
58 }
59 }
60
61 public static string GetQuotedSwitch(BuildSystem _, string switchName, string switchValue)
62 {
63 // If the value ends with a backslash, escape it.
64 if (switchValue?.EndsWith("\\") == true)
65 {
66 switchValue += @"\";
67 }
68
69 return $"-{switchName}:\"{switchValue}\"";
70 }
71
72 public static string GetQuotedPropertySwitch(BuildSystem buildSystem, string propertyName, string propertyValue)
73 {
74 // If the value ends with a backslash, escape it.
75 if (propertyValue?.EndsWith("\\") == true)
76 {
77 propertyValue += @"\";
78 }
79
80 var quotedValue = "\"" + propertyValue + "\"";
81
82 // If the value contains a semicolon then escape-quote it (wrap with the characters: \") to wrap the value
83 // instead of just quoting the value, otherwise dotnet.exe will not pass the value to MSBuild correctly.
84 if (buildSystem == BuildSystem.DotNetCoreSdk && propertyValue?.IndexOf(';') > -1)
85 {
86 quotedValue = "\\\"" + propertyValue + "\\\"";
87 }
88
89 return $"-p:{propertyName}={quotedValue}";
90 }
91
92 public static IEnumerable<string> GetToolCommandLines(MsbuildRunnerResult result, string toolName, string operation, BuildSystem buildSystem)
93 {
94 var expectedToolExe = buildSystem == BuildSystem.DotNetCoreSdk ? $"{toolName}.dll\"" : $"{toolName}.exe";
95 var expectedToolCommand = $"{expectedToolExe} {operation}";
96 return result.Output.Where(line => line.Contains(expectedToolCommand));
97 }
98 }
99}