Load .wixlib intermediates with single creator
Using a single creator ensures definitions are shared and consistent across the entire build.
Rob Mensching committed
Jan 1, 2019 at 00:26 UTC
41622a07f82c57cf3d80393b0b6914f5ccb76e33
10 files changed
+259
-21
src/WixToolset.Core/CommandLine/BuildCommand.cs
+12
-19
@@ -331,27 +331,20 @@ namespace WixToolset.Core.CommandLine
331
332
private IEnumerable<Intermediate> LoadLibraries(IEnumerable<string> libraryFiles, ITupleDefinitionCreator creator)
333
{
334
- var libraries = new List<Intermediate>();
335
-
336
- foreach (var libraryFile in libraryFiles)
334
+ try
335
{
338
- try
339
- {
340
- var library = Intermediate.Load(libraryFile, creator);
341
-
342
- libraries.Add(library);
343
- }
344
- catch (WixCorruptFileException e)
345
- {
346
- this.Messaging.Write(e.Error);
347
- }
348
- catch (WixUnexpectedFileFormatException e)
349
- {
350
- this.Messaging.Write(e.Error);
351
- }
336
+ return Intermediate.Load(libraryFiles, creator);
337
+ }
338
+ catch (WixCorruptFileException e)
339
+ {
340
+ this.Messaging.Write(e.Error);
341
+ }
342
+ catch (WixUnexpectedFileFormatException e)
343
+ {
344
+ this.Messaging.Write(e.Error);
345
}
346
354
- return libraries;
347
+ return Array.Empty<Intermediate>();
348
}
349
350
private IEnumerable<Localization> LoadLocalizationFiles(IEnumerable<string> locFiles, IDictionary<string, string> preprocessorVariables)
@@ -437,7 +430,7 @@ namespace WixToolset.Core.CommandLine
430
public string OutputsFile { get; private set; }
431
432
public string BuiltOutputsFile { get; private set; }
440
-
433
+
434
public CommandLine(IMessaging messaging)
435
{
436
this.Messaging = messaging;
src/WixToolset.Core/ExtensibilityServices/TupleDefinitionCreator.cs
+5
-2
@@ -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 WixToolset.Core.ExtensibilityServices
4
{
@@ -23,7 +23,10 @@ namespace WixToolset.Core.ExtensibilityServices
23
24
public void AddCustomTupleDefinition(IntermediateTupleDefinition definition)
25
{
26
- this.CustomDefinitionByName.Add(definition.Name, definition);
26
+ if (!this.CustomDefinitionByName.TryGetValue(definition.Name, out var existing) || definition.Revision > existing.Revision)
27
+ {
28
+ this.CustomDefinitionByName[definition.Name] = definition;
29
+ }
30
}
31
32
public bool TryGetTupleDefinitionByName(string name, out IntermediateTupleDefinition tupleDefinition)
src/test/WixToolsetTest.CoreIntegration/TestData/ComplexExampleExtension/OtherComponents.wxs
new
+12
@@ -0,0 +1,12 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3
+ xmlns:ex="http://www.example.com/scheams/v1/wxs">
4
+ <Fragment>
5
+ <ComponentGroup Id="OtherComponents" Directory="INSTALLFOLDER">
6
+ <Component>
7
+ <File Source="other.txt" />
8
+ <ex:Example Id="Other" Value="Value" />
9
+ </Component>
10
+ </ComponentGroup>
11
+ </Fragment>
12
+</Wix>
src/test/WixToolsetTest.CoreIntegration/TestData/ComplexExampleExtension/Package.en-us.wxl
new
+11
@@ -0,0 +1,11 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+
3
+<!--
4
+This file contains the declaration of all the localizable strings.
5
+-->
6
+<WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US">
7
+
8
+ <String Id="DowngradeError">A newer version of [ProductName] is already installed.</String>
9
+ <String Id="FeatureTitle">MsiPackage</String>
10
+
11
+</WixLocalization>
src/test/WixToolsetTest.CoreIntegration/TestData/ComplexExampleExtension/Package.wxs
new
+26
@@ -0,0 +1,26 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3
+ <Product Id="*" Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
4
+ <Package InstallerVersion="200" Compressed="no" InstallScope="perMachine" />
5
+
6
+ <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
7
+ <MediaTemplate />
8
+
9
+ <Property Id="ExampleProperty" Value="$(ex.Test)" />
10
+
11
+ <PropertyRef Id="PropertyFromExampleWir" />
12
+
13
+ <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)">
14
+ <ComponentGroupRef Id="ProductComponents" />
15
+ <ComponentGroupRef Id="OtherComponents" />
16
+ </Feature>
17
+ </Product>
18
+
19
+ <Fragment>
20
+ <Directory Id="TARGETDIR" Name="SourceDir">
21
+ <Directory Id="ProgramFilesFolder">
22
+ <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
23
+ </Directory>
24
+ </Directory>
25
+ </Fragment>
26
+</Wix>
src/test/WixToolsetTest.CoreIntegration/TestData/ComplexExampleExtension/PackageComponents.wxs
new
+12
@@ -0,0 +1,12 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3
+ xmlns:ex="http://www.example.com/scheams/v1/wxs">
4
+ <Fragment>
5
+ <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
6
+ <Component>
7
+ <File Source="example.txt" />
8
+ <ex:Example Id="Foo" Value="Bar" />
9
+ </Component>
10
+ </ComponentGroup>
11
+ </Fragment>
12
+</Wix>
src/test/WixToolsetTest.CoreIntegration/TestData/ComplexExampleExtension/data/example.txt
new
+1
@@ -0,0 +1 @@
1
+This is example.txt.
\ No newline at end of file
src/test/WixToolsetTest.CoreIntegration/TestData/ComplexExampleExtension/data/other.txt
new
+1
@@ -0,0 +1 @@
1
+This is other.txt.
\ No newline at end of file
src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
+6
@@ -38,6 +38,12 @@
38
<Content Include="TestData\BadIf\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
39
<Content Include="TestData\BadIf\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
40
<Content Include="TestData\BadIf\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
41
+ <Content Include="TestData\ComplexExampleExtension\data\example.txt" CopyToOutputDirectory="PreserveNewest" />
42
+ <Content Include="TestData\ComplexExampleExtension\data\other.txt" CopyToOutputDirectory="PreserveNewest" />
43
+ <Content Include="TestData\ComplexExampleExtension\OtherComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
44
+ <Content Include="TestData\ComplexExampleExtension\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
45
+ <Content Include="TestData\ComplexExampleExtension\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
46
+ <Content Include="TestData\ComplexExampleExtension\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
47
<Content Include="TestData\SingleFile\data\test.txt" CopyToOutputDirectory="PreserveNewest" />
48
<Content Include="TestData\SingleFile\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
49
<Content Include="TestData\SingleFile\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
src/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs
new
+173
@@ -0,0 +1,173 @@
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 WixToolsetTest.CoreIntegration
4
+{
5
+ using System;
6
+ using System.IO;
7
+ using System.Linq;
8
+ using Example.Extension;
9
+ using WixBuildTools.TestSupport;
10
+ using WixToolset.Core.TestPackage;
11
+ using WixToolset.Data;
12
+ using WixToolset.Data.Tuples;
13
+ using Xunit;
14
+
15
+ public class WixlibFixture
16
+ {
17
+ [Fact]
18
+ public void CanBuildSingleFileUsingWixlib()
19
+ {
20
+ var folder = TestData.Get(@"TestData\SingleFile");
21
+
22
+ using (var fs = new DisposableFileSystem())
23
+ {
24
+ var baseFolder = fs.GetFolder();
25
+ var intermediateFolder = Path.Combine(baseFolder, "obj");
26
+
27
+ var result = WixRunner.Execute(new[]
28
+ {
29
+ "build",
30
+ Path.Combine(folder, "PackageComponents.wxs"),
31
+ "-intermediateFolder", intermediateFolder,
32
+ "-o", Path.Combine(intermediateFolder, @"test.wixlib")
33
+ });
34
+
35
+ result.AssertSuccess();
36
+
37
+ result = WixRunner.Execute(new[]
38
+ {
39
+ "build",
40
+ Path.Combine(folder, "Package.wxs"),
41
+ "-loc", Path.Combine(folder, "Package.en-us.wxl"),
42
+ "-lib", Path.Combine(intermediateFolder, @"test.wixlib"),
43
+ "-bindpath", Path.Combine(folder, "data"),
44
+ "-intermediateFolder", intermediateFolder,
45
+ "-o", Path.Combine(baseFolder, @"bin\test.msi")
46
+ });
47
+
48
+ result.AssertSuccess();
49
+
50
+ var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"obj\test.wir"));
51
+ var section = intermediate.Sections.Single();
52
+
53
+ var wixFile = section.Tuples.OfType<WixFileTuple>().Single();
54
+ Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path);
55
+ Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path);
56
+ }
57
+ }
58
+
59
+ [Fact]
60
+ public void CanBuildWithExtensionUsingWixlib()
61
+ {
62
+ var folder = TestData.Get(@"TestData\ExampleExtension");
63
+ var extensionPath = Path.GetFullPath(new Uri(typeof(ExampleExtensionFactory).Assembly.CodeBase).LocalPath);
64
+
65
+ using (var fs = new DisposableFileSystem())
66
+ {
67
+ var baseFolder = fs.GetFolder();
68
+ var intermediateFolder = Path.Combine(baseFolder, "obj");
69
+
70
+ var result = WixRunner.Execute(new[]
71
+ {
72
+ "build",
73
+ Path.Combine(folder, "PackageComponents.wxs"),
74
+ "-ext", extensionPath,
75
+ "-intermediateFolder", intermediateFolder,
76
+ "-o", Path.Combine(intermediateFolder, @"test.wixlib")
77
+ });
78
+
79
+ result.AssertSuccess();
80
+
81
+ result = WixRunner.Execute(new[]
82
+ {
83
+ "build",
84
+ Path.Combine(folder, "Package.wxs"),
85
+ "-loc", Path.Combine(folder, "Package.en-us.wxl"),
86
+ "-lib", Path.Combine(intermediateFolder, @"test.wixlib"),
87
+ "-ext", extensionPath,
88
+ "-bindpath", Path.Combine(folder, "data"),
89
+ "-intermediateFolder", intermediateFolder,
90
+ "-o", Path.Combine(intermediateFolder, @"bin\test.msi")
91
+ });
92
+
93
+ result.AssertSuccess();
94
+
95
+ var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir"));
96
+ var section = intermediate.Sections.Single();
97
+
98
+ var wixFile = section.Tuples.OfType<WixFileTuple>().Single();
99
+ Assert.Equal(Path.Combine(folder, @"data\example.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path);
100
+ Assert.Equal(@"example.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path);
101
+
102
+ var example = section.Tuples.Where(t => t.Definition.Type == TupleDefinitionType.MustBeFromAnExtension).Single();
103
+ Assert.Equal("Foo", example.Id.Id);
104
+ Assert.Equal("Foo", example[0].AsString());
105
+ Assert.Equal("Bar", example[1].AsString());
106
+ }
107
+ }
108
+
109
+ [Fact]
110
+ public void CanBuildWithExtensionUsingMultipleWixlibs()
111
+ {
112
+ var folder = TestData.Get(@"TestData\ComplexExampleExtension");
113
+ var extensionPath = Path.GetFullPath(new Uri(typeof(ExampleExtensionFactory).Assembly.CodeBase).LocalPath);
114
+
115
+ using (var fs = new DisposableFileSystem())
116
+ {
117
+ var baseFolder = fs.GetFolder();
118
+ var intermediateFolder = Path.Combine(baseFolder, "obj");
119
+
120
+ var result = WixRunner.Execute(new[]
121
+ {
122
+ "build",
123
+ Path.Combine(folder, "PackageComponents.wxs"),
124
+ "-ext", extensionPath,
125
+ "-intermediateFolder", intermediateFolder,
126
+ "-o", Path.Combine(intermediateFolder, @"components.wixlib")
127
+ });
128
+
129
+ result.AssertSuccess();
130
+
131
+ result = WixRunner.Execute(new[]
132
+ {
133
+ "build",
134
+ Path.Combine(folder, "OtherComponents.wxs"),
135
+ "-ext", extensionPath,
136
+ "-intermediateFolder", intermediateFolder,
137
+ "-o", Path.Combine(intermediateFolder, @"other.wixlib")
138
+ });
139
+
140
+ result.AssertSuccess();
141
+
142
+ result = WixRunner.Execute(new[]
143
+ {
144
+ "build",
145
+ Path.Combine(folder, "Package.wxs"),
146
+ "-loc", Path.Combine(folder, "Package.en-us.wxl"),
147
+ "-lib", Path.Combine(intermediateFolder, @"components.wixlib"),
148
+ "-lib", Path.Combine(intermediateFolder, @"other.wixlib"),
149
+ "-ext", extensionPath,
150
+ "-bindpath", Path.Combine(folder, "data"),
151
+ "-intermediateFolder", intermediateFolder,
152
+ "-o", Path.Combine(intermediateFolder, @"bin\test.msi")
153
+ });
154
+
155
+ result.AssertSuccess();
156
+
157
+ var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir"));
158
+ var section = intermediate.Sections.Single();
159
+
160
+ var wixFiles = section.Tuples.OfType<WixFileTuple>().OrderBy(t => Path.GetFileName(t.Source.Path)).ToArray();
161
+ Assert.Equal(Path.Combine(folder, @"data\example.txt"), wixFiles[0][WixFileTupleFields.Source].AsPath().Path);
162
+ Assert.Equal(@"example.txt", wixFiles[0][WixFileTupleFields.Source].PreviousValue.AsPath().Path);
163
+ Assert.Equal(Path.Combine(folder, @"data\other.txt"), wixFiles[1][WixFileTupleFields.Source].AsPath().Path);
164
+ Assert.Equal(@"other.txt", wixFiles[1][WixFileTupleFields.Source].PreviousValue.AsPath().Path);
165
+
166
+ var examples = section.Tuples.Where(t => t.Definition.Type == TupleDefinitionType.MustBeFromAnExtension).ToArray();
167
+ Assert.Equal(new[] { "Foo", "Other" }, examples.Select(t => t.Id.Id).ToArray());
168
+ Assert.Equal(new[] { "Foo", "Other" }, examples.Select(t => t.AsString(0)).ToArray());
169
+ Assert.Equal(new[] { "Bar", "Value" }, examples.Select(t => t[1].AsString()).ToArray());
170
+ }
171
+ }
172
+ }
173
+}