@joebigelow / wix-1 / commits / b4210b23

Allow DownloadUrl on embedded payloads.

#5253

Sean Hall committed Apr 25, 2021 at 15:36 UTC b4210b23ea28e0acc5a8b7ca5357d7d3926071b4
8 files changed +110 -58
src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+1 -1
@@ -300,7 +300,7 @@ namespace WixToolset.Core.Burn
300
301 if (PackagingType.Embedded == payload.Packaging && String.IsNullOrEmpty(payload.EmbeddedId))
302 {
303 - payload.EmbeddedId = String.Format(CultureInfo.InvariantCulture, BurnCommon.BurnAttachedContainerEmbeddedIdFormat, payloadIndex);
303 + payload.EmbeddedId = String.Format(CultureInfo.InvariantCulture, BurnCommon.BurnAuthoredContainerEmbeddedIdFormat, payloadIndex);
304 ++payloadIndex;
305 }
306 }
src/WixToolset.Core.Burn/Bind/ResolveDownloadUrlsCommand.cs
+9 -8
@@ -5,6 +5,7 @@ namespace WixToolset.Core.Burn.Bind
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Data;
8 + using WixToolset.Data.Burn;
9 using WixToolset.Data.Symbols;
10 using WixToolset.Extensibility;
11 using WixToolset.Extensibility.Services;
@@ -60,7 +61,14 @@ namespace WixToolset.Core.Burn.Bind
61 {
62 foreach (var payload in this.PayloadsById.Values)
63 {
63 - if (payload.Packaging == PackagingType.External)
64 + if (payload.Packaging == PackagingType.Embedded && payload.ContainerRef == BurnConstants.BurnUXContainerName)
65 + {
66 + if (!String.IsNullOrEmpty(payload.DownloadUrl))
67 + {
68 + this.Messaging.Write(WarningMessages.DownloadUrlNotSupportedForBAPayloads(payload.SourceLineNumbers, payload.Id.Id));
69 + }
70 + }
71 + else
72 {
73 var packageId = payload.ParentPackagePayloadRef;
74 var parentUrl = payload.ParentPackagePayloadRef == null ? null : this.PayloadsById[payload.ParentPackagePayloadRef].DownloadUrl;
@@ -70,13 +78,6 @@ namespace WixToolset.Core.Burn.Bind
78 payload.DownloadUrl = resolvedUrl;
79 }
80 }
73 - else if (payload.Packaging == PackagingType.Embedded)
74 - {
75 - if (!String.IsNullOrEmpty(payload.DownloadUrl))
76 - {
77 - this.Messaging.Write(WarningMessages.DownloadUrlNotSupportedForEmbeddedPayloads(payload.SourceLineNumbers, payload.Id.Id));
78 - }
79 - }
81 }
82 }
83
src/WixToolset.Core.Burn/Bundles/BurnCommon.cs
+1 -2
@@ -19,8 +19,7 @@ namespace WixToolset.Core.Burn.Bundles
19 {
20 public const string BurnNamespace = "http://wixtoolset.org/schemas/v4/2008/Burn";
21 public const string BurnUXContainerEmbeddedIdFormat = "u{0}";
22 - public const string BurnUXContainerPayloadIdFormat = "p{0}";
23 - public const string BurnAttachedContainerEmbeddedIdFormat = "a{0}";
22 + public const string BurnAuthoredContainerEmbeddedIdFormat = "a{0}";
23
24 public const string BADataFileName = "BootstrapperApplicationData.xml";
25 public const string BADataNamespace = "http://wixtoolset.org/schemas/v4/BootstrapperApplicationData";
src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+33 -28
@@ -166,9 +166,7 @@ namespace WixToolset.Core.Burn.Bundles
166 // write the UX allPayloads...
167 foreach (var payload in this.UXContainerPayloads)
168 {
169 - writer.WriteStartElement("Payload");
170 - this.WriteBurnManifestPayloadAttributes(writer, payload, true, this.Payloads);
171 - writer.WriteEndElement();
169 + this.WriteBurnManifestUXPayload(writer, payload);
170 }
171
172 writer.WriteEndElement(); // </UX>
@@ -183,20 +181,9 @@ namespace WixToolset.Core.Burn.Bundles
181 }
182 }
183
186 - foreach (var payload in this.Payloads.Values)
184 + foreach (var payload in this.Payloads.Values.Where(p => p.ContainerRef != BurnConstants.BurnUXContainerName))
185 {
188 - if (PackagingType.Embedded == payload.Packaging && BurnConstants.BurnUXContainerName != payload.ContainerRef)
189 - {
190 - writer.WriteStartElement("Payload");
191 - this.WriteBurnManifestPayloadAttributes(writer, payload, true, this.Payloads);
192 - writer.WriteEndElement();
193 - }
194 - else if (PackagingType.External == payload.Packaging)
195 - {
196 - writer.WriteStartElement("Payload");
197 - this.WriteBurnManifestPayloadAttributes(writer, payload, false, this.Payloads);
198 - writer.WriteEndElement();
199 - }
186 + this.WriteBurnManifestPayload(writer, payload);
187 }
188
189 foreach (var rollbackBoundary in this.RollbackBoundaries)
@@ -654,9 +641,9 @@ namespace WixToolset.Core.Burn.Bundles
641 }
642 }
643
657 - private void WriteBurnManifestPayloadAttributes(XmlTextWriter writer, WixBundlePayloadSymbol payload, bool embeddedOnly, Dictionary<string, WixBundlePayloadSymbol> allPayloads)
644 + private void WriteBurnManifestPayload(XmlTextWriter writer, WixBundlePayloadSymbol payload)
645 {
659 - Debug.Assert(!embeddedOnly || PackagingType.Embedded == payload.Packaging);
646 + writer.WriteStartElement("Payload");
647
648 writer.WriteAttributeString("Id", payload.Id.Id);
649 writer.WriteAttributeString("FilePath", payload.Name);
@@ -668,28 +655,46 @@ namespace WixToolset.Core.Burn.Bundles
655 writer.WriteAttributeString("LayoutOnly", "yes");
656 }
657
658 + if (!String.IsNullOrEmpty(payload.DownloadUrl))
659 + {
660 + writer.WriteAttributeString("DownloadUrl", payload.DownloadUrl);
661 + }
662 +
663 switch (payload.Packaging)
664 {
665 case PackagingType.Embedded: // this means it's in a container.
666 + Debug.Assert(BurnConstants.BurnUXContainerName != payload.ContainerRef);
667 +
668 writer.WriteAttributeString("Packaging", "embedded");
669 writer.WriteAttributeString("SourcePath", payload.EmbeddedId);
676 -
677 - if (BurnConstants.BurnUXContainerName != payload.ContainerRef)
678 - {
679 - writer.WriteAttributeString("Container", payload.ContainerRef);
680 - }
670 + writer.WriteAttributeString("Container", payload.ContainerRef);
671 break;
672
673 case PackagingType.External:
684 - if (!String.IsNullOrEmpty(payload.DownloadUrl))
685 - {
686 - writer.WriteAttributeString("DownloadUrl", payload.DownloadUrl);
687 - }
688 -
674 writer.WriteAttributeString("Packaging", "external");
675 writer.WriteAttributeString("SourcePath", payload.Name);
676 break;
677 }
678 +
679 + writer.WriteEndElement();
680 + }
681 +
682 + private void WriteBurnManifestUXPayload(XmlTextWriter writer, WixBundlePayloadSymbol payload)
683 + {
684 + Debug.Assert(PackagingType.Embedded == payload.Packaging);
685 + Debug.Assert(BurnConstants.BurnUXContainerName == payload.ContainerRef);
686 +
687 + writer.WriteStartElement("Payload");
688 +
689 + // TODO: The engine should be updated to not require FileSize, Hash, or Packaging for UX payloads since the values are never used.
690 + writer.WriteAttributeString("Id", payload.Id.Id);
691 + writer.WriteAttributeString("FilePath", payload.Name);
692 + writer.WriteAttributeString("FileSize", payload.FileSize.Value.ToString(CultureInfo.InvariantCulture));
693 + writer.WriteAttributeString("Hash", payload.Hash);
694 + writer.WriteAttributeString("Packaging", "embedded");
695 + writer.WriteAttributeString("SourcePath", payload.EmbeddedId);
696 +
697 + writer.WriteEndElement();
698 }
699 }
700 }
src/WixToolset.Core.Burn/Bundles/CreateContainerCommand.cs
-7
@@ -44,13 +44,6 @@ namespace WixToolset.Core.Burn.Bundles
44
45 public void Execute()
46 {
47 - var payloadCount = this.Payloads.Count(); // The number of embedded payloads
48 -
49 - if (!String.IsNullOrEmpty(this.ManifestFile))
50 - {
51 - ++payloadCount;
52 - }
53 -
47 var cabinetPath = Path.GetFullPath(this.OutputPath);
48
49 var files = new List<CabinetCompressFile>();
src/WixToolset.Core/Compile/CompilerPayload.cs
+2 -9
@@ -15,8 +15,6 @@ namespace WixToolset.Core
15
16 public string Description { get; set; }
17
18 - public string DisplayName { get; set; }
19 -
18 public string DownloadUrl { get; set; }
19
20 public string Hash { get; set; }
@@ -158,7 +156,7 @@ namespace WixToolset.Core
156
157 if (!String.IsNullOrEmpty(this.DownloadUrl))
158 {
161 - this.Core.Write(WarningMessages.DownloadUrlNotSupportedForEmbeddedPayloads(this.SourceLineNumbers, this.Id.Id));
159 + this.Core.Write(WarningMessages.DownloadUrlNotSupportedForBAPayloads(this.SourceLineNumbers, this.Id.Id));
160 }
161
162 this.Compressed = YesNoDefaultType.Yes;
@@ -174,7 +172,7 @@ namespace WixToolset.Core
172 DownloadUrl = this.DownloadUrl,
173 Compressed = (this.Compressed == YesNoDefaultType.Yes) ? true : (this.Compressed == YesNoDefaultType.No) ? (bool?)false : null,
174 UnresolvedSourceFile = this.SourceFile, // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding.
177 - DisplayName = this.DisplayName ?? this.ProductName,
175 + DisplayName = this.ProductName,
176 Description = this.Description,
177 Hash = this.Hash,
178 FileSize = this.Size,
@@ -245,11 +243,6 @@ namespace WixToolset.Core
243 this.Description = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib);
244 }
245
248 - public void ParseDisplayName(XAttribute attrib)
249 - {
250 - this.DisplayName = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib);
251 - }
252 -
246 public void ParseDownloadUrl(XAttribute attrib)
247 {
248 this.DownloadUrl = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib);
src/test/WixToolsetTest.CoreIntegration/ContainerFixture.cs
+47 -3
@@ -15,6 +15,50 @@ namespace WixToolsetTest.CoreIntegration
15
16 public class ContainerFixture
17 {
18 + [Fact(Skip = "Test demonstrates failure")]
19 + public void CanBuildWithCustomAttachedContainer()
20 + {
21 + var folder = TestData.Get(@"TestData");
22 +
23 + using (var fs = new DisposableFileSystem())
24 + {
25 + var baseFolder = fs.GetFolder();
26 + var intermediateFolder = Path.Combine(baseFolder, "obj");
27 + var binFolder = Path.Combine(baseFolder, "bin");
28 + var bundlePath = Path.Combine(binFolder, "test.exe");
29 + var baFolderPath = Path.Combine(baseFolder, "ba");
30 + var extractFolderPath = Path.Combine(baseFolder, "extract");
31 +
32 + this.BuildMsis(folder, intermediateFolder, binFolder, buildToSubfolder: true);
33 +
34 + var result = WixRunner.Execute(new[]
35 + {
36 + "build",
37 + Path.Combine(folder, "Container", "HarvestIntoAttachedContainer.wxs"),
38 + Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"),
39 + "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
40 + "-bindpath", binFolder,
41 + "-intermediateFolder", intermediateFolder,
42 + "-o", bundlePath
43 + });
44 +
45 + result.AssertSuccess();
46 +
47 + Assert.True(File.Exists(bundlePath));
48 +
49 + var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath);
50 + extractResult.AssertSuccess();
51 +
52 + var payloads = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Payload");
53 + Assert.Equal(4, payloads.Count);
54 + var ignoreAttributes = new Dictionary<string, List<string>> { { "Payload", new List<string> { "FileSize", "Hash" } } };
55 + Assert.Equal(@"<Payload Id='FirstX64' FilePath='FirstX64\FirstX64.msi' FileSize='*' Hash='*' DownloadUrl='http://example.com//FirstX64/FirstX64/FirstX64.msi' Packaging='embedded' SourcePath='a0' Container='BundlePackages' />", payloads[0].GetTestXml(ignoreAttributes));
56 + Assert.Equal(@"<Payload Id='FirstX86.msi' FilePath='FirstX86\FirstX86.msi' FileSize='*' Hash='*' DownloadUrl='http://example.com//FirstX86.msi/FirstX86/FirstX86.msi' Packaging='embedded' SourcePath='a1' Container='BundlePackages' />", payloads[1].GetTestXml(ignoreAttributes));
57 + Assert.Equal(@"<Payload Id='fk1m38Cf9RZ2Bx_ipinRY6BftelU' FilePath='FirstX86\PFiles\MsiPackage\test.txt' FileSize='*' Hash='*' DownloadUrl='http://example.com/FirstX86/fk1m38Cf9RZ2Bx_ipinRY6BftelU/FirstX86/PFiles/MsiPackage/test.txt' Packaging='embedded' SourcePath='a2' Container='BundlePackages' />", payloads[2].GetTestXml(ignoreAttributes));
58 + Assert.Equal(@"<Payload Id='ff2L_N_DLQ.nSUi.l8LxG14gd2V4' FilePath='FirstX64\PFiles\MsiPackage\test.txt' FileSize='*' Hash='*' DownloadUrl='http://example.com/FirstX64/ff2L_N_DLQ.nSUi.l8LxG14gd2V4/FirstX64/PFiles/MsiPackage/test.txt' Packaging='embedded' SourcePath='a3' Container='BundlePackages' />", payloads[3].GetTestXml(ignoreAttributes));
59 + }
60 + }
61 +
62 [Fact]
63 public void HarvestedPayloadsArePutInCorrectContainer()
64 {
@@ -309,7 +353,7 @@ namespace WixToolsetTest.CoreIntegration
353 }
354 }
355
312 - private void BuildMsis(string folder, string intermediateFolder, string binFolder)
356 + private void BuildMsis(string folder, string intermediateFolder, string binFolder, bool buildToSubfolder = false)
357 {
358 var result = WixRunner.Execute(new[]
359 {
@@ -319,7 +363,7 @@ namespace WixToolsetTest.CoreIntegration
363 Path.Combine(folder, "ProductWithComponentGroupRef", "Product.wxs"),
364 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
365 "-intermediateFolder", intermediateFolder,
322 - "-o", Path.Combine(binFolder, "FirstX86.msi"),
366 + "-o", Path.Combine(binFolder, buildToSubfolder ? "FirstX86" : ".", "FirstX86.msi"),
367 });
368
369 result.AssertSuccess();
@@ -332,7 +376,7 @@ namespace WixToolsetTest.CoreIntegration
376 Path.Combine(folder, "ProductWithComponentGroupRef", "Product.wxs"),
377 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
378 "-intermediateFolder", intermediateFolder,
335 - "-o", Path.Combine(binFolder, "FirstX64.msi"),
379 + "-o", Path.Combine(binFolder, buildToSubfolder ? "FirstX64" : ".", "FirstX64.msi"),
380 });
381
382 result.AssertSuccess();
src/test/WixToolsetTest.CoreIntegration/TestData/Container/HarvestIntoAttachedContainer.wxs new
+17
@@ -0,0 +1,17 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 + <Fragment>
4 + <PackageGroup Id="BundlePackages">
5 + <MsiPackage Id="FirstX86">
6 + <PayloadGroupRef Id="FirstX86Payloads" />
7 + </MsiPackage>
8 + <MsiPackage Id="FirstX64" Name="FirstX64\FirstX64.msi" SourceFile="FirstX64\" DownloadUrl="http://example.com/{0}/{1}/{2}" />
9 + </PackageGroup>
10 + <Container Id="BundlePackages" Type="attached">
11 + <PackageGroupRef Id="BundlePackages" />
12 + </Container>
13 + <PayloadGroup Id="FirstX86Payloads">
14 + <MsiPackagePayload Name="FirstX86\FirstX86.msi" SourceFile="FirstX86\" DownloadUrl="http://example.com/{0}/{1}/{2}" />
15 + </PayloadGroup>
16 + </Fragment>
17 +</Wix>