Skip to content

Commit

Permalink
move package correlator to common location
Browse files Browse the repository at this point in the history
  • Loading branch information
brettfo committed Dec 19, 2024
1 parent 6d1dfab commit 9521d2f
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ namespace DotNetPackageCorrelation;

public class PackageMapper
{
private readonly RuntimePackages _runtimePackages;
public RuntimePackages RuntimePackages { get; }

private PackageMapper(RuntimePackages runtimePackages)
{
_runtimePackages = runtimePackages;
RuntimePackages = runtimePackages;
}

/// <summary>
Expand All @@ -24,15 +24,15 @@ private PackageMapper(RuntimePackages runtimePackages)
return null;
}

var candidateRuntimeVersions = _runtimePackages.Runtimes.Keys
var candidateRuntimeVersions = RuntimePackages.Runtimes.Keys
.Where(v => v.Major == runtimeVersion.Major)
.Where(v => v.ComparePrecedenceTo(runtimeVersion) <= 0)
.OrderBy(v => v, SemVerComparer.Instance)
.Reverse()
.ToArray();
foreach (var candidateRuntimeVersion in candidateRuntimeVersions)
{
if (!_runtimePackages.Runtimes.TryGetValue(candidateRuntimeVersion, out var packageSet))
if (!RuntimePackages.Runtimes.TryGetValue(candidateRuntimeVersion, out var packageSet))
{
continue;
}
Expand All @@ -49,7 +49,7 @@ private PackageMapper(RuntimePackages runtimePackages)
private SemVersion? GetRuntimeVersionFromPackage(string packageName, SemVersion packageVersion)
{
// TODO: linear search is slow
foreach (var runtime in _runtimePackages.Runtimes)
foreach (var runtime in RuntimePackages.Runtimes)
{
if (runtime.Value.Packages.TryGetValue(packageName, out var foundPackageVersion) &&
foundPackageVersion == packageVersion)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
using System.Collections.Immutable;
using System.Reflection;
using System.Text.Json;
using System.Xml.Linq;
using System.Xml.XPath;

using DotNetPackageCorrelation;

using Microsoft.Build.Logging.StructuredLogger;

using NuGet.Versioning;
Expand All @@ -20,16 +17,6 @@ namespace NuGetUpdater.Core.Discover;

internal static class SdkProjectDiscovery
{
private static readonly PackageMapper _packageMapper;
private static readonly Dictionary<string, PackageMapper> _packageMapperByOverrideFile = new();

static SdkProjectDiscovery()
{
var packageCorrelationPath = Path.Combine(Path.GetDirectoryName(typeof(SdkProjectDiscovery).Assembly.Location)!, "dotnet-package-correlation.json");
var runtimePackages = LoadRuntimePackagesFromFile(packageCorrelationPath);
_packageMapper = PackageMapper.Load(runtimePackages);
}

private static readonly HashSet<string> TopLevelPackageItemNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"PackageReference"
Expand Down Expand Up @@ -252,7 +239,7 @@ public static async Task<ImmutableArray<ProjectDiscoveryResult>> DiscoverWithBin
runtimePackageVersion is not null &&
SemVersion.TryParse(runtimePackageVersion, out var parsedRuntimePackageVersion))
{
var packageMapper = GetPackageMapper();
var packageMapper = DotNetPackageCorrelationManager.GetPackageMapper();
var replacementPackageVersion = packageMapper.GetPackageVersionThatShippedWithOtherPackage(runtimePackageName, parsedRuntimePackageVersion, removedPackageName);
if (replacementPackageVersion is not null)
{
Expand Down Expand Up @@ -378,32 +365,6 @@ runtimePackageVersion is not null &&
return projectDiscoveryResults;
}

private static PackageMapper GetPackageMapper()
{
var packageCorrelationFileOverride = Environment.GetEnvironmentVariable("DOTNET_PACKAGE_CORRELATION_FILE_PATH");
if (packageCorrelationFileOverride is not null)
{
// this is used as a test hook to allow unit tests to be SDK agnostic
if (_packageMapperByOverrideFile.TryGetValue(packageCorrelationFileOverride, out var packageMapper))
{
return packageMapper;
}

var runtimePackages = LoadRuntimePackagesFromFile(packageCorrelationFileOverride);
packageMapper = PackageMapper.Load(runtimePackages);
_packageMapperByOverrideFile[packageCorrelationFileOverride] = packageMapper;
return packageMapper;
}

return _packageMapper;
}

private static RuntimePackages LoadRuntimePackagesFromFile(string filePath)
{
var packageCorrelationJson = File.ReadAllText(filePath);
return JsonSerializer.Deserialize<RuntimePackages>(packageCorrelationJson, Correlator.SerializerOptions)!;
}

private static void ProcessResolvedPackageReference(
NamedNode node,
Dictionary<string, Dictionary<string, Dictionary<string, string>>> packagesPerProject, // projectPath -> tfm -> (packageName, packageVersion)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

using NuGet.Versioning;

using NuGetUpdater.Core.Utilities;

namespace NuGetUpdater.Core;

/// <summary>
Expand Down Expand Up @@ -36,6 +38,25 @@ public static async Task UpdateDependencyAsync(

// Get the set of all top-level dependencies in the current project
var topLevelDependencies = MSBuildHelper.GetTopLevelPackageDependencyInfos(buildFiles).ToArray();
var isDependencyTopLevel = topLevelDependencies.Any(d => d.Name.Equals(dependencyName, StringComparison.OrdinalIgnoreCase));
if (isDependencyTopLevel)
{
var packageMapper = DotNetPackageCorrelationManager.GetPackageMapper();
// TODO: this is slow
var isSdkReplacementPackage = packageMapper.RuntimePackages.Runtimes.Any(r =>
{
return r.Value.Packages.Any(p => dependencyName.Equals(p.Key, StringComparison.Ordinal));
});
if (isSdkReplacementPackage)
{
// If we're updating a top level SDK replacement package, the version listed in the project file won't
// necessarily match the resolved version that caused the update because the SDK might have replaced
// the package. To handle this scenario, we pretend the version we're searching for is the actual
// version in the file, not the resolved version. This allows us to keep a strict equality check when
// finding the file to update.
previousDependencyVersion = topLevelDependencies.First(d => d.Name.Equals(dependencyName, StringComparison.OrdinalIgnoreCase)).Version!;
}
}

if (!await DoesDependencyRequireUpdateAsync(repoRootPath, projectPath, tfms, topLevelDependencies, dependencyName, newDependencyVersion, experimentsManager, logger))
{
Expand Down Expand Up @@ -95,11 +116,6 @@ public static async Task UpdateDependencyWithConflictResolution(
var dependenciesToUpdate = new[] { new Dependency(dependencyName, newDependencyVersion, DependencyType.PackageReference) };

// update the initial dependency...
if (isDependencyTopLevel)
{
// TODO: is SDK replacement package
previousDependencyVersion = topLevelDependencies.First(d => d.Name.Equals(dependencyName, StringComparison.OrdinalIgnoreCase)).Version!;
}
TryUpdateDependencyVersion(buildFiles, dependencyName, previousDependencyVersion, newDependencyVersion, logger);

// ...and the peer dependencies...
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Text.Json;

using DotNetPackageCorrelation;

using NuGetUpdater.Core.Discover;

namespace NuGetUpdater.Core.Utilities;

internal static class DotNetPackageCorrelationManager
{
private static readonly PackageMapper _packageMapper;
private static readonly Dictionary<string, PackageMapper> _packageMapperByOverrideFile = new();

static DotNetPackageCorrelationManager()
{
var packageCorrelationPath = Path.Combine(Path.GetDirectoryName(typeof(SdkProjectDiscovery).Assembly.Location)!, "dotnet-package-correlation.json");
var runtimePackages = LoadRuntimePackagesFromFile(packageCorrelationPath);
_packageMapper = PackageMapper.Load(runtimePackages);
}

public static PackageMapper GetPackageMapper()
{
var packageCorrelationFileOverride = Environment.GetEnvironmentVariable("DOTNET_PACKAGE_CORRELATION_FILE_PATH");
if (packageCorrelationFileOverride is not null)
{
// this is used as a test hook to allow unit tests to be SDK agnostic
if (_packageMapperByOverrideFile.TryGetValue(packageCorrelationFileOverride, out var packageMapper))
{
return packageMapper;
}

var runtimePackages = LoadRuntimePackagesFromFile(packageCorrelationFileOverride);
packageMapper = PackageMapper.Load(runtimePackages);
_packageMapperByOverrideFile[packageCorrelationFileOverride] = packageMapper;
return packageMapper;
}

return _packageMapper;
}

private static RuntimePackages LoadRuntimePackagesFromFile(string filePath)
{
var packageCorrelationJson = File.ReadAllText(filePath);
return JsonSerializer.Deserialize<RuntimePackages>(packageCorrelationJson, Correlator.SerializerOptions)!;
}
}

0 comments on commit 9521d2f

Please sign in to comment.