aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2019-10-07 11:18:13 -0700
committerRob Mensching <rob@firegiant.com>2019-10-07 11:59:14 -0700
commit860676fa5b40a1904478151e9b4934c004e7db63 (patch)
tree83fabd53f2a68dcf56bc8da66d88e115af3764b0 /src/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs
parent3b98dac62b47d590f3465985362d6e6fd100b1c0 (diff)
downloadwix-860676fa5b40a1904478151e9b4934c004e7db63.tar.gz
wix-860676fa5b40a1904478151e9b4934c004e7db63.tar.bz2
wix-860676fa5b40a1904478151e9b4934c004e7db63.zip
Implement Bundle build
Diffstat (limited to 'src/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs')
-rw-r--r--src/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs166
1 files changed, 166 insertions, 0 deletions
diff --git a/src/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs b/src/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs
new file mode 100644
index 00000000..7f36dbcc
--- /dev/null
+++ b/src/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs
@@ -0,0 +1,166 @@
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 System.Linq;
8 using WixToolset.Data;
9 using WixToolset.Core.Burn.Bundles;
10 using WixToolset.Extensibility.Services;
11 using WixToolset.Data.Tuples;
12
13 internal class ProcessDependencyProvidersCommand
14 {
15 public ProcessDependencyProvidersCommand(IMessaging messaging, IntermediateSection section, IDictionary<string, PackageFacade> facades)
16 {
17 this.Messaging = messaging;
18 this.Section = section;
19
20 this.Facades = facades;
21 }
22
23 public string BundleProviderKey { get; private set; }
24
25 public Dictionary<string, ProvidesDependencyTuple> DependencyTuplesByKey { get; private set; }
26
27 private IMessaging Messaging { get; }
28
29 private IntermediateSection Section { get; }
30
31 private IDictionary<string, PackageFacade> Facades { get; }
32
33 /// <summary>
34 /// Sets the explicitly provided bundle provider key, if provided. And...
35 /// Imports authored dependency providers for each package in the manifest,
36 /// and generates dependency providers for certain package types that do not
37 /// have a provider defined.
38 /// </summary>
39 public void Execute()
40 {
41 var wixDependencyProviderTuples = this.Section.Tuples.OfType<WixDependencyProviderTuple>();
42
43 foreach (var wixDependencyProviderTuple in wixDependencyProviderTuples)
44 {
45 // Sets the provider key for the bundle, if it is not set already.
46 if (String.IsNullOrEmpty(this.BundleProviderKey))
47 {
48 if (wixDependencyProviderTuple.Bundle)
49 {
50 this.BundleProviderKey = wixDependencyProviderTuple.ProviderKey;
51 }
52 }
53
54 // Import any authored dependencies. These may merge with imported provides from MSI packages.
55 var packageId = wixDependencyProviderTuple.Id.Id;
56
57 if (this.Facades.TryGetValue(packageId, out var facade))
58 {
59 var dependency = new ProvidesDependencyTuple(wixDependencyProviderTuple.SourceLineNumbers, wixDependencyProviderTuple.Id)
60 {
61 PackageRef = packageId,
62 Key = wixDependencyProviderTuple.ProviderKey,
63 Version = wixDependencyProviderTuple.Version,
64 DisplayName = wixDependencyProviderTuple.DisplayName,
65 Attributes = (int)wixDependencyProviderTuple.Attributes
66 };
67
68 if (String.IsNullOrEmpty(dependency.Key))
69 {
70 switch (facade.SpecificPackageTuple)
71 {
72 // The WixDependencyExtension allows an empty Key for MSIs and MSPs.
73 case WixBundleMsiPackageTuple msiPackage:
74 dependency.Key = msiPackage.ProductCode;
75 break;
76 case WixBundleMspPackageTuple mspPackage:
77 dependency.Key = mspPackage.PatchCode;
78 break;
79 }
80 }
81
82 if (String.IsNullOrEmpty(dependency.Version))
83 {
84 dependency.Version = facade.PackageTuple.Version;
85 }
86
87 // If the version is still missing, a version could not be harvested from the package and was not authored.
88 if (String.IsNullOrEmpty(dependency.Version))
89 {
90 this.Messaging.Write(ErrorMessages.MissingDependencyVersion(facade.PackageId));
91 }
92
93 if (String.IsNullOrEmpty(dependency.DisplayName))
94 {
95 dependency.DisplayName = facade.PackageTuple.DisplayName;
96 }
97
98 this.Section.Tuples.Add(dependency);
99 }
100 }
101
102 this.DependencyTuplesByKey = this.GetDependencyTuplesByKey();
103
104 // Generate providers for MSI and MSP packages that still do not have providers.
105 foreach (var facade in this.Facades.Values)
106 {
107 string key = null;
108
109 //if (WixBundlePackageType.Msi == facade.PackageTuple.Type)
110 if (facade.SpecificPackageTuple is WixBundleMsiPackageTuple msiPackage)
111 {
112 //var msiPackage = (WixBundleMsiPackageTuple)facade.SpecificPackageTuple;
113 key = msiPackage.ProductCode;
114 }
115 //else if (WixBundlePackageType.Msp == facade.PackageTuple.Type)
116 else if (facade.SpecificPackageTuple is WixBundleMspPackageTuple mspPackage)
117 {
118 //var mspPackage = (WixBundleMspPackageTuple)facade.SpecificPackageTuple;
119 key = mspPackage.PatchCode;
120 }
121
122 if (!String.IsNullOrEmpty(key) && !this.DependencyTuplesByKey.ContainsKey(key))
123 {
124 var dependency = new ProvidesDependencyTuple(facade.PackageTuple.SourceLineNumbers, facade.PackageTuple.Id)
125 {
126 PackageRef = facade.PackageId,
127 Key = key,
128 Version = facade.PackageTuple.Version,
129 DisplayName = facade.PackageTuple.DisplayName
130 };
131
132 this.Section.Tuples.Add(dependency);
133
134 this.DependencyTuplesByKey.Add(dependency.Key, dependency);
135 }
136 }
137 }
138
139 private Dictionary<string, ProvidesDependencyTuple> GetDependencyTuplesByKey()
140 {
141 var dependencyTuplesByKey = new Dictionary<string, ProvidesDependencyTuple>();
142
143 var dependencyTuples = this.Section.Tuples.OfType<ProvidesDependencyTuple>();
144
145 foreach (var dependency in dependencyTuples)
146 {
147 if (dependencyTuplesByKey.TryGetValue(dependency.Key, out var collision))
148 {
149 // If not a perfect dependency collision, display an error.
150 if (dependency.Key != collision.Key ||
151 dependency.Version != collision.Version ||
152 dependency.DisplayName != collision.DisplayName)
153 {
154 this.Messaging.Write(ErrorMessages.DuplicateProviderDependencyKey(dependency.Key, dependency.PackageRef));
155 }
156 }
157 else
158 {
159 dependencyTuplesByKey.Add(dependency.Key, dependency);
160 }
161 }
162
163 return dependencyTuplesByKey;
164 }
165 }
166}