Skip to content
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
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

<Project>
<PropertyGroup>
<Version>4.1.2</Version>
<Version>4.1.3</Version>
<LangVersion>preview</LangVersion>
<NoWarn>NU1608</NoWarn>
<AssemblyVersion>1.0.0</AssemblyVersion>
Expand Down
4 changes: 3 additions & 1 deletion src/PackageUpdate/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
global using System.Xml;
global using System.Collections.Concurrent;
global using System.Diagnostics;
global using System.Xml;
global using System.Xml.Linq;
global using CommandLine;
global using NuGet.Common;
Expand Down
14 changes: 14 additions & 0 deletions src/PackageUpdate/PackageCacheKeyComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
sealed class PackageCacheKeyComparer :
IEqualityComparer<(string Package, NuGetVersion Version)>
{
public static PackageCacheKeyComparer Instance { get; } = new();

public bool Equals((string Package, NuGetVersion Version) x, (string Package, NuGetVersion Version) y) =>
string.Equals(x.Package, y.Package, StringComparison.OrdinalIgnoreCase) &&
EqualityComparer<NuGetVersion>.Default.Equals(x.Version, y.Version);

public int GetHashCode((string Package, NuGetVersion Version) obj) =>
HashCode.Combine(
StringComparer.OrdinalIgnoreCase.GetHashCode(obj.Package),
EqualityComparer<NuGetVersion>.Default.GetHashCode(obj.Version));
}
5 changes: 5 additions & 0 deletions src/PackageUpdate/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ static async Task Inner(string directory, string? package, bool build)
Environment.Exit(1);
}

var totalStopwatch = Stopwatch.StartNew();
using var cache = new SourceCacheContext
{
RefreshMemoryCache = true
Expand All @@ -28,6 +29,8 @@ static async Task Inner(string directory, string? package, bool build)
{
await DotnetStarter.Shutdown();
}

Log.Information("Completed in {Elapsed}", totalStopwatch.Elapsed);
}

static async Task TryProcessSolution(SourceCacheContext cache, string solution, string? package, bool build)
Expand Down Expand Up @@ -67,7 +70,9 @@ static async Task ProcessSolution(SourceCacheContext cache, string solution, str
return;
}

var stopwatch = Stopwatch.StartNew();
await Updater.Update(cache, props, package);
Log.Information(" Updated in {Elapsed}", stopwatch.Elapsed);

if (build)
{
Expand Down
18 changes: 18 additions & 0 deletions src/PackageUpdate/Updater.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
public static class Updater
{
static ConcurrentDictionary<(string Package, NuGetVersion Version), IPackageSearchMetadata?> metadataCache = new(PackageCacheKeyComparer.Instance);
static ConcurrentDictionary<(string Package, NuGetVersion CurrentVersion), IPackageSearchMetadata?> latestVersionCache = new(PackageCacheKeyComparer.Instance);

public static async Task Update(
SourceCacheContext cache,
string directoryPackagesPropsPath,
Expand Down Expand Up @@ -179,6 +182,12 @@ public static async Task Update(
List<PackageSource> sources,
SourceCacheContext cache)
{
var key = (package, currentVersion);
if (latestVersionCache.TryGetValue(key, out var cached))
{
return cached;
}

IPackageSearchMetadata? latestMetadata = null;

foreach (var source in sources)
Expand Down Expand Up @@ -212,6 +221,7 @@ public static async Task Update(
}
}

latestVersionCache[key] = latestMetadata;
return latestMetadata;
}

Expand All @@ -221,6 +231,12 @@ public static async Task Update(
List<PackageSource> sources,
SourceCacheContext cache)
{
var key = (package, version);
if (metadataCache.TryGetValue(key, out var cached))
{
return cached;
}

foreach (var source in sources)
{
var (_, metadataResource) = await RepositoryReader.Read(source);
Expand All @@ -233,10 +249,12 @@ public static async Task Update(

if (metadata != null)
{
metadataCache[key] = metadata;
return metadata;
}
}

metadataCache[key] = null;
return null;
}

Expand Down
80 changes: 80 additions & 0 deletions src/Tests/PackageCacheKeyComparerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
public class PackageCacheKeyComparerTests
{
static PackageCacheKeyComparer comparer = PackageCacheKeyComparer.Instance;

[Fact]
public void Equals_SamePackageAndVersion()
{
var x = ("Newtonsoft.Json", NuGetVersion.Parse("13.0.1"));
var y = ("Newtonsoft.Json", NuGetVersion.Parse("13.0.1"));

Assert.True(comparer.Equals(x, y));
}

[Fact]
public void Equals_DifferentCase()
{
var x = ("Newtonsoft.Json", NuGetVersion.Parse("13.0.1"));
var y = ("newtonsoft.json", NuGetVersion.Parse("13.0.1"));

Assert.True(comparer.Equals(x, y));
}

[Fact]
public void Equals_DifferentVersion()
{
var x = ("Newtonsoft.Json", NuGetVersion.Parse("13.0.1"));
var y = ("Newtonsoft.Json", NuGetVersion.Parse("12.0.1"));

Assert.False(comparer.Equals(x, y));
}

[Fact]
public void Equals_DifferentPackage()
{
var x = ("Newtonsoft.Json", NuGetVersion.Parse("13.0.1"));
var y = ("NUnit", NuGetVersion.Parse("13.0.1"));

Assert.False(comparer.Equals(x, y));
}

[Fact]
public void GetHashCode_SameForDifferentCase()
{
var x = ("Newtonsoft.Json", NuGetVersion.Parse("13.0.1"));
var y = ("newtonsoft.json", NuGetVersion.Parse("13.0.1"));

Assert.Equal(comparer.GetHashCode(x), comparer.GetHashCode(y));
}

[Fact]
public void GetHashCode_DifferentForDifferentVersion()
{
var x = ("Newtonsoft.Json", NuGetVersion.Parse("13.0.1"));
var y = ("Newtonsoft.Json", NuGetVersion.Parse("12.0.1"));

Assert.NotEqual(comparer.GetHashCode(x), comparer.GetHashCode(y));
}

[Fact]
public void GetHashCode_DifferentForDifferentPackage()
{
var x = ("Newtonsoft.Json", NuGetVersion.Parse("13.0.1"));
var y = ("NUnit", NuGetVersion.Parse("13.0.1"));

Assert.NotEqual(comparer.GetHashCode(x), comparer.GetHashCode(y));
}

[Fact]
public void WorksWithDictionary()
{
var dictionary = new Dictionary<(string Package, NuGetVersion Version), string>(comparer)
{
[("Newtonsoft.Json", NuGetVersion.Parse("13.0.1"))] = "first"
};

Assert.True(dictionary.ContainsKey(("newtonsoft.json", NuGetVersion.Parse("13.0.1"))));
Assert.True(dictionary.ContainsKey(("NEWTONSOFT.JSON", NuGetVersion.Parse("13.0.1"))));
Assert.False(dictionary.ContainsKey(("Newtonsoft.Json", NuGetVersion.Parse("12.0.1"))));
}
}