From 7a0aa56131ba7fa3b63788908c164d0f8118e3fc Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 18 Jan 2023 19:03:44 -0600 Subject: Improve error messages from BalBurnBackendExtension. --- .../test/WixToolsetTest.Bal/BalExtensionFixture.cs | 2 +- src/ext/Bal/wixext/BalBurnBackendExtension.cs | 45 ++++++++++------- src/ext/Bal/wixext/BalCompiler.cs | 15 ++++-- src/ext/Bal/wixext/BalErrors.cs | 14 +++--- src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs | 6 ++- .../Symbols/WixBalBootstrapperApplicationSymbol.cs | 56 ++++++++++++++++++++++ 6 files changed, 105 insertions(+), 33 deletions(-) create mode 100644 src/ext/Bal/wixext/Symbols/WixBalBootstrapperApplicationSymbol.cs (limited to 'src/ext') diff --git a/src/ext/Bal/test/WixToolsetTest.Bal/BalExtensionFixture.cs b/src/ext/Bal/test/WixToolsetTest.Bal/BalExtensionFixture.cs index 57dbda9c..2e60e2c0 100644 --- a/src/ext/Bal/test/WixToolsetTest.Bal/BalExtensionFixture.cs +++ b/src/ext/Bal/test/WixToolsetTest.Bal/BalExtensionFixture.cs @@ -204,7 +204,7 @@ namespace WixToolsetTest.Bal }); WixAssert.CompareLineByLine(new[] { - "The BA's entry point DLL must have bal:BAFactoryAssembly=\"yes\" when using the DotNetCoreBootstrapperApplicationHost.", + "When using DotNetCoreBootstrapperApplicationHost, the Payload element for the BA's entry point DLL must have bal:BAFactoryAssembly=\"yes\".", }, compileResult.Messages.Select(x => x.ToString()).ToArray()); Assert.Equal(6818, compileResult.ExitCode); diff --git a/src/ext/Bal/wixext/BalBurnBackendExtension.cs b/src/ext/Bal/wixext/BalBurnBackendExtension.cs index be294131..0293b236 100644 --- a/src/ext/Bal/wixext/BalBurnBackendExtension.cs +++ b/src/ext/Bal/wixext/BalBurnBackendExtension.cs @@ -86,6 +86,11 @@ namespace WixToolset.Bal return true; } + else if (symbol is WixBalBootstrapperApplicationSymbol) + { + // This symbol is only for the processing in SymbolsFinalized. + return true; + } else { return base.TryProcessSymbol(section, symbol); @@ -100,28 +105,33 @@ namespace WixToolset.Bal this.VerifyDisplayInternalUICondition(section); this.VerifyOverridableVariables(section); - var baSymbol = section.Symbols.OfType().SingleOrDefault(); - var baId = baSymbol?.Id?.Id; - if (null == baId) + var balBaSymbol = section.Symbols.OfType().SingleOrDefault(); + if (balBaSymbol == null) { return; } - var isIuiBA = baId.StartsWith("WixInternalUIBootstrapperApplication"); - var isStdBA = baId.StartsWith("WixStandardBootstrapperApplication"); - var isMBA = baId.StartsWith("WixManagedBootstrapperApplicationHost"); - var isDNC = baId.StartsWith("WixDotNetCoreBootstrapperApplicationHost"); + var isIuiBA = balBaSymbol.Type == WixBalBootstrapperApplicationType.InternalUi; + var isStdBA = balBaSymbol.Type == WixBalBootstrapperApplicationType.Standard; + var isMBA = balBaSymbol.Type == WixBalBootstrapperApplicationType.ManagedHost; + var isDNC = balBaSymbol.Type == WixBalBootstrapperApplicationType.DotNetCoreHost; var isSCD = isDNC && this.VerifySCD(section); + + if (!isIuiBA && !isStdBA && !isMBA && !isDNC) + { + throw new WixException($"Invalid WixBalBootstrapperApplicationType: '{balBaSymbol.Type}'"); + } + if (isIuiBA) { // This needs to happen before VerifyPrereqPackages because it can add prereq packages. - this.VerifyPrimaryPackages(section); + this.VerifyPrimaryPackages(section, balBaSymbol.SourceLineNumbers); } if (isDNC) { - this.FinalizeBAFactorySymbol(section, baSymbol); + this.FinalizeBAFactorySymbol(section, balBaSymbol.SourceLineNumbers); } if (isIuiBA || isStdBA || isMBA || isDNC) @@ -131,16 +141,16 @@ namespace WixToolset.Bal if (isIuiBA || isMBA || (isDNC && !isSCD)) { - this.VerifyPrereqPackages(section, isDNC, isIuiBA); + this.VerifyPrereqPackages(section, balBaSymbol.SourceLineNumbers, isDNC, isIuiBA); } } - private void FinalizeBAFactorySymbol(IntermediateSection section, WixBootstrapperApplicationDllSymbol baSymbol) + private void FinalizeBAFactorySymbol(IntermediateSection section, SourceLineNumber baSourceLineNumbers) { var factorySymbol = section.Symbols.OfType().SingleOrDefault(); if (null == factorySymbol) { - this.Messaging.Write(BalErrors.MissingDNCBAFactoryAssembly(baSymbol.SourceLineNumbers)); + this.Messaging.Write(BalErrors.MissingDNCBAFactoryAssembly(baSourceLineNumbers)); return; } @@ -149,8 +159,7 @@ namespace WixToolset.Bal .SingleOrDefault(); if (null == factoryPayloadSymbol) { - this.Messaging.Write(BalErrors.MissingDNCBAFactoryAssembly(factorySymbol.SourceLineNumbers)); - return; + throw new WixException($"Missing payload symbol with id: 'factorySymbol.PayloadId'"); } factorySymbol.FilePath = factoryPayloadSymbol.Name; @@ -216,7 +225,7 @@ namespace WixToolset.Bal } } - private void VerifyPrimaryPackages(IntermediateSection section) + private void VerifyPrimaryPackages(IntermediateSection section, SourceLineNumber baSourceLineNumbers) { WixBalPackageInfoSymbol defaultPrimaryPackage = null; WixBalPackageInfoSymbol x86PrimaryPackage = null; @@ -398,7 +407,7 @@ namespace WixToolset.Bal } else if (defaultPrimaryPackage == null) { - this.Messaging.Write(BalErrors.MissingIUIPrimaryPackage()); + this.Messaging.Write(BalErrors.MissingIUIPrimaryPackage(baSourceLineNumbers)); } else { @@ -467,12 +476,12 @@ namespace WixToolset.Bal } } - private void VerifyPrereqPackages(IntermediateSection section, bool isDNC, bool isIuiBA) + private void VerifyPrereqPackages(IntermediateSection section, SourceLineNumber baSourceLineNumbers, bool isDNC, bool isIuiBA) { var prereqInfoSymbols = section.Symbols.OfType().ToList(); if (!isIuiBA && prereqInfoSymbols.Count == 0) { - var message = isDNC ? BalErrors.MissingDNCPrereq() : BalErrors.MissingMBAPrereq(); + var message = isDNC ? BalErrors.MissingDNCPrereq(baSourceLineNumbers) : BalErrors.MissingMBAPrereq(baSourceLineNumbers); this.Messaging.Write(message); return; } diff --git a/src/ext/Bal/wixext/BalCompiler.cs b/src/ext/Bal/wixext/BalCompiler.cs index bd2fb4a2..731943ee 100644 --- a/src/ext/Bal/wixext/BalCompiler.cs +++ b/src/ext/Bal/wixext/BalCompiler.cs @@ -581,7 +581,7 @@ namespace WixToolset.Bal break; } - this.CreateBARef(section, sourceLineNumbers, node, baId); + this.CreateBARef(section, sourceLineNumbers, node, baId, WixBalBootstrapperApplicationType.InternalUi); } } @@ -860,7 +860,7 @@ namespace WixToolset.Bal break; } - this.CreateBARef(section, sourceLineNumbers, node, baId); + this.CreateBARef(section, sourceLineNumbers, node, baId, WixBalBootstrapperApplicationType.Standard); } } @@ -963,7 +963,7 @@ namespace WixToolset.Bal break; } - this.CreateBARef(section, sourceLineNumbers, node, baId); + this.CreateBARef(section, sourceLineNumbers, node, baId, WixBalBootstrapperApplicationType.ManagedHost); if (alwaysInstallPrereqs) { @@ -1086,7 +1086,7 @@ namespace WixToolset.Bal break; } - this.CreateBARef(section, sourceLineNumbers, node, baId); + this.CreateBARef(section, sourceLineNumbers, node, baId, WixBalBootstrapperApplicationType.DotNetCoreHost); if (alwaysInstallPrereqs) { @@ -1098,7 +1098,7 @@ namespace WixToolset.Bal } } - private void CreateBARef(IntermediateSection section, SourceLineNumber sourceLineNumbers, XElement node, string name) + private void CreateBARef(IntermediateSection section, SourceLineNumber sourceLineNumbers, XElement node, string name, WixBalBootstrapperApplicationType baType) { var id = this.ParseHelper.CreateIdentifierValueFromPlatform(name, this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64); if (id == null) @@ -1109,6 +1109,11 @@ namespace WixToolset.Bal if (!this.Messaging.EncounteredError) { this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixBootstrapperApplication, id); + + section.AddSymbol(new WixBalBootstrapperApplicationSymbol(sourceLineNumbers) + { + Type = baType, + }); } } } diff --git a/src/ext/Bal/wixext/BalErrors.cs b/src/ext/Bal/wixext/BalErrors.cs index 2548b279..7fbccecb 100644 --- a/src/ext/Bal/wixext/BalErrors.cs +++ b/src/ext/Bal/wixext/BalErrors.cs @@ -45,22 +45,22 @@ namespace WixToolset.Bal public static Message MissingDNCBAFactoryAssembly(SourceLineNumber sourceLineNumbers) { - return Message(sourceLineNumbers, Ids.MissingDNCBAFactoryAssembly, "The BA's entry point DLL must have bal:BAFactoryAssembly=\"yes\" when using the DotNetCoreBootstrapperApplicationHost."); + return Message(sourceLineNumbers, Ids.MissingDNCBAFactoryAssembly, "When using DotNetCoreBootstrapperApplicationHost, the Payload element for the BA's entry point DLL must have bal:BAFactoryAssembly=\"yes\"."); } - public static Message MissingDNCPrereq() + public static Message MissingDNCPrereq(SourceLineNumber sourceLineNumbers) { - 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\"."); + 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\"."); } - public static Message MissingIUIPrimaryPackage() + public static Message MissingIUIPrimaryPackage(SourceLineNumber sourceLineNumbers) { - return Message(null, Ids.MissingIUIPrimaryPackage, "When using WixInternalUIBootstrapperApplication, there must be one package with bal:PrimaryPackageType=\"default\"."); + return Message(sourceLineNumbers, Ids.MissingIUIPrimaryPackage, "When using WixInternalUIBootstrapperApplication, there must be one package with bal:PrimaryPackageType=\"default\"."); } - public static Message MissingMBAPrereq() + public static Message MissingMBAPrereq(SourceLineNumber sourceLineNumbers) { - 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."); + 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."); } public static Message MultipleBAFunctions(SourceLineNumber sourceLineNumbers) diff --git a/src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs b/src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs index 22375508..5229f278 100644 --- a/src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs +++ b/src/ext/Bal/wixext/Symbols/BalSymbolDefinitions.cs @@ -18,12 +18,11 @@ namespace WixToolset.Bal WixStdbaOptions, WixStdbaOverridableVariable, WixMbaPrereqOptions, + WixBalBootstrapperApplication, } public static partial class BalSymbolDefinitions { - public static readonly Version Version = new Version("4.0.0"); - public static IntermediateSymbolDefinition ByName(string name) { if (!Enum.TryParse(name, out BalSymbolDefinitionType type)) @@ -68,6 +67,9 @@ namespace WixToolset.Bal case BalSymbolDefinitionType.WixMbaPrereqOptions: return BalSymbolDefinitions.WixMbaPrereqOptions; + case BalSymbolDefinitionType.WixBalBootstrapperApplication: + return BalSymbolDefinitions.WixBalBootstrapperApplication; + default: throw new ArgumentOutOfRangeException(nameof(type)); } diff --git a/src/ext/Bal/wixext/Symbols/WixBalBootstrapperApplicationSymbol.cs b/src/ext/Bal/wixext/Symbols/WixBalBootstrapperApplicationSymbol.cs new file mode 100644 index 00000000..7096930d --- /dev/null +++ b/src/ext/Bal/wixext/Symbols/WixBalBootstrapperApplicationSymbol.cs @@ -0,0 +1,56 @@ +// 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. + +namespace WixToolset.Bal +{ + using WixToolset.Data; + using WixToolset.Bal.Symbols; + + public static partial class BalSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition WixBalBootstrapperApplication = new IntermediateSymbolDefinition( + BalSymbolDefinitionType.WixBalBootstrapperApplication.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(WixBalBootstrapperApplicationSymbolFields.Type), IntermediateFieldType.Number), + }, + typeof(WixBalBootstrapperApplicationSymbol)); + } +} + +namespace WixToolset.Bal.Symbols +{ + using WixToolset.Data; + + public enum WixBalBootstrapperApplicationType + { + Unknown, + Standard, + ManagedHost, + DotNetCoreHost, + InternalUi, + } + + public enum WixBalBootstrapperApplicationSymbolFields + { + Type, + } + + public class WixBalBootstrapperApplicationSymbol : IntermediateSymbol + { + public WixBalBootstrapperApplicationSymbol() : base(BalSymbolDefinitions.WixBalBootstrapperApplication, null, null) + { + } + + public WixBalBootstrapperApplicationSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(BalSymbolDefinitions.WixBalBootstrapperApplication, sourceLineNumber, id) + { + } + + public IntermediateField this[WixBalBootstrapperApplicationSymbolFields index] => this.Fields[(int)index]; + + public WixBalBootstrapperApplicationType Type + { + get => (WixBalBootstrapperApplicationType)this.Fields[(int)WixBalBootstrapperApplicationSymbolFields.Type].AsNumber(); + set => this.Set((int)WixBalBootstrapperApplicationSymbolFields.Type, (int)value); + } + } +} -- cgit v1.2.3-55-g6feb