aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs8
-rw-r--r--src/WixToolset.Core.Burn/Bind/ResolveDownloadUrlsCommand.cs127
-rw-r--r--src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs49
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs2
4 files changed, 138 insertions, 48 deletions
diff --git a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
index ea8d33d0..fd847e05 100644
--- a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+++ b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
@@ -459,12 +459,18 @@ namespace WixToolset.Core.Burn
459 containers = command.Containers; 459 containers = command.Containers;
460 } 460 }
461 461
462 // Resolve the download URLs now that we have all of the containers and payloads calculated.
463 {
464 var command = new ResolveDownloadUrlsCommand(this.Messaging, this.BackendExtensions, containers, payloadSymbols);
465 command.Execute();
466 }
467
462 // Create the bundle manifest. 468 // Create the bundle manifest.
463 string manifestPath; 469 string manifestPath;
464 { 470 {
465 var executableName = Path.GetFileName(this.OutputPath); 471 var executableName = Path.GetFileName(this.OutputPath);
466 472
467 var command = new CreateBurnManifestCommand(this.Messaging, this.BackendExtensions, executableName, section, bundleSymbol, containers, chainSymbol, orderedFacades, boundaries, uxPayloads, payloadSymbols, packagesPayloads, orderedSearches, this.IntermediateFolder); 473 var command = new CreateBurnManifestCommand(executableName, section, bundleSymbol, containers, chainSymbol, orderedFacades, boundaries, uxPayloads, payloadSymbols, packagesPayloads, orderedSearches, this.IntermediateFolder);
468 command.Execute(); 474 command.Execute();
469 475
470 manifestPath = command.OutputPath; 476 manifestPath = command.OutputPath;
diff --git a/src/WixToolset.Core.Burn/Bind/ResolveDownloadUrlsCommand.cs b/src/WixToolset.Core.Burn/Bind/ResolveDownloadUrlsCommand.cs
new file mode 100644
index 00000000..e41c1058
--- /dev/null
+++ b/src/WixToolset.Core.Burn/Bind/ResolveDownloadUrlsCommand.cs
@@ -0,0 +1,127 @@
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
3namespace WixToolset.Core.Burn.Bind
4{
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Data;
8 using WixToolset.Data.Symbols;
9 using WixToolset.Extensibility;
10 using WixToolset.Extensibility.Services;
11
12 internal class ResolveDownloadUrlsCommand
13 {
14 public ResolveDownloadUrlsCommand(IMessaging messaging, IEnumerable<IBurnBackendBinderExtension> backendExtensions, IEnumerable<WixBundleContainerSymbol> containers, Dictionary<string, WixBundlePayloadSymbol> payloadsById)
15 {
16 this.Messaging = messaging;
17 this.BackendExtensions = backendExtensions;
18 this.Containers = containers;
19 this.PayloadsById = payloadsById;
20 }
21
22 private IMessaging Messaging { get; }
23
24 private IEnumerable<IBurnBackendBinderExtension> BackendExtensions { get; }
25
26 private IEnumerable<WixBundleContainerSymbol> Containers { get; }
27
28 private Dictionary<string, WixBundlePayloadSymbol> PayloadsById { get; }
29
30 public void Execute()
31 {
32 this.ResolveContainerUrls();
33
34 this.ResolvePayloadUrls();
35 }
36
37 private void ResolveContainerUrls()
38 {
39 foreach (var container in this.Containers)
40 {
41 if (container.Type == ContainerType.Detached)
42 {
43 var resolvedUrl = this.ResolveUrl(container.DownloadUrl, null, null, container.Id.Id, container.Name);
44 if (!String.IsNullOrEmpty(resolvedUrl))
45 {
46 container.DownloadUrl = resolvedUrl;
47 }
48 }
49 else if (container.Type == ContainerType.Attached)
50 {
51 if (!String.IsNullOrEmpty(container.DownloadUrl))
52 {
53 this.Messaging.Write(WarningMessages.DownloadUrlNotSupportedForAttachedContainers(container.SourceLineNumbers, container.Id.Id));
54 }
55 }
56 }
57 }
58
59 private void ResolvePayloadUrls()
60 {
61 foreach (var payload in this.PayloadsById.Values)
62 {
63 if (payload.Packaging == PackagingType.External)
64 {
65 var packageId = payload.ParentPackagePayloadRef;
66 var parentUrl = payload.ParentPackagePayloadRef == null ? null : this.PayloadsById[payload.ParentPackagePayloadRef].DownloadUrl;
67 var resolvedUrl = this.ResolveUrl(payload.DownloadUrl, parentUrl, packageId, payload.Id.Id, payload.Name);
68 if (!String.IsNullOrEmpty(resolvedUrl))
69 {
70 payload.DownloadUrl = resolvedUrl;
71 }
72 }
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 }
80 }
81 }
82
83 private string ResolveUrl(string url, string fallbackUrl, string packageId, string payloadId, string fileName)
84 {
85 string resolvedUrl = null;
86
87 foreach (var extension in this.BackendExtensions)
88 {
89 resolvedUrl = extension.ResolveUrl(url, fallbackUrl, packageId, payloadId, fileName);
90 if (!String.IsNullOrEmpty(resolvedUrl))
91 {
92 break;
93 }
94 }
95
96 if (String.IsNullOrEmpty(resolvedUrl))
97 {
98 // If a URL was not specified but there is a fallback URL that has a format specifier in it
99 // then use the fallback URL formatter for this URL.
100 if (String.IsNullOrEmpty(url) && !String.IsNullOrEmpty(fallbackUrl))
101 {
102 var formattedFallbackUrl = String.Format(fallbackUrl, packageId, payloadId, fileName);
103 if (!String.Equals(fallbackUrl, formattedFallbackUrl, StringComparison.OrdinalIgnoreCase))
104 {
105 url = fallbackUrl;
106 }
107 }
108
109 if (!String.IsNullOrEmpty(url))
110 {
111 var formattedUrl = String.Format(url, packageId, payloadId, fileName);
112
113 if (Uri.TryCreate(formattedUrl, UriKind.Absolute, out var canonicalUri))
114 {
115 resolvedUrl = canonicalUri.AbsoluteUri;
116 }
117 else
118 {
119 resolvedUrl = null;
120 }
121 }
122 }
123
124 return resolvedUrl;
125 }
126 }
127}
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
index 128c7a5f..a8a12c28 100644
--- a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
@@ -18,10 +18,8 @@ namespace WixToolset.Core.Burn.Bundles
18 18
19 internal class CreateBurnManifestCommand 19 internal class CreateBurnManifestCommand
20 { 20 {
21 public CreateBurnManifestCommand(IMessaging messaging, IEnumerable<IBurnBackendBinderExtension> backendExtensions, string executableName, IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleContainerSymbol> containers, WixChainSymbol chainSymbol, IEnumerable<PackageFacade> orderedPackages, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, IEnumerable<WixBundlePayloadSymbol> uxPayloads, Dictionary<string, WixBundlePayloadSymbol> allPayloadsById, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, IEnumerable<ISearchFacade> orderedSearches, string intermediateFolder) 21 public CreateBurnManifestCommand(string executableName, IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleContainerSymbol> containers, WixChainSymbol chainSymbol, IEnumerable<PackageFacade> orderedPackages, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, IEnumerable<WixBundlePayloadSymbol> uxPayloads, Dictionary<string, WixBundlePayloadSymbol> allPayloadsById, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, IEnumerable<ISearchFacade> orderedSearches, string intermediateFolder)
22 { 22 {
23 this.Messaging = messaging;
24 this.BackendExtensions = backendExtensions;
25 this.ExecutableName = executableName; 23 this.ExecutableName = executableName;
26 this.Section = section; 24 this.Section = section;
27 this.BundleSymbol = bundleSymbol; 25 this.BundleSymbol = bundleSymbol;
@@ -38,10 +36,6 @@ namespace WixToolset.Core.Burn.Bundles
38 36
39 public string OutputPath { get; private set; } 37 public string OutputPath { get; private set; }
40 38
41 private IMessaging Messaging { get; }
42
43 private IEnumerable<IBurnBackendBinderExtension> BackendExtensions { get; }
44
45 private string ExecutableName { get; } 39 private string ExecutableName { get; }
46 40
47 private IntermediateSection Section { get; } 41 private IntermediateSection Section { get; }
@@ -657,12 +651,7 @@ namespace WixToolset.Core.Burn.Bundles
657 651
658 if (ContainerType.Detached == container.Type) 652 if (ContainerType.Detached == container.Type)
659 { 653 {
660 string resolvedUrl = this.ResolveUrl(container.DownloadUrl, null, null, container.Id.Id, container.Name); 654 if (!String.IsNullOrEmpty(container.DownloadUrl))
661 if (!String.IsNullOrEmpty(resolvedUrl))
662 {
663 writer.WriteAttributeString("DownloadUrl", resolvedUrl);
664 }
665 else if (!String.IsNullOrEmpty(container.DownloadUrl))
666 { 655 {
667 writer.WriteAttributeString("DownloadUrl", container.DownloadUrl); 656 writer.WriteAttributeString("DownloadUrl", container.DownloadUrl);
668 } 657 }
@@ -671,11 +660,6 @@ namespace WixToolset.Core.Burn.Bundles
671 } 660 }
672 else if (ContainerType.Attached == container.Type) 661 else if (ContainerType.Attached == container.Type)
673 { 662 {
674 if (!String.IsNullOrEmpty(container.DownloadUrl))
675 {
676 this.Messaging.Write(WarningMessages.DownloadUrlNotSupportedForAttachedContainers(container.SourceLineNumbers, container.Id.Id));
677 }
678
679 writer.WriteAttributeString("FilePath", executableName); // attached containers use the name of the bundle since they are attached to the executable. 663 writer.WriteAttributeString("FilePath", executableName); // attached containers use the name of the bundle since they are attached to the executable.
680 writer.WriteAttributeString("AttachedIndex", container.AttachedContainerIndex.Value.ToString(CultureInfo.InvariantCulture)); 664 writer.WriteAttributeString("AttachedIndex", container.AttachedContainerIndex.Value.ToString(CultureInfo.InvariantCulture));
681 writer.WriteAttributeString("Attached", "yes"); 665 writer.WriteAttributeString("Attached", "yes");
@@ -700,11 +684,6 @@ namespace WixToolset.Core.Burn.Bundles
700 switch (payload.Packaging) 684 switch (payload.Packaging)
701 { 685 {
702 case PackagingType.Embedded: // this means it's in a container. 686 case PackagingType.Embedded: // this means it's in a container.
703 if (!String.IsNullOrEmpty(payload.DownloadUrl))
704 {
705 this.Messaging.Write(WarningMessages.DownloadUrlNotSupportedForEmbeddedPayloads(payload.SourceLineNumbers, payload.Id.Id));
706 }
707
708 writer.WriteAttributeString("Packaging", "embedded"); 687 writer.WriteAttributeString("Packaging", "embedded");
709 writer.WriteAttributeString("SourcePath", payload.EmbeddedId); 688 writer.WriteAttributeString("SourcePath", payload.EmbeddedId);
710 689
@@ -715,14 +694,7 @@ namespace WixToolset.Core.Burn.Bundles
715 break; 694 break;
716 695
717 case PackagingType.External: 696 case PackagingType.External:
718 var packageId = payload.ParentPackagePayloadRef; 697 if (!String.IsNullOrEmpty(payload.DownloadUrl))
719 var parentUrl = payload.ParentPackagePayloadRef == null ? null : allPayloads[payload.ParentPackagePayloadRef].DownloadUrl;
720 var resolvedUrl = this.ResolveUrl(payload.DownloadUrl, parentUrl, packageId, payload.Id.Id, payload.Name);
721 if (!String.IsNullOrEmpty(resolvedUrl))
722 {
723 writer.WriteAttributeString("DownloadUrl", resolvedUrl);
724 }
725 else if (!String.IsNullOrEmpty(payload.DownloadUrl))
726 { 698 {
727 writer.WriteAttributeString("DownloadUrl", payload.DownloadUrl); 699 writer.WriteAttributeString("DownloadUrl", payload.DownloadUrl);
728 } 700 }
@@ -732,20 +704,5 @@ namespace WixToolset.Core.Burn.Bundles
732 break; 704 break;
733 } 705 }
734 } 706 }
735
736 private string ResolveUrl(string url, string fallbackUrl, string packageId, string payloadId, string fileName)
737 {
738 string resolved = null;
739 foreach (var extension in this.BackendExtensions)
740 {
741 resolved = extension.ResolveUrl(url, fallbackUrl, packageId, payloadId, fileName);
742 if (!String.IsNullOrEmpty(resolved))
743 {
744 break;
745 }
746 }
747
748 return resolved;
749 }
750 } 707 }
751} 708}
diff --git a/src/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs b/src/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs
index 9bd33eac..e9e59b9e 100644
--- a/src/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs
+++ b/src/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs
@@ -143,7 +143,7 @@ namespace WixToolsetTest.CoreIntegration
143 } 143 }
144 } 144 }
145 145
146 [Fact(Skip = "Test demonstrates failure")] 146 [Fact]
147 public void ReplacesDownloadUrlPlaceholders() 147 public void ReplacesDownloadUrlPlaceholders()
148 { 148 {
149 var folder = TestData.Get(@"TestData"); 149 var folder = TestData.Get(@"TestData");