Handle duplicated assemblies in binding redirects
This commit is contained in:
parent
ac4c6702d5
commit
e844355d7a
4 changed files with 93 additions and 14 deletions
|
@ -34,7 +34,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
|
|
||||||
private static SHA1 Sha1 { get; } = SHA1.Create();
|
private static SHA1 Sha1 { get; } = SHA1.Create();
|
||||||
|
|
||||||
internal static XDocument GenerateBindingRedirects(this IEnumerable<LibraryExport> dependencies, XDocument document)
|
public static XDocument GenerateBindingRedirects(this IEnumerable<LibraryExport> dependencies, XDocument document)
|
||||||
{
|
{
|
||||||
var redirects = CollectRedirects(dependencies);
|
var redirects = CollectRedirects(dependencies);
|
||||||
|
|
||||||
|
@ -107,23 +107,34 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AssemblyRedirect[] CollectRedirects(IEnumerable<LibraryExport> dependencies)
|
internal static AssemblyRedirect[] CollectRedirects(IEnumerable<LibraryExport> dependencies)
|
||||||
{
|
{
|
||||||
var allRuntimeAssemblies = dependencies
|
var runtimeAssemblies = dependencies
|
||||||
.SelectMany(d => d.RuntimeAssemblyGroups.GetDefaultAssets())
|
.SelectMany(d => d.RuntimeAssemblyGroups.GetDefaultAssets())
|
||||||
.Select(GetAssemblyInfo)
|
.Select(GetAssemblyInfo);
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
var assemblyLookup = allRuntimeAssemblies.ToDictionary(r => r.Identity.ToLookupKey());
|
return CollectRedirects(runtimeAssemblies);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static AssemblyRedirect[] CollectRedirects(IEnumerable<AssemblyReferenceInfo> runtimeAssemblies)
|
||||||
|
{
|
||||||
|
var assemblyLookup = runtimeAssemblies.ToLookup(r => r.Identity.ToLookupKey());
|
||||||
|
|
||||||
var redirectAssemblies = new HashSet<AssemblyRedirect>();
|
var redirectAssemblies = new HashSet<AssemblyRedirect>();
|
||||||
foreach (var assemblyReferenceInfo in allRuntimeAssemblies)
|
foreach (var assemblyReferenceInfo in assemblyLookup)
|
||||||
{
|
{
|
||||||
foreach (var referenceIdentity in assemblyReferenceInfo.References)
|
// Using .First here is not exactly valid, but we don't know which one gets copied to
|
||||||
|
// output so we just use first
|
||||||
|
var references = assemblyReferenceInfo.First().References;
|
||||||
|
foreach (var referenceIdentity in references)
|
||||||
{
|
{
|
||||||
AssemblyReferenceInfo targetAssemblyIdentity;
|
var targetAssemblies = assemblyLookup[referenceIdentity.ToLookupKey()];
|
||||||
if (assemblyLookup.TryGetValue(referenceIdentity.ToLookupKey(), out targetAssemblyIdentity)
|
if (!targetAssemblies.Any())
|
||||||
&& targetAssemblyIdentity.Identity.Version != referenceIdentity.Version)
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var targetAssemblyIdentity = targetAssemblies.First();
|
||||||
|
if (targetAssemblyIdentity.Identity.Version != referenceIdentity.Version)
|
||||||
{
|
{
|
||||||
if (targetAssemblyIdentity.Identity.PublicKeyToken != null)
|
if (targetAssemblyIdentity.Identity.PublicKeyToken != null)
|
||||||
{
|
{
|
||||||
|
@ -200,7 +211,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
return hex.ToString();
|
return hex.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct AssemblyRedirect
|
internal struct AssemblyRedirect
|
||||||
{
|
{
|
||||||
public AssemblyRedirect(AssemblyIdentity from, AssemblyIdentity to)
|
public AssemblyRedirect(AssemblyIdentity from, AssemblyIdentity to)
|
||||||
{
|
{
|
||||||
|
@ -213,7 +224,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
public AssemblyIdentity To { get; set; }
|
public AssemblyIdentity To { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct AssemblyIdentity
|
internal struct AssemblyIdentity
|
||||||
{
|
{
|
||||||
public AssemblyIdentity(string name, Version version, string culture, string publicKeyToken)
|
public AssemblyIdentity(string name, Version version, string culture, string publicKeyToken)
|
||||||
{
|
{
|
||||||
|
@ -239,7 +250,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct AssemblyReferenceInfo
|
internal struct AssemblyReferenceInfo
|
||||||
{
|
{
|
||||||
public AssemblyReferenceInfo(AssemblyIdentity identity, AssemblyIdentity[] references)
|
public AssemblyReferenceInfo(AssemblyIdentity identity, AssemblyIdentity[] references)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("dotnet-compile.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
|
@ -0,0 +1,59 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.DotNet.Cli.Compiler.Common;
|
||||||
|
using Xunit;
|
||||||
|
using FluentAssertions;
|
||||||
|
|
||||||
|
using AssemblyReferenceInfo = Microsoft.DotNet.Cli.Compiler.Common.BindingRedirectGenerator.AssemblyReferenceInfo;
|
||||||
|
using AssemblyIdentity = Microsoft.DotNet.Cli.Compiler.Common.BindingRedirectGenerator.AssemblyIdentity;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Tools.Compiler.Tests
|
||||||
|
{
|
||||||
|
public class BindingRedirectGeneratorTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void ResolvesDuplicatesUsingFirstOccurence()
|
||||||
|
{
|
||||||
|
var hash = "01234qwerty";
|
||||||
|
var redirects = BindingRedirectGenerator.CollectRedirects(new[]
|
||||||
|
{
|
||||||
|
new AssemblyReferenceInfo(
|
||||||
|
new AssemblyIdentity("A", new Version(1, 5), "en-US", hash),
|
||||||
|
new []
|
||||||
|
{
|
||||||
|
new AssemblyIdentity("B", new Version(1, 1), "en-US", hash),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
new AssemblyReferenceInfo(
|
||||||
|
new AssemblyIdentity("B", new Version(1, 4), "en-US", hash), new AssemblyIdentity[] {}
|
||||||
|
),
|
||||||
|
new AssemblyReferenceInfo(
|
||||||
|
new AssemblyIdentity("B", new Version(1, 5), "en-US", hash), new AssemblyIdentity[] {}
|
||||||
|
),
|
||||||
|
new AssemblyReferenceInfo(
|
||||||
|
new AssemblyIdentity("C", new Version(1, 5), "en-US", hash),
|
||||||
|
new []
|
||||||
|
{
|
||||||
|
new AssemblyIdentity("B", new Version(1, 3), "en-US", hash),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
redirects.Should().HaveCount(2);
|
||||||
|
redirects.Should().Contain(r =>
|
||||||
|
r.From.Version == new Version(1, 1) &&
|
||||||
|
r.From.Name == "B" &&
|
||||||
|
r.To.Version == new Version(1, 4) &&
|
||||||
|
r.To.Name == "B"
|
||||||
|
);
|
||||||
|
redirects.Should().Contain(r =>
|
||||||
|
r.From.Version == new Version(1, 3) &&
|
||||||
|
r.From.Name == "B" &&
|
||||||
|
r.To.Version == new Version(1, 4) &&
|
||||||
|
r.To.Name == "B"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,15 @@
|
||||||
{
|
{
|
||||||
"version": "1.0.0-*",
|
"version": "1.0.0-*",
|
||||||
|
"compilationOptions": {
|
||||||
|
"keyFile": "../../tools/Key.snk"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.DotNet.Cli.Utils": {
|
"Microsoft.DotNet.Cli.Utils": {
|
||||||
"target": "project"
|
"target": "project"
|
||||||
},
|
},
|
||||||
|
"Microsoft.DotNet.Compiler.Common": {
|
||||||
|
"target": "project"
|
||||||
|
},
|
||||||
"dotnet": {
|
"dotnet": {
|
||||||
"target": "project"
|
"target": "project"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue