diff --git a/tests/Meziantou.Analyzer.Test/Helpers/ProjectBuilder.Validation.cs b/tests/Meziantou.Analyzer.Test/Helpers/ProjectBuilder.Validation.cs index fd8ecd7e..08485a46 100755 --- a/tests/Meziantou.Analyzer.Test/Helpers/ProjectBuilder.Validation.cs +++ b/tests/Meziantou.Analyzer.Test/Helpers/ProjectBuilder.Validation.cs @@ -191,7 +191,7 @@ private Task CreateProject() break; case TargetFramework.Net9_0: - AddNuGetReference("Microsoft.NETCore.App.Ref", "9.0.0-rc.1.24431.7", "ref/net9.0/"); + AddNuGetReference("Microsoft.NETCore.App.Ref", "9.0.0", "ref/net9.0/"); break; case TargetFramework.AspNetCore5_0: diff --git a/tests/Meziantou.Analyzer.Test/Helpers/ProjectBuilder.cs b/tests/Meziantou.Analyzer.Test/Helpers/ProjectBuilder.cs index 599672fa..cfdedc94 100755 --- a/tests/Meziantou.Analyzer.Test/Helpers/ProjectBuilder.cs +++ b/tests/Meziantou.Analyzer.Test/Helpers/ProjectBuilder.cs @@ -8,8 +8,10 @@ using System.Reflection; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; +using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; +using Meziantou.Analyzer.Rules; using Meziantou.Analyzer.Test.Helpers; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; @@ -45,19 +47,28 @@ public sealed partial class ProjectBuilder public string DefaultAnalyzerId { get; set; } public string DefaultAnalyzerMessage { get; set; } - private static Task GetNuGetReferences(string packageName, string version, params string[] paths) + private static async Task GetNuGetReferences(string packageName, string version, params string[] paths) { - var task = NuGetPackagesCache.GetOrAdd( - packageName + '@' + version + ':' + string.Join(",", paths), - _ => new Lazy>(Download)); - - return task.Value; + var bytes = Encoding.UTF8.GetBytes(packageName + '@' + version + ':' + string.Join(",", paths)); +#if NET8_0_OR_GREATER + var hash = SHA256.HashData(bytes); +#else + using var sha256 = SHA256.Create(); + var hash = sha256.ComputeHash(bytes); +#endif + var key = Convert.ToBase64String(hash).Replace('/', '_'); + var task = NuGetPackagesCache.GetOrAdd(key, _ => new Lazy>(Download)); + return await task.Value.ConfigureAwait(false); async Task Download() { - var tempFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Meziantou.AnalyzerTests", "ref", packageName + '@' + version); - if (!Directory.Exists(tempFolder) || !Directory.EnumerateFileSystemEntries(tempFolder).Any()) + var cacheFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Meziantou.AnalyzerTests", "ref", key); + bool IsCacheValid() => Directory.Exists(cacheFolder) && Directory.EnumerateFileSystemEntries(cacheFolder).Any(); + + if (!IsCacheValid()) { + var tempFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(tempFolder); using var stream = await SharedHttpClient.Instance.GetStreamAsync(new Uri($"https://www.nuget.org/api/v2/package/{packageName}/{version}")).ConfigureAwait(false); using var zip = new ZipArchive(stream, ZipArchiveMode.Read); @@ -66,9 +77,22 @@ async Task Download() { entry.ExtractToFile(Path.Combine(tempFolder, entry.Name), overwrite: true); } + + try + { + Directory.CreateDirectory(Path.GetDirectoryName(cacheFolder)); + Directory.Move(tempFolder, cacheFolder); + } + catch (Exception ex) + { + if (!IsCacheValid()) + { + throw new InvalidOperationException("Cannot download NuGet package " + packageName + "@" + version + "\n" + ex); + } + } } - var dlls = Directory.GetFiles(tempFolder, "*.dll"); + var dlls = Directory.GetFiles(cacheFolder, "*.dll"); // Filter invalid .NET assembly var result = new List();