diff options
Diffstat (limited to 'src')
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 | |||
| 3 | namespace 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"); |
