Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove forced override of package contents #1156

Merged
merged 4 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -460,14 +460,58 @@ await PackageExtractor.ExtractPackageAsync(
}
}

// Prefer assemblies from the reference assembly package to ones otherwise provided
// Prefer newer assemblies when more than one have the same name
if (ReferenceAssemblyPackage is not null)
{
var referenceAssemblies = new HashSet<string>(resolvedAssemblies.Where(resolved => resolved.StartsWith(referenceAssemblyInstalledPath!)));
var comparer = new FrameworkPrecedenceSorter(DefaultFrameworkNameProvider.Instance, allEquivalent: false);
var assembliesByName = resolvedAssemblies.GroupBy(Path.GetFileNameWithoutExtension, StringComparer.OrdinalIgnoreCase);

// Suppression due to https://github.com/dotnet/roslyn/issues/44735
var referenceAssemblyNames = new HashSet<string>(referenceAssemblies.Select((Func<string, string>)Path.GetFileNameWithoutExtension!));
resolvedAssemblies.RemoveWhere(resolved => referenceAssemblyNames.Contains(Path.GetFileNameWithoutExtension(resolved)) && !referenceAssemblies.Contains(resolved));
// Keep track of assemblies to remove from resolvedAssemblies. Defer the actual removal to the end
// of this block for ease in future debugging scenarios.
var assembliesToRemove = new List<string>();
foreach (var assemblyNameGroup in assembliesByName)
{
var assembliesByPrecedence = assemblyNameGroup
.Select(static name => (name, framework: GetFrameworkNameFromPath(name)))
.OrderBy(static x => x.framework, comparer)
.ThenByDescending(static x => x.framework, new NuGetFrameworkSorter())
.ToArray();
for (var i = 1; i < assembliesByPrecedence.Length; i++)
{
// We want to keep the last reference listed for the most recent supported target framework.
// Typically, if more than one item has the most recent supported target framework, it will
// be a case where the reference assembly package provides the assembly and a newer version
// is provided explicitly. For example:
//
// Microsoft.NETCore.App.Ref 6.0.0 provides System.Collections.Immutable in the net6.0 folder
// System.Collections.Immutable 8.0.0 provides System.Collections.Immutable in the net6.0 folder
//
// In this example, the Microsoft.NETCore.App.Ref package is resolved first, so by taking
// the last net6.0 assembly, we ensure the assembly from System.Collections.Immutable 8.0.0
// is resolved.
if (Equals(assembliesByPrecedence[0].framework, assembliesByPrecedence[i].framework))
{
assembliesToRemove.Add(assembliesByPrecedence[i - 1].name);
}
else
{
assembliesToRemove.Add(assembliesByPrecedence[i].name);
}
}

static NuGetFramework GetFrameworkNameFromPath(string path)
{
var frameworkFolder = Path.GetFileName(Path.GetDirectoryName(path));
if (frameworkFolder is null)
{
return NuGetFramework.UnsupportedFramework;
}

return NuGetFramework.ParseFolder(frameworkFolder);
}
}

resolvedAssemblies.ExceptWith(assembliesToRemove);
}

// Add the facade assemblies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
Expand Down Expand Up @@ -649,6 +650,37 @@ class TestClass {
}.RunAsync();
}

[Theory]
[InlineData("net462")]
[InlineData("net47")]
[InlineData("net471")]
[InlineData("net472")]
[InlineData("net48")]
#if !(NETCOREAPP1_1 || NET46)
[InlineData("net6.0")]
[InlineData("net7.0")]
[InlineData("net8.0")]
#endif
[InlineData("netstandard2.0")]
[InlineData("netstandard2.1")]
public async Task ResolveSystemCollectionsImmutable8(string targetFramework)
{
var testCode = @"
using System.Collections.Frozen;

class TestClass {
FrozenSet<int> TestMethod() => throw null;
}
";

await new CSharpTest()
{
TestCode = testCode,
ReferenceAssemblies = ReferenceAssembliesForTargetFramework(targetFramework)
.AddPackages(ImmutableArray.Create(new PackageIdentity("System.Collections.Immutable", "8.0.0"))),
}.RunAsync();
}

internal static ReferenceAssemblies ReferenceAssembliesForTargetFramework(string targetFramework)
{
return targetFramework switch
Expand Down