@joebigelow / wix-1 / commits / 7a0aa561

Improve error messages from BalBurnBackendExtension.

Sean Hall committed Jan 18, 2023 at 19:03 UTC 7a0aa56131ba7fa3b63788908c164d0f8118e3fc
6 files changed +105 -33
src/ext/Bal/test/WixToolsetTest.Bal/BalExtensionFixture.cs
+1 -1
@@ -204,7 +204,7 @@ namespace WixToolsetTest.Bal
204 });
205 WixAssert.CompareLineByLine(new[]
206 {
207 - "The BA's entry point DLL must have bal:BAFactoryAssembly=\"yes\" when using the DotNetCoreBootstrapperApplicationHost.",
207 + "When using DotNetCoreBootstrapperApplicationHost, the Payload element for the BA's entry point DLL must have bal:BAFactoryAssembly=\"yes\".",
208 }, compileResult.Messages.Select(x => x.ToString()).ToArray());
209 Assert.Equal(6818, compileResult.ExitCode);
210
src/ext/Bal/wixext/BalBurnBackendExtension.cs
+27 -18
@@ -86,6 +86,11 @@ namespace WixToolset.Bal
86
87 return true;
88 }
89 + else if (symbol is WixBalBootstrapperApplicationSymbol)
90 + {
91 + // This symbol is only for the processing in SymbolsFinalized.
92 + return true;
93 + }
94 else
95 {
96 return base.TryProcessSymbol(section, symbol);
@@ -100,28 +105,33 @@ namespace WixToolset.Bal
105 this.VerifyDisplayInternalUICondition(section);
106 this.VerifyOverridableVariables(section);
107
103 - var baSymbol = section.Symbols.OfType<WixBootstrapperApplicationDllSymbol>().SingleOrDefault();
104 - var baId = baSymbol?.Id?.Id;
105 - if (null == baId)
108 + var balBaSymbol = section.Symbols.OfType<WixBalBootstrapperApplicationSymbol>().SingleOrDefault();
109 + if (balBaSymbol == null)
110 {
111 return;
112 }
113
110 - var isIuiBA = baId.StartsWith("WixInternalUIBootstrapperApplication");
111 - var isStdBA = baId.StartsWith("WixStandardBootstrapperApplication");
112 - var isMBA = baId.StartsWith("WixManagedBootstrapperApplicationHost");
113 - var isDNC = baId.StartsWith("WixDotNetCoreBootstrapperApplicationHost");
114 + var isIuiBA = balBaSymbol.Type == WixBalBootstrapperApplicationType.InternalUi;
115 + var isStdBA = balBaSymbol.Type == WixBalBootstrapperApplicationType.Standard;
116 + var isMBA = balBaSymbol.Type == WixBalBootstrapperApplicationType.ManagedHost;
117 + var isDNC = balBaSymbol.Type == WixBalBootstrapperApplicationType.DotNetCoreHost;
118 var isSCD = isDNC && this.VerifySCD(section);
119
120 +
121 + if (!isIuiBA && !isStdBA && !isMBA && !isDNC)
122 + {
123 + throw new WixException($"Invalid WixBalBootstrapperApplicationType: '{balBaSymbol.Type}'");
124 + }
125 +
126 if (isIuiBA)
127 {
128 // This needs to happen before VerifyPrereqPackages because it can add prereq packages.
119 - this.VerifyPrimaryPackages(section);
129 + this.VerifyPrimaryPackages(section, balBaSymbol.SourceLineNumbers);
130 }
131
132 if (isDNC)
133 {
124 - this.FinalizeBAFactorySymbol(section, baSymbol);
134 + this.FinalizeBAFactorySymbol(section, balBaSymbol.SourceLineNumbers);
135 }
136
137 if (isIuiBA || isStdBA || isMBA || isDNC)
@@ -131,16 +141,16 @@ namespace WixToolset.Bal
141
142 if (isIuiBA || isMBA || (isDNC && !isSCD))
143 {
134 - this.VerifyPrereqPackages(section, isDNC, isIuiBA);
144 + this.VerifyPrereqPackages(section, balBaSymbol.SourceLineNumbers, isDNC, isIuiBA);
145 }
146 }
147
138 - private void FinalizeBAFactorySymbol(IntermediateSection section, WixBootstrapperApplicationDllSymbol baSymbol)
148 + private void FinalizeBAFactorySymbol(IntermediateSection section, SourceLineNumber baSourceLineNumbers)
149 {
150 var factorySymbol = section.Symbols.OfType<WixBalBAFactoryAssemblySymbol>().SingleOrDefault();
151 if (null == factorySymbol)
152 {
143 - this.Messaging.Write(BalErrors.MissingDNCBAFactoryAssembly(baSymbol.SourceLineNumbers));
153 + this.Messaging.Write(BalErrors.MissingDNCBAFactoryAssembly(baSourceLineNumbers));
154 return;
155 }
156
@@ -149,8 +159,7 @@ namespace WixToolset.Bal
159 .SingleOrDefault();
160 if (null == factoryPayloadSymbol)
161 {
152 - this.Messaging.Write(BalErrors.MissingDNCBAFactoryAssembly(factorySymbol.SourceLineNumbers));
153 - return;
162 + throw new WixException($"Missing payload symbol with id: 'factorySymbol.PayloadId'");
163 }
164
165 factorySymbol.FilePath = factoryPayloadSymbol.Name;
@@ -216,7 +225,7 @@ namespace WixToolset.Bal
225 }
226 }
227
219 - private void VerifyPrimaryPackages(IntermediateSection section)
228 + private void VerifyPrimaryPackages(IntermediateSection section, SourceLineNumber baSourceLineNumbers)
229 {
230 WixBalPackageInfoSymbol defaultPrimaryPackage = null;
231 WixBalPackageInfoSymbol x86PrimaryPackage = null;
@@ -398,7 +407,7 @@ namespace WixToolset.Bal
407 }
408 else if (defaultPrimaryPackage == null)
409 {
401 - this.Messaging.Write(BalErrors.MissingIUIPrimaryPackage());
410 + this.Messaging.Write(BalErrors.MissingIUIPrimaryPackage(baSourceLineNumbers));
411 }
412 else
413 {
@@ -467,12 +476,12 @@ namespace WixToolset.Bal
476 }
477 }
478
470 - private void VerifyPrereqPackages(IntermediateSection section, bool isDNC, bool isIuiBA)
479 + private void VerifyPrereqPackages(IntermediateSection section, SourceLineNumber baSourceLineNumbers, bool isDNC, bool isIuiBA)
480 {
481 var prereqInfoSymbols = section.Symbols.OfType<WixMbaPrereqInformationSymbol>().ToList();
482 if (!isIuiBA && prereqInfoSymbols.Count == 0)
483 {
475 - var message = isDNC ? BalErrors.MissingDNCPrereq() : BalErrors.MissingMBAPrereq();
484 + var message = isDNC ? BalErrors.MissingDNCPrereq(baSourceLineNumbers) : BalErrors.MissingMBAPrereq(baSourceLineNumbers);
485 this.Messaging.Write(message);
486 return;
487 }
src/ext/Bal/wixext/BalCompiler.cs
+10 -5
@@ -581,7 +581,7 @@ namespace WixToolset.Bal
581 break;
582 }
583
584 - this.CreateBARef(section, sourceLineNumbers, node, baId);
584 + this.CreateBARef(section, sourceLineNumbers, node, baId, WixBalBootstrapperApplicationType.InternalUi);
585 }
586 }
587
@@ -860,7 +860,7 @@ namespace WixToolset.Bal
860 break;
861 }
862
863 - this.CreateBARef(section, sourceLineNumbers, node, baId);
863 + this.CreateBARef(section, sourceLineNumbers, node, baId, WixBalBootstrapperApplicationType.Standard);
864 }
865 }
866
@@ -963,7 +963,7 @@ namespace WixToolset.Bal
963 break;
964 }
965
966 - this.CreateBARef(section, sourceLineNumbers, node, baId);
966 + this.CreateBARef(section, sourceLineNumbers, node, baId, WixBalBootstrapperApplicationType.ManagedHost);
967
968 if (alwaysInstallPrereqs)
969 {
@@ -1086,7 +1086,7 @@ namespace WixToolset.Bal
1086 break;
1087 }
1088
1089 - this.CreateBARef(section, sourceLineNumbers, node, baId);
1089 + this.CreateBARef(section, sourceLineNumbers, node, baId, WixBalBootstrapperApplicationType.DotNetCoreHost);
1090
1091 if (alwaysInstallPrereqs)
1092 {
@@ -1098,7 +1098,7 @@ namespace WixToolset.Bal
1098 }
1099 }
1100
1101 - private void CreateBARef(IntermediateSection section, SourceLineNumber sourceLineNumbers, XElement node, string name)
1101 + private void CreateBARef(IntermediateSection section, SourceLineNumber sourceLineNumbers, XElement node, string name, WixBalBootstrapperApplicationType baType)
1102 {
1103 var id = this.ParseHelper.CreateIdentifierValueFromPlatform(name, this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64);
1104 if (id == null)
@@ -1109,6 +1109,11 @@ namespace WixToolset.Bal
1109 if (!this.Messaging.EncounteredError)
1110 {
1111 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixBootstrapperApplication, id);
1112 +
1113 + section.AddSymbol(new WixBalBootstrapperApplicationSymbol(sourceLineNumbers)
1114 + {
1115 + Type = baType,
1116 + });
1117 }
1118 }
1119 }
src/ext/Bal/wixext/BalErrors.cs
+7 -7
@@ -45,22 +45,22 @@ namespace WixToolset.Bal
45
46 public static Message MissingDNCBAFactoryAssembly(SourceLineNumber sourceLineNumbers)
47 {
48 - return Message(sourceLineNumbers, Ids.MissingDNCBAFactoryAssembly, "The BA's entry point DLL must have bal:BAFactoryAssembly=\"yes\" when using the DotNetCoreBootstrapperApplicationHost.");
48 + return Message(sourceLineNumbers, Ids.MissingDNCBAFactoryAssembly, "When using DotNetCoreBootstrapperApplicationHost, the Payload element for the BA's entry point DLL must have bal:BAFactoryAssembly=\"yes\".");
49 }
50
51 - public static Message MissingDNCPrereq()
51 + public static Message MissingDNCPrereq(SourceLineNumber sourceLineNumbers)
52 {
53 - return Message(null, Ids.MissingDNCPrereq, "There must be at least one package with bal:PrereqPackage=\"yes\" when using the DotNetCoreBootstrapperApplicationHost with SelfContainedDeployment set to \"no\".");
53 + return Message(sourceLineNumbers, Ids.MissingDNCPrereq, "There must be at least one package with bal:PrereqPackage=\"yes\" when using the DotNetCoreBootstrapperApplicationHost with SelfContainedDeployment set to \"no\".");
54 }
55
56 - public static Message MissingIUIPrimaryPackage()
56 + public static Message MissingIUIPrimaryPackage(SourceLineNumber sourceLineNumbers)
57 {
58 - return Message(null, Ids.MissingIUIPrimaryPackage, "When using WixInternalUIBootstrapperApplication, there must be one package with bal:PrimaryPackageType=\"default\".");
58 + return Message(sourceLineNumbers, Ids.MissingIUIPrimaryPackage, "When using WixInternalUIBootstrapperApplication, there must be one package with bal:PrimaryPackageType=\"default\".");
59 }
60
61 - public static Message MissingMBAPrereq()
61 + public static Message MissingMBAPrereq(SourceLineNumber sourceLineNumbers)
62 {
63 - return Message(null, Ids.MissingMBAPrereq, "There must be at least one package with bal:PrereqPackage=\"yes\" when using the ManagedBootstrapperApplicationHost.\nThis is typically done by using the WixNetFxExtension and referencing one of the NetFxAsPrereq package groups.");
63 + return Message(sourceLineNumbers, Ids.MissingMBAPrereq, "There must be at least one package with bal:PrereqPackage=\"yes\" when using the ManagedBootstrapperApplicationHost.\nThis is typically done by using the WixNetFxExtension and referencing one of the NetFxAsPrereq package groups.");
64 }
65
66 public static Message MultipleBAFunctions(SourceLineNumber sourceLineNumbers)
src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs
+4 -2
@@ -18,12 +18,11 @@ namespace WixToolset.Bal
18 WixStdbaOptions,
19 WixStdbaOverridableVariable,
20 WixMbaPrereqOptions,
21 + WixBalBootstrapperApplication,
22 }
23
24 public static partial class BalSymbolDefinitions
25 {
25 - public static readonly Version Version = new Version("4.0.0");
26 -
26 public static IntermediateSymbolDefinition ByName(string name)
27 {
28 if (!Enum.TryParse(name, out BalSymbolDefinitionType type))
@@ -68,6 +67,9 @@ namespace WixToolset.Bal
67 case BalSymbolDefinitionType.WixMbaPrereqOptions:
68 return BalSymbolDefinitions.WixMbaPrereqOptions;
69
70 + case BalSymbolDefinitionType.WixBalBootstrapperApplication:
71 + return BalSymbolDefinitions.WixBalBootstrapperApplication;
72 +
73 default:
74 throw new ArgumentOutOfRangeException(nameof(type));
75 }
src/ext/Bal/wixext/Symbols/WixBalBootstrapperApplicationSymbol.cs new
+56
@@ -0,0 +1,56 @@
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.Bal
4 +{
5 + using WixToolset.Data;
6 + using WixToolset.Bal.Symbols;
7 +
8 + public static partial class BalSymbolDefinitions
9 + {
10 + public static readonly IntermediateSymbolDefinition WixBalBootstrapperApplication = new IntermediateSymbolDefinition(
11 + BalSymbolDefinitionType.WixBalBootstrapperApplication.ToString(),
12 + new[]
13 + {
14 + new IntermediateFieldDefinition(nameof(WixBalBootstrapperApplicationSymbolFields.Type), IntermediateFieldType.Number),
15 + },
16 + typeof(WixBalBootstrapperApplicationSymbol));
17 + }
18 +}
19 +
20 +namespace WixToolset.Bal.Symbols
21 +{
22 + using WixToolset.Data;
23 +
24 + public enum WixBalBootstrapperApplicationType
25 + {
26 + Unknown,
27 + Standard,
28 + ManagedHost,
29 + DotNetCoreHost,
30 + InternalUi,
31 + }
32 +
33 + public enum WixBalBootstrapperApplicationSymbolFields
34 + {
35 + Type,
36 + }
37 +
38 + public class WixBalBootstrapperApplicationSymbol : IntermediateSymbol
39 + {
40 + public WixBalBootstrapperApplicationSymbol() : base(BalSymbolDefinitions.WixBalBootstrapperApplication, null, null)
41 + {
42 + }
43 +
44 + public WixBalBootstrapperApplicationSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(BalSymbolDefinitions.WixBalBootstrapperApplication, sourceLineNumber, id)
45 + {
46 + }
47 +
48 + public IntermediateField this[WixBalBootstrapperApplicationSymbolFields index] => this.Fields[(int)index];
49 +
50 + public WixBalBootstrapperApplicationType Type
51 + {
52 + get => (WixBalBootstrapperApplicationType)this.Fields[(int)WixBalBootstrapperApplicationSymbolFields.Type].AsNumber();
53 + set => this.Set((int)WixBalBootstrapperApplicationSymbolFields.Type, (int)value);
54 + }
55 + }
56 +}