@joebigelow / wix / commits / 86b7ea7a

Move validate guids to a command and execute it earlier

Rob Mensching committed Jun 12, 2020 at 12:46 UTC 86b7ea7a411813e03a2b238ca5c24fcebc947209
2 files changed +68 -44
src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+5 -44
@@ -319,6 +319,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
319 command.Execute();
320 }
321
322 + {
323 + var command = new ValidateComponentGuidsCommand(this.Messaging, section);
324 + command.Execute();
325 + }
326 +
327 // Add missing CreateFolder tuples to null-keypath components.
328 {
329 var command = new AddCreateFoldersCommand(section);
@@ -407,8 +412,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
412 }
413 #endif
414
410 - this.ValidateComponentGuids(output);
411 -
415 // Stop processing if an error previously occurred.
416 if (this.Messaging.EncounteredError)
417 {
@@ -579,48 +582,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
582 return wixout;
583 }
584
582 - /// <summary>
583 - /// Validate that there are no duplicate GUIDs in the output.
584 - /// </summary>
585 - /// <remarks>
586 - /// Duplicate GUIDs without conditions are an error condition; with conditions, it's a
587 - /// warning, as the conditions might be mutually exclusive.
588 - /// </remarks>
589 - private void ValidateComponentGuids(WindowsInstallerData output)
590 - {
591 - if (output.TryGetTable("Component", out var componentTable))
592 - {
593 - var componentGuidConditions = new Dictionary<string, bool>(componentTable.Rows.Count);
594 -
595 - foreach (Data.WindowsInstaller.Rows.ComponentRow row in componentTable.Rows)
596 - {
597 - // We don't care about unmanaged components and if there's a * GUID remaining,
598 - // there's already an error that prevented it from being replaced with a real GUID.
599 - if (!String.IsNullOrEmpty(row.Guid) && "*" != row.Guid)
600 - {
601 - var thisComponentHasCondition = !String.IsNullOrEmpty(row.Condition);
602 - var allComponentsHaveConditions = thisComponentHasCondition;
603 -
604 - if (componentGuidConditions.ContainsKey(row.Guid))
605 - {
606 - allComponentsHaveConditions = thisComponentHasCondition && componentGuidConditions[row.Guid];
607 -
608 - if (allComponentsHaveConditions)
609 - {
610 - this.Messaging.Write(WarningMessages.DuplicateComponentGuidsMustHaveMutuallyExclusiveConditions(row.SourceLineNumbers, row.Component, row.Guid));
611 - }
612 - else
613 - {
614 - this.Messaging.Write(ErrorMessages.DuplicateComponentGuids(row.SourceLineNumbers, row.Component, row.Guid));
615 - }
616 - }
617 -
618 - componentGuidConditions[row.Guid] = allComponentsHaveConditions;
619 - }
620 - }
621 - }
622 - }
623 -
585 private string ResolveMedia(MediaTuple media, string mediaLayoutDirectory, string layoutDirectory)
586 {
587 string layout = null;
src/WixToolset.Core.WindowsInstaller/Bind/ValidateComponentGuidsCommand.cs new
+63
@@ -0,0 +1,63 @@
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.WindowsInstaller.Bind
4 +{
5 + using System;
6 + using System.Collections.Generic;
7 + using System.Linq;
8 + using WixToolset.Data;
9 + using WixToolset.Data.Tuples;
10 + using WixToolset.Extensibility.Services;
11 +
12 + /// <summary>
13 + /// Validate that there are no duplicate GUIDs in the output.
14 + /// </summary>
15 + /// <remarks>
16 + /// Duplicate GUIDs without conditions are an error condition; with conditions, it's a
17 + /// warning, as the conditions might be mutually exclusive.
18 + /// </remarks>
19 + internal class ValidateComponentGuidsCommand
20 + {
21 + internal ValidateComponentGuidsCommand(IMessaging messaging, IntermediateSection section)
22 + {
23 + this.Messaging = messaging;
24 + this.Section = section;
25 + }
26 +
27 + private IMessaging Messaging { get; }
28 +
29 + private IntermediateSection Section { get; }
30 +
31 + public void Execute()
32 + {
33 + var componentGuidConditions = new Dictionary<string, bool>();
34 +
35 + foreach (var componentTuple in this.Section.Tuples.OfType<ComponentTuple>())
36 + {
37 + // We don't care about unmanaged components and if there's a * GUID remaining,
38 + // there's already an error that prevented it from being replaced with a real GUID.
39 + if (!String.IsNullOrEmpty(componentTuple.ComponentId) && "*" != componentTuple.ComponentId)
40 + {
41 + var thisComponentHasCondition = !String.IsNullOrEmpty(componentTuple.Condition);
42 + var allComponentsHaveConditions = thisComponentHasCondition;
43 +
44 + if (componentGuidConditions.TryGetValue(componentTuple.ComponentId, out var alreadyCheckedCondition))
45 + {
46 + allComponentsHaveConditions = thisComponentHasCondition && alreadyCheckedCondition;
47 +
48 + if (allComponentsHaveConditions)
49 + {
50 + this.Messaging.Write(WarningMessages.DuplicateComponentGuidsMustHaveMutuallyExclusiveConditions(componentTuple.SourceLineNumbers, componentTuple.Id.Id, componentTuple.ComponentId));
51 + }
52 + else
53 + {
54 + this.Messaging.Write(ErrorMessages.DuplicateComponentGuids(componentTuple.SourceLineNumbers, componentTuple.Id.Id, componentTuple.ComponentId));
55 + }
56 + }
57 +
58 + componentGuidConditions[componentTuple.ComponentId] = allComponentsHaveConditions;
59 + }
60 + }
61 + }
62 + }
63 +}