@joebigelow / wix / commits / bb40dc8a

Detect duplicate CacheIds

Fixes wixtoolset/issues#4628

Rob Mensching committed Apr 19, 2021 at 15:50 UTC bb40dc8a911ec0679016cbbf7132ea813ea1a3ad
4 files changed +43 -11
src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+25 -2
@@ -359,7 +359,6 @@ namespace WixToolset.Core.Burn
359 this.BackendHelper.ResolveDelayedFields(this.DelayedFields, variableCache);
360 }
361
362 - Dictionary<string, WixDependencyProviderSymbol> dependencySymbolsByKey;
362 {
363 var command = new ProcessDependencyProvidersCommand(this.Messaging, section, facades);
364 command.Execute();
@@ -368,7 +367,6 @@ namespace WixToolset.Core.Burn
367 {
368 bundleSymbol.ProviderKey = command.BundleProviderKey; // set the overridable bundle provider key.
369 }
371 - dependencySymbolsByKey = command.DependencySymbolsByKey;
370 }
371
372 // Update the bundle per-machine/per-user scope based on the chained packages.
@@ -381,6 +379,13 @@ namespace WixToolset.Core.Burn
379 command.Execute();
380 }
381
382 + this.DetectDuplicateCacheIds(facades);
383 +
384 + if (this.Messaging.EncounteredError)
385 + {
386 + return;
387 + }
388 +
389 // Give the extension one last hook before generating the output files.
390 foreach (var extension in this.BackendExtensions)
391 {
@@ -581,6 +586,24 @@ namespace WixToolset.Core.Burn
586 }
587 }
588
589 + private void DetectDuplicateCacheIds(IDictionary<string, PackageFacade> facades)
590 + {
591 + var duplicateCacheIdDetector = new Dictionary<string, WixBundlePackageSymbol>();
592 +
593 + foreach (var facade in facades.Values)
594 + {
595 + if (duplicateCacheIdDetector.TryGetValue(facade.PackageSymbol.CacheId, out var collisionPackage))
596 + {
597 + this.Messaging.Write(BurnBackendErrors.DuplicateCacheIds(collisionPackage.SourceLineNumbers, facade.PackageSymbol.CacheId));
598 + this.Messaging.Write(BurnBackendErrors.DuplicateCacheIds2(facade.PackageSymbol.SourceLineNumbers, facade.PackageSymbol.CacheId));
599 + }
600 + else
601 + {
602 + duplicateCacheIdDetector.Add(facade.PackageSymbol.CacheId, facade.PackageSymbol);
603 + }
604 + }
605 + }
606 +
607 private IEnumerable<T> GetRequiredSymbols<T>() where T : IntermediateSymbol
608 {
609 var symbols = this.Output.Sections.Single().Symbols.OfType<T>().ToList();
src/WixToolset.Core.Burn/BurnBackendErrors.cs
+11 -5
@@ -6,10 +6,15 @@ namespace WixToolset.Core.Burn
6
7 internal static class BurnBackendErrors
8 {
9 - //public static Message ReplaceThisWithTheFirstError(SourceLineNumber sourceLineNumbers)
10 - //{
11 - // return Message(sourceLineNumbers, Ids.ReplaceThisWithTheFirstError, "format string", arg1, arg2);
12 - //}
9 + public static Message DuplicateCacheIds(SourceLineNumber originalLineNumber, string cacheId)
10 + {
11 + return Message(originalLineNumber, Ids.DuplicateCacheIds, "The cache id '{0}' has been duplicated as indicated in the following message.", cacheId);
12 + }
13 +
14 + public static Message DuplicateCacheIds2(SourceLineNumber duplicateLineNumber, string cacheId)
15 + {
16 + return Message(duplicateLineNumber, Ids.DuplicateCacheIds2, "Each cache id must be unique. '{0}' has been used before as indicated in the previous message.", cacheId);
17 + }
18
19 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
20 {
@@ -18,7 +23,8 @@ namespace WixToolset.Core.Burn
23
24 public enum Ids
25 {
21 - // ReplaceThisWithTheFirstError = 8000,
26 + DuplicateCacheIds = 8000,
27 + DuplicateCacheIds2 = 8001,
28 }
29 }
30 }
src/test/WixToolsetTest.CoreIntegration/BundleFixture.cs
+2 -2
@@ -280,7 +280,7 @@ namespace WixToolsetTest.CoreIntegration
280 }
281 }
282
283 - [Fact(Skip = "https://github.com/wixtoolset/issues/issues/4628")]
283 + [Fact]
284 public void CantBuildWithDuplicateCacheIds()
285 {
286 var folder = TestData.Get(@"TestData");
@@ -302,7 +302,7 @@ namespace WixToolsetTest.CoreIntegration
302 "-o", exePath,
303 });
304
305 - Assert.InRange(result.ExitCode, 2, Int32.MaxValue);
305 + Assert.Equal(8001, result.ExitCode);
306 }
307 }
308
src/test/WixToolsetTest.CoreIntegration/TestData/BadInput/DuplicateCacheIds.wxs
+5 -2
@@ -2,8 +2,11 @@
2 <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment>
4 <PackageGroup Id="BundlePackages">
5 - <ExePackage Id="Manual1" SourceFile="burn.exe" Name="manual1\burn.exe" CacheId="Manual" />
6 - <ExePackage Id="Manual2" SourceFile="burn.exe" Name="manual2\burn.exe" CacheId="Manual" />
5 + <ExePackage Id="Manual1" SourceFile="burn.exe" Name="manual1\burn.exe" DetectCondition="test" CacheId="!(wix.WixVariable1)" />
6 + <ExePackage Id="Manual2" SourceFile="burn.exe" Name="manual2\burn.exe" DetectCondition="test" CacheId="!(wix.WixVariable2)" />
7 </PackageGroup>
8 +
9 + <WixVariable Id="WixVariable1" Value="CollidingCacheId" />
10 + <WixVariable Id="WixVariable2" Value="CollidingCacheId" />
11 </Fragment>
12 </Wix>