@joebigelow / wix-1 / commits / a7f145fa

Add support for testing with MSBuild

Rob Mensching committed Jul 30, 2018 at 01:49 UTC a7f145fa0669ab988e69e031f346360072306a94
5 files changed +175 -1
src/WixBuildTools.TestSupport/FakeBuildEngine.cs new
+33
@@ -0,0 +1,33 @@
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 +
3 +namespace WixBuildTools.TestSupport
4 +{
5 + using System.Collections;
6 + using System.Text;
7 + using Microsoft.Build.Framework;
8 +
9 + public class FakeBuildEngine : IBuildEngine
10 + {
11 + private readonly StringBuilder output = new StringBuilder();
12 +
13 + public int ColumnNumberOfTaskNode => 0;
14 +
15 + public bool ContinueOnError => false;
16 +
17 + public int LineNumberOfTaskNode => 0;
18 +
19 + public string ProjectFileOfTaskNode => "fake_wix.targets";
20 +
21 + public string Output => this.output.ToString();
22 +
23 + public bool BuildProjectFile(string projectFileName, string[] targetNames, IDictionary globalProperties, IDictionary targetOutputs) => throw new System.NotImplementedException();
24 +
25 + public void LogCustomEvent(CustomBuildEventArgs e) => this.output.AppendLine(e.Message);
26 +
27 + public void LogErrorEvent(BuildErrorEventArgs e) => this.output.AppendLine(e.Message);
28 +
29 + public void LogMessageEvent(BuildMessageEventArgs e) => this.output.AppendLine(e.Message);
30 +
31 + public void LogWarningEvent(BuildWarningEventArgs e) => this.output.AppendLine(e.Message);
32 + }
33 +}
src/WixBuildTools.TestSupport/MsbuildRunner.cs new
+117
@@ -0,0 +1,117 @@
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 +
3 +namespace WixBuildTools.TestSupport
4 +{
5 + using System;
6 + using System.Collections.Generic;
7 + using System.Diagnostics;
8 + using System.IO;
9 + using System.Text;
10 +
11 + public class MsbuildRunner
12 + {
13 + private static readonly string VswhereRelativePath = @"Microsoft Visual Studio\Installer\vswhere.exe";
14 + private static readonly string[] VswhereFindArguments = new[] { "-property", "installationPath", "-latest" };
15 + private static readonly string Msbuild15RelativePath = @"MSBuild\15.0\bin\MSBuild.exe";
16 +
17 + public MsbuildRunner()
18 + {
19 + var vswherePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), VswhereRelativePath);
20 + if (!File.Exists(vswherePath))
21 + {
22 + throw new InvalidOperationException($"Failed to find vswhere at: {vswherePath}");
23 + }
24 +
25 + var result = RunProcessCaptureOutput(vswherePath, VswhereFindArguments);
26 + if (result.ExitCode != 0)
27 + {
28 + throw new InvalidOperationException($"Failed to execute vswhere.exe, exit code: {result.ExitCode}");
29 + }
30 +
31 + this.Msbuild15Path = Path.Combine(result.Output[0], Msbuild15RelativePath);
32 + if (!File.Exists(this.Msbuild15Path))
33 + {
34 + throw new InvalidOperationException($"Failed to find MSBuild v15 at: {this.Msbuild15Path}");
35 + }
36 + }
37 +
38 + private string Msbuild15Path { get; }
39 +
40 + public MsbuildRunnerResult Execute(string projectPath, string[] arguments = null)
41 + {
42 + var total = new List<string>
43 + {
44 + projectPath
45 + };
46 +
47 + if (arguments != null)
48 + {
49 + total.AddRange(arguments);
50 + }
51 +
52 + var workingFolder = Path.GetDirectoryName(projectPath);
53 + return RunProcessCaptureOutput(this.Msbuild15Path, total.ToArray(), workingFolder);
54 + }
55 +
56 + private static MsbuildRunnerResult RunProcessCaptureOutput(string executablePath, string[] arguments = null, string workingFolder = null)
57 + {
58 + var startInfo = new ProcessStartInfo(executablePath)
59 + {
60 + Arguments = CombineArguments(arguments),
61 + CreateNoWindow = true,
62 + RedirectStandardError = true,
63 + RedirectStandardOutput = true,
64 + UseShellExecute = false,
65 + WorkingDirectory = workingFolder,
66 + };
67 +
68 + var exitCode = 0;
69 + var output = new List<string>();
70 +
71 + using (var process = Process.Start(startInfo))
72 + {
73 + process.OutputDataReceived += (s, e) => { if (e.Data != null) output.Add(e.Data); };
74 + process.ErrorDataReceived += (s, e) => { if (e.Data != null) output.Add(e.Data); };
75 +
76 + process.BeginErrorReadLine();
77 + process.BeginOutputReadLine();
78 +
79 + process.WaitForExit();
80 + exitCode = process.ExitCode;
81 + }
82 +
83 + return new MsbuildRunnerResult { ExitCode = exitCode, Output = output.ToArray() };
84 + }
85 +
86 + private static string CombineArguments(string[] arguments)
87 + {
88 + if (arguments == null)
89 + {
90 + return null;
91 + }
92 +
93 + var sb = new StringBuilder();
94 +
95 + foreach (var arg in arguments)
96 + {
97 + if (sb.Length > 0)
98 + {
99 + sb.Append(' ');
100 + }
101 +
102 + if (arg.IndexOf(' ') > -1)
103 + {
104 + sb.Append("\"");
105 + sb.Append(arg);
106 + sb.Append("\"");
107 + }
108 + else
109 + {
110 + sb.Append(arg);
111 + }
112 + }
113 +
114 + return sb.ToString();
115 + }
116 + }
117 +}
src/WixBuildTools.TestSupport/MsbuildRunnerResult.cs new
+19
@@ -0,0 +1,19 @@
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 +
3 +namespace WixBuildTools.TestSupport
4 +{
5 + using System;
6 + using Xunit;
7 +
8 + public class MsbuildRunnerResult
9 + {
10 + public int ExitCode { get; set; }
11 +
12 + public string[] Output { get; set; }
13 +
14 + public void AssertSuccess()
15 + {
16 + Assert.True(0 == this.ExitCode, $"MSBuild failed unexpectedly. Output:\r\n{String.Join("\r\n", this.Output)}");
17 + }
18 + }
19 +}
src/WixBuildTools.TestSupport/TestData.cs
+1 -1
@@ -1,4 +1,4 @@
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.
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
3 namespace WixBuildTools.TestSupport
4 {
src/WixBuildTools.TestSupport/WixBuildTools.TestSupport.csproj
+5
@@ -9,6 +9,7 @@
9 </PropertyGroup>
10
11 <ItemGroup>
12 + <PackageReference Include="Microsoft.Build.Tasks.Core" Version="14.3" />
13 <PackageReference Include="WixToolset.Dtf.WindowsInstaller" Version="4.0.*" NoWarn="NU1701" />
14 </ItemGroup>
15
@@ -16,4 +17,8 @@
17 <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta-63102-01" PrivateAssets="All"/>
18 <PackageReference Include="Nerdbank.GitVersioning" Version="2.1.65" PrivateAssets="all" />
19 </ItemGroup>
20 +
21 + <ItemGroup>
22 + <PackageReference Include="xunit" Version="2.4.0" />
23 + </ItemGroup>
24 </Project>