@joebigelow / wix / commits / 23de0a19

Assign authored payloads to authored containers during linking.

Sean Hall committed Apr 24, 2021 at 15:34 UTC 23de0a19bffe457916b0a45e07044650ace8f456
4 files changed +120 -60
src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
-21
@@ -143,27 +143,6 @@ namespace WixToolset.Core.Burn
143 var payloadSymbols = section.Symbols.OfType<WixBundlePayloadSymbol>().ToDictionary(t => t.Id.Id);
144 var packagesPayloads = RecalculatePackagesPayloads(payloadSymbols, wixGroupSymbols);
145
146 - // Update explicitly authored payloads with their parent container
147 - // to make it easier to gather the payloads later.
148 - foreach (var groupSymbol in wixGroupSymbols)
149 - {
150 - if (ComplexReferenceChildType.Payload == groupSymbol.ChildType)
151 - {
152 - var payloadSymbol = payloadSymbols[groupSymbol.ChildId];
153 -
154 - if (ComplexReferenceParentType.Container == groupSymbol.ParentType)
155 - {
156 - // TODO: v3 didn't warn if we overwrote the payload's container.
157 - // Should we warn now?
158 - payloadSymbol.ContainerRef = groupSymbol.ParentId;
159 - }
160 - else if (ComplexReferenceParentType.Layout == groupSymbol.ParentType)
161 - {
162 - payloadSymbol.LayoutOnly = true;
163 - }
164 - }
165 - }
166 -
146 var layoutDirectory = Path.GetDirectoryName(this.OutputPath);
147
148 // Process the explicitly authored payloads.
src/WixToolset.Core/Link/FlattenAndProcessBundleTablesCommand.cs new
+91
@@ -0,0 +1,91 @@
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.Link
4 +{
5 + using System;
6 + using System.Collections.Generic;
7 + using System.Linq;
8 + using WixToolset.Data;
9 + using WixToolset.Data.Burn;
10 + using WixToolset.Data.Symbols;
11 + using WixToolset.Extensibility.Services;
12 +
13 + internal class FlattenAndProcessBundleTablesCommand
14 + {
15 + public FlattenAndProcessBundleTablesCommand(IntermediateSection entrySection, IMessaging messaging)
16 + {
17 + this.EntrySection = entrySection;
18 + this.Messaging = messaging;
19 + }
20 +
21 + private IntermediateSection EntrySection { get; }
22 +
23 + private IMessaging Messaging { get; }
24 +
25 + public void Execute()
26 + {
27 + this.FlattenBundleTables();
28 +
29 + if (this.Messaging.EncounteredError)
30 + {
31 + return;
32 + }
33 +
34 + this.ProcessBundleComplexReferences();
35 + }
36 +
37 + /// <summary>
38 + /// Flattens the tables used in a Bundle.
39 + /// </summary>
40 + private void FlattenBundleTables()
41 + {
42 + // We need to flatten the nested PayloadGroups and PackageGroups under
43 + // UX, Chain, and any Containers. When we're done, the WixGroups table
44 + // will hold Payloads under UX, ChainPackages (references?) under Chain,
45 + // and ChainPackages/Payloads under the attached and any detatched
46 + // Containers.
47 + var groups = new WixGroupingOrdering(this.EntrySection, this.Messaging);
48 +
49 + // Create UX payloads and Package payloads
50 + groups.UseTypes(new[] { ComplexReferenceParentType.Container, ComplexReferenceParentType.Layout, ComplexReferenceParentType.PackageGroup, ComplexReferenceParentType.PayloadGroup, ComplexReferenceParentType.Package },
51 + new[] { ComplexReferenceChildType.PackageGroup, ComplexReferenceChildType.Package, ComplexReferenceChildType.PackagePayload, ComplexReferenceChildType.PayloadGroup, ComplexReferenceChildType.Payload });
52 + groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Package, false);
53 + groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Container, false);
54 + groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Layout, false);
55 +
56 + // Create Chain packages...
57 + groups.UseTypes(new[] { ComplexReferenceParentType.PackageGroup }, new[] { ComplexReferenceChildType.Package, ComplexReferenceChildType.PackageGroup });
58 + groups.FlattenAndRewriteRows(ComplexReferenceChildType.PackageGroup, "WixChain", false);
59 +
60 + groups.RemoveUsedGroupRows();
61 + }
62 +
63 + private void ProcessBundleComplexReferences()
64 + {
65 + var groups = this.EntrySection.Symbols.OfType<WixGroupSymbol>().ToList();
66 + var payloadsById = this.EntrySection.Symbols.OfType<WixBundlePayloadSymbol>().ToDictionary(c => c.Id.Id);
67 +
68 + // Assign authored payloads to authored containers.
69 + // Compressed Payloads not assigned to a container here will get assigned to the default attached container during binding.
70 + foreach (var groupSymbol in groups)
71 + {
72 + if (ComplexReferenceChildType.Payload == groupSymbol.ChildType)
73 + {
74 + var payloadSymbol = payloadsById[groupSymbol.ChildId];
75 +
76 + if (ComplexReferenceParentType.Container == groupSymbol.ParentType)
77 + {
78 + // TODO: v3 didn't warn if we overwrote the payload's container.
79 + // Should we warn now?
80 + payloadSymbol.ContainerRef = groupSymbol.ParentId;
81 + }
82 + else if (ComplexReferenceParentType.Layout == groupSymbol.ParentType)
83 + {
84 + payloadSymbol.LayoutOnly = true;
85 + }
86 + }
87 + }
88 +
89 + }
90 + }
91 +}
src/WixToolset.Core/Linker.cs
+5 -32
@@ -312,7 +312,11 @@ namespace WixToolset.Core
312 }
313
314 // Bundles have groups of data that must be flattened in a way different from other types.
315 - this.FlattenBundleTables(resolvedSection);
315 + if (resolvedSection.Type == SectionType.Bundle)
316 + {
317 + var command = new FlattenAndProcessBundleTablesCommand(resolvedSection, this.Messaging);
318 + command.Execute();
319 + }
320
321 if (this.Messaging.EncounteredError)
322 {
@@ -853,37 +857,6 @@ namespace WixToolset.Core
857 }
858 */
859
856 - /// <summary>
857 - /// Flattens the tables used in a Bundle.
858 - /// </summary>
859 - /// <param name="entrySection">Output containing the tables to process.</param>
860 - private void FlattenBundleTables(IntermediateSection entrySection)
861 - {
862 - if (SectionType.Bundle != entrySection.Type)
863 - {
864 - return;
865 - }
866 -
867 - // We need to flatten the nested PayloadGroups and PackageGroups under
868 - // UX, Chain, and any Containers. When we're done, the WixGroups table
869 - // will hold Payloads under UX, ChainPackages (references?) under Chain,
870 - // and ChainPackages/Payloads under the attached and any detatched
871 - // Containers.
872 - var groups = new WixGroupingOrdering(entrySection, this.Messaging);
873 -
874 - // Create UX payloads and Package payloads
875 - groups.UseTypes(new[] { ComplexReferenceParentType.Container, ComplexReferenceParentType.Layout, ComplexReferenceParentType.PackageGroup, ComplexReferenceParentType.PayloadGroup, ComplexReferenceParentType.Package }, new[] { ComplexReferenceChildType.PackageGroup, ComplexReferenceChildType.Package, ComplexReferenceChildType.PackagePayload, ComplexReferenceChildType.PayloadGroup, ComplexReferenceChildType.Payload });
876 - groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Package, false);
877 - groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Container, false);
878 - groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Layout, false);
879 -
880 - // Create Chain packages...
881 - groups.UseTypes(new[] { ComplexReferenceParentType.PackageGroup }, new[] { ComplexReferenceChildType.Package, ComplexReferenceChildType.PackageGroup });
882 - groups.FlattenAndRewriteRows(ComplexReferenceChildType.PackageGroup, "WixChain", false);
883 -
884 - groups.RemoveUsedGroupRows();
885 - }
886 -
860 /// <summary>
861 /// Resolves the features connected to other features in the active output.
862 /// </summary>
src/test/WixToolsetTest.CoreIntegration/ContainerFixture.cs
+24 -7
@@ -142,17 +142,34 @@ namespace WixToolsetTest.CoreIntegration
142 var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath);
143 extractResult.AssertSuccess();
144
145 - var payloads = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Chain/burn:MsiPackage/burn:PayloadRef")
145 + var ignoreAttributes = new Dictionary<string, List<string>>
146 + {
147 + { "MsiPackage", new List<string> { "CacheId", "InstallSize", "Size", "ProductCode" } },
148 + { "Provides", new List<string> { "Key" } },
149 + };
150 + var msiPackages = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Chain/burn:MsiPackage")
151 .Cast<XmlElement>()
147 - .Select(e => e.GetTestXml())
152 + .Select(e => e.GetTestXml(ignoreAttributes))
153 .ToArray();
154 WixAssert.CompareLineByLine(new string[]
155 {
151 - "<PayloadRef Id='FirstX86.msi' />",
152 - "<PayloadRef Id='fk1m38Cf9RZ2Bx_ipinRY6BftelU' />",
153 - "<PayloadRef Id='FirstX64.msi' />",
154 - "<PayloadRef Id='fC0n41rZK8oW3JK8LzHu6AT3CjdQ' />",
155 - }, payloads);
156 + "<MsiPackage Id='FirstX86.msi' Cache='keep' CacheId='*' InstallSize='*' Size='*' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' LogPathVariable='WixBundleLog_FirstX86.msi' RollbackLogPathVariable='WixBundleRollbackLog_FirstX86.msi' ProductCode='*' Language='1033' Version='1.0.0.0' UpgradeCode='{12E4699F-E774-4D05-8A01-5BDD41BBA127}'>" +
157 + "<MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />" +
158 + "<Provides Key='*' Version='1.0.0.0' DisplayName='MsiPackage' />" +
159 + "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='no'><Language Id='1033' /></RelatedPackage>" +
160 + "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='no'><Language Id='1033' /></RelatedPackage>" +
161 + "<PayloadRef Id='FirstX86.msi' />" +
162 + "<PayloadRef Id='fk1m38Cf9RZ2Bx_ipinRY6BftelU' />" +
163 + "</MsiPackage>",
164 + "<MsiPackage Id='FirstX64.msi' Cache='keep' CacheId='*' InstallSize='*' Size='*' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_FirstX64.msi' RollbackLogPathVariable='WixBundleRollbackLog_FirstX64.msi' ProductCode='*' Language='1033' Version='1.0.0.0' UpgradeCode='{12E4699F-E774-4D05-8A01-5BDD41BBA127}'>" +
165 + "<MsiProperty Id='ARPSYSTEMCOMPONENT' Value='1' />" +
166 + "<Provides Key='*' Version='1.0.0.0' DisplayName='MsiPackage' />" +
167 + "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MaxVersion='1.0.0.0' MaxInclusive='no' OnlyDetect='no' LangInclusive='no'><Language Id='1033' /></RelatedPackage>" +
168 + "<RelatedPackage Id='{12E4699F-E774-4D05-8A01-5BDD41BBA127}' MinVersion='1.0.0.0' MinInclusive='no' OnlyDetect='yes' LangInclusive='no'><Language Id='1033' /></RelatedPackage>" +
169 + "<PayloadRef Id='FirstX64.msi' />" +
170 + "<PayloadRef Id='fC0n41rZK8oW3JK8LzHu6AT3CjdQ' />" +
171 + "</MsiPackage>",
172 + }, msiPackages);
173 }
174 }
175