@joebigelow / wix / commits / 4d96895a

Process Unreal custom tables in CreateBootstrapperApplicationManifestCommand

Sean Hall committed May 16, 2020 at 16:38 UTC 4d96895a19c79ced1543d44e181527824c82c8e8
4 files changed +113
src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
+47
@@ -16,6 +16,8 @@ namespace WixToolset.Core.Burn.Bundles
16
17 internal class CreateBootstrapperApplicationManifestCommand
18 {
19 + private static readonly char[] ColonCharacter = new[] { ':' };
20 +
21 public CreateBootstrapperApplicationManifestCommand(IntermediateSection section, WixBundleTuple bundleTuple, IEnumerable<PackageFacade> chainPackages, int lastUXPayloadIndex, Dictionary<string, WixBundlePayloadTuple> payloadTuples, string intermediateFolder)
22 {
23 this.Section = section;
@@ -277,6 +279,51 @@ namespace WixToolset.Core.Burn.Bundles
279 writer.WriteEndElement();
280 }
281 }
282 +
283 + var dataTablesById = this.Section.Tuples.OfType<WixCustomTableTuple>()
284 + .Where(t => t.Unreal && t.Id != null)
285 + .ToDictionary(t => t.Id.Id);
286 + var dataRowsByTable = this.Section.Tuples.OfType<WixCustomRowTuple>()
287 + .GroupBy(t => t.Table);
288 + foreach (var tableDataRows in dataRowsByTable)
289 + {
290 + var tableName = tableDataRows.Key;
291 + if (!dataTablesById.TryGetValue(tableName, out var tableTuple))
292 + {
293 + // This should have been a linker error.
294 + continue;
295 + }
296 +
297 + var columnNames = tableTuple.ColumnNames.Split('\t');
298 +
299 + // We simply assert that the table (and field) name is valid, because
300 + // this is up to the extension developer to get right. An author will
301 + // only affect the attribute value, and that will get properly escaped.
302 +#if DEBUG
303 + Debug.Assert(Common.IsIdentifier(tableName));
304 + foreach (var columnName in columnNames)
305 + {
306 + Debug.Assert(Common.IsIdentifier(columnName));
307 + }
308 +#endif // DEBUG
309 +
310 + foreach (var rowTuple in tableDataRows)
311 + {
312 + writer.WriteStartElement(tableName);
313 +
314 + //var rowFields = rowTuple.FieldDataSeparated;
315 + foreach (var field in rowTuple.FieldDataSeparated)
316 + {
317 + var splitField = field.Split(ColonCharacter, 2);
318 + if (splitField.Length == 2)
319 + {
320 + writer.WriteAttributeString(splitField[0], splitField[1]);
321 + }
322 + }
323 +
324 + writer.WriteEndElement();
325 + }
326 + }
327 }
328
329 private WixBundlePayloadTuple CreateBootstrapperApplicationManifestPayloadRow(string baManifestPath)
src/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
+39
@@ -12,6 +12,45 @@ namespace WixToolsetTest.CoreIntegration
12
13 public class BundleManifestFixture
14 {
15 + [Fact]
16 + public void PopulatesBAManifestWithUnrealCustomTable()
17 + {
18 + var folder = TestData.Get(@"TestData");
19 +
20 + using (var fs = new DisposableFileSystem())
21 + {
22 + var baseFolder = fs.GetFolder();
23 + var intermediateFolder = Path.Combine(baseFolder, "obj");
24 + var bundlePath = Path.Combine(baseFolder, @"bin\test.exe");
25 + var baFolderPath = Path.Combine(baseFolder, "ba");
26 + var extractFolderPath = Path.Combine(baseFolder, "extract");
27 +
28 + var result = WixRunner.Execute(new[]
29 + {
30 + "build",
31 + Path.Combine(folder, "BundleCustomTable", "BundleCustomTable.wxs"),
32 + Path.Combine(folder, "BundleWithPackageGroupRef", "MinimalPackageGroup.wxs"),
33 + Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
34 + "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
35 + "-intermediateFolder", intermediateFolder,
36 + "-o", bundlePath
37 + });
38 +
39 + result.AssertSuccess();
40 +
41 + Assert.True(File.Exists(bundlePath));
42 +
43 + var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath);
44 + extractResult.AssertSuccess();
45 +
46 + var customElements = extractResult.SelectBADataNodes("/ba:BootstrapperApplicationData/ba:BundleCustomTable");
47 + Assert.Equal(3, customElements.Count);
48 + Assert.Equal("<BundleCustomTable Id='one' Column2='two' />", customElements[0].GetTestXml());
49 + Assert.Equal("<BundleCustomTable Column2='&lt;' Id='&gt;' />", customElements[1].GetTestXml());
50 + Assert.Equal("<BundleCustomTable Id='1' Column2='2' />", customElements[2].GetTestXml());
51 + }
52 + }
53 +
54 [Fact]
55 public void PopulatesManifestWithBundleExtension()
56 {
src/test/WixToolsetTest.CoreIntegration/TestData/BundleCustomTable/BundleCustomTable.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 + <Fragment>
4 + <PackageGroup Id="BundlePackages">
5 + <PackageGroupRef Id="MinimalPackageGroup" />
6 + </PackageGroup>
7 +
8 + <CustomTable Id="BundleCustomTable" Unreal="yes">
9 + <Column Id="Id" Type="string" PrimaryKey="yes" />
10 + <Column Id="Column2" Type="string" PrimaryKey="yes" />
11 +
12 + <Row>
13 + <Data Column="Id">one</Data>
14 + <Data Column="Column2">two</Data>
15 + </Row>
16 + <Row>
17 + <Data Column="Column2">&lt;</Data>
18 + <Data Column="Id">&gt;</Data>
19 + </Row>
20 + <Row>
21 + <Data Column="Id">1</Data>
22 + <Data Column="Column2">2</Data>
23 + </Row>
24 + </CustomTable>
25 + </Fragment>
26 +</Wix>
src/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
+1
@@ -22,6 +22,7 @@
22 <Content Include="TestData\AppSearch\NestedDirSearchUnderRegSearch.msi" CopyToOutputDirectory="PreserveNewest" />
23 <Content Include="TestData\AppSearch\RegistrySearch.wxs" CopyToOutputDirectory="PreserveNewest" />
24 <Content Include="TestData\BadEnsureTable\BadEnsureTable.wxs" CopyToOutputDirectory="PreserveNewest" />
25 + <Content Include="TestData\BundleCustomTable\BundleCustomTable.wxs" CopyToOutputDirectory="PreserveNewest" />
26 <Content Include="TestData\BundleExtension\BundleExtension.wxs" CopyToOutputDirectory="PreserveNewest" />
27 <Content Include="TestData\BundleExtension\BundleExtensionSearches.wxs" CopyToOutputDirectory="PreserveNewest" />
28 <Content Include="TestData\BundleExtension\BundleWithSearches.wxs" CopyToOutputDirectory="PreserveNewest" />