diff --git a/DotNetSolutionTools.Core/DotNetSolutionTools.Core.csproj b/DotNetSolutionTools.Core/DotNetSolutionTools.Core.csproj index db84586..6b095b7 100644 --- a/DotNetSolutionTools.Core/DotNetSolutionTools.Core.csproj +++ b/DotNetSolutionTools.Core/DotNetSolutionTools.Core.csproj @@ -8,6 +8,7 @@ + diff --git a/DotNetSolutionTools.Core/DotNetUpgrade.cs b/DotNetSolutionTools.Core/DotNetUpgrade.cs index fedb844..480ee4e 100644 --- a/DotNetSolutionTools.Core/DotNetUpgrade.cs +++ b/DotNetSolutionTools.Core/DotNetUpgrade.cs @@ -1,4 +1,5 @@ -using Microsoft.Build.Construction; +using DotNetSolutionTools.Core.Infrastructure; +using Microsoft.Build.Construction; using Microsoft.Build.Definition; using Microsoft.Build.Evaluation; @@ -6,23 +7,21 @@ namespace DotNetSolutionTools.Core; public static class DotNetUpgrade { - public static void UpdateProjectsInSolutionToNet80(string solutionFilePath) + public static async Task UpdateProjectsInSolutionToNet80(string solutionFilePath) { var solutionFile = SolutionFile.Parse(solutionFilePath); var csprojList = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile( solutionFile ); - UpdateProjectsToNet80(csprojList); + await UpdateProjectsToNet80(csprojList); } - private static void UpdateProjectsToNet80(List projects) + private static async Task UpdateProjectsToNet80(List projects) { foreach (var project in projects) { - var evalProject = Project.FromProjectRootElement(project, new ProjectOptions(){LoadSettings = ProjectLoadSettings.IgnoreMissingImports}); - var packages = evalProject.GetItems("PackageReference"); - //packages.First().Metadata.First().UnevaluatedValue = "9.0.0"; - var targetFramework = project.PropertyGroups + var targetFramework = project + .PropertyGroups .SelectMany(x => x.Properties) .FirstOrDefault(x => x.Name == "TargetFramework"); if (targetFramework?.Value is "net7.0") @@ -31,6 +30,46 @@ public static class DotNetUpgrade project.Save(); FormatCsproj.FormatCsprojFile(project.FullPath); } + + await UpdatePackagesToLatest(project); } } -} \ No newline at end of file + + public static async Task UpdatePackagesToLatest(ProjectRootElement project) + { + var evalProject = Project.FromProjectRootElement( + project, + new ProjectOptions() { LoadSettings = ProjectLoadSettings.IgnoreMissingImports } + ); + var packages = evalProject.Items.Where(x => x.ItemType == "PackageReference"); + var packageNameAndVersion = packages + .Select( + x => + new + { + Package = x, + Name = x.EvaluatedInclude, + Version = Version.Parse( + x.Metadata.First(s => s.Name == "Version").UnevaluatedValue + ) + } + ) + .ToList(); + + var shouldFormat = false; + foreach (var package in packageNameAndVersion) + { + var latestNugetVersion = await NugetLookup.FetchPackageMetadataAsync(package.Name); + // it will compare 6.8.0.0 to 6.8.0, and says left is newer, we dont want to say its newer, so use the normalized string to make a new version + var normalizedVersion = Version.Parse(latestNugetVersion.ToString()); + if (normalizedVersion > package.Version) + { + shouldFormat = true; + package.Package.SetMetadataValue("Version", latestNugetVersion.ToString()); + project.Save(); + } + } + if (shouldFormat) + FormatCsproj.FormatCsprojFile(project.FullPath); + } +} diff --git a/DotNetSolutionTools.Core/Infrastructure/NugetLookup.cs b/DotNetSolutionTools.Core/Infrastructure/NugetLookup.cs new file mode 100644 index 0000000..f403ff1 --- /dev/null +++ b/DotNetSolutionTools.Core/Infrastructure/NugetLookup.cs @@ -0,0 +1,26 @@ +using NuGet.Common; +using NuGet.Protocol; +using NuGet.Protocol.Core.Types; +using NuGet.Versioning; + +namespace DotNetSolutionTools.Core.Infrastructure; + +public static class NugetLookup +{ + public static async Task FetchPackageMetadataAsync(string packageId) + { + var cache = new SourceCacheContext(); + var repositories = Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json"); + var logger = NullLogger.Instance; + + var resource = await repositories.GetResourceAsync(); + var versions = await resource.GetAllVersionsAsync( + packageId, + cache, + logger, + CancellationToken.None + ); + + return versions.Last(s => s.IsPrerelease == false); + } +}