diff --git a/src/NuGet.Updater.Tests/ConsoleArgsParserTests.cs b/src/NuGet.Updater.Tests/ConsoleArgsParserTests.cs index 1b26b14..4cead74 100644 --- a/src/NuGet.Updater.Tests/ConsoleArgsParserTests.cs +++ b/src/NuGet.Updater.Tests/ConsoleArgsParserTests.cs @@ -20,7 +20,7 @@ public class ConsoleArgsParserTests private const string SomePublicFeed = "https://pkgs.dev.azure.com/qwe/_packaging/asd/nuget/v3/index.json"; private const string SomePrivateFeed = "https://pkgs.dev.azure.com/qwe/_packaging/asd/nuget/v3/index.json|hunter2"; private const string PinnedVersionJsonPath = @"Resources\version_overrides.json"; - + [TestMethod] public void Given_HelpArgument_ContextIsHelp() { @@ -167,8 +167,7 @@ public void Given_UpdaterParametersArgument_ContextTargetVersionIsSet() Assert.IsFalse(context.HasError); - var actualValues = context.Parameters.VersionOverrides - .ToDictionary(x => x.Key, x => x.Value); + var actualValues = (ICollection)context.Parameters.VersionOverrides; var expectedValues = ConsoleArgsContext.LoadManualOperations(PinnedVersionJsonPath); CollectionAssert.AreEqual(expectedValues, actualValues); diff --git a/src/NuGet.Updater.Tests/PackageReferenceTests.cs b/src/NuGet.Updater.Tests/PackageReferenceTests.cs index ca2a0ad..5b270b6 100644 --- a/src/NuGet.Updater.Tests/PackageReferenceTests.cs +++ b/src/NuGet.Updater.Tests/PackageReferenceTests.cs @@ -19,6 +19,7 @@ public class PackageReferenceTests private static readonly Dictionary TestPackages = new Dictionary { {"nventive.NuGet.Updater", new[] { "1.0-beta.1" } }, + {"Uno.UI", new[] { "2.1.39", "2.2.0", "2.3.0-dev.44", "2.3.0-dev.48", "2.3.0-dev.58" } }, }; private static readonly TestPackageFeed TestFeed = new TestPackageFeed(TestFeedUri, TestPackages); @@ -72,7 +73,7 @@ public async Task GivenManualUpdates_AndVersionNotInFeed_ManualVersionIsFound() Feeds = { TestFeed }, VersionOverrides = { - { reference.Identity.Id, reference.Identity.Version }, + { reference.Identity.Id, (true, new VersionRange(reference.Identity.Version, true, reference.Identity.Version, true)) }, }, }; @@ -80,5 +81,51 @@ public async Task GivenManualUpdates_AndVersionNotInFeed_ManualVersionIsFound() Assert.AreEqual(version.Version, reference.Identity.Version); } + + [TestMethod] + public async Task GivenRangeOverrides_CorrectVersionsAreResolved() + { + var reference = new PackageReference("Uno.UI", "2.1.39"); + + var parameters = new UpdaterParameters + { + TargetVersions = { "dev", "stable" }, + Feeds = { TestFeed }, + VersionOverrides = + { + { reference.Identity.Id, (false, VersionRange.Parse("(,2.3.0-dev.48]")) }, + }, + }; + + var version = await reference.GetLatestVersion(CancellationToken.None, parameters); + + Assert.AreEqual(NuGetVersion.Parse("2.3.0-dev.48"), version.Version); + + parameters.VersionOverrides["Uno.UI"] = (false, VersionRange.Parse("(,2.3.0-dev.48)")); + + version = await reference.GetLatestVersion(CancellationToken.None, parameters); + + Assert.AreEqual(NuGetVersion.Parse("2.3.0-dev.44"), version.Version); + } + + [TestMethod] + public async Task GivenRangeOverrides_CorrectVersionsAreResolved_AndTargetVersionIsHonored() + { + var reference = new PackageReference("Uno.UI", "2.1.39"); + + var parameters = new UpdaterParameters + { + TargetVersions = { "stable" }, + Feeds = { TestFeed }, + VersionOverrides = + { + { reference.Identity.Id, (false, VersionRange.Parse("(,2.3.0-dev.48]")) }, + }, + }; + + var version = await reference.GetLatestVersion(CancellationToken.None, parameters); + + Assert.AreEqual(NuGetVersion.Parse("2.2.0"), version.Version); + } } } diff --git a/src/NuGet.Updater.Tests/SolutionHelperTests.cs b/src/NuGet.Updater.Tests/SolutionHelperTests.cs deleted file mode 100644 index 5c13d4d..0000000 --- a/src/NuGet.Updater.Tests/SolutionHelperTests.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using NuGet.Shared.Entities; -using NuGet.Shared.Helpers; - -namespace NuGet.Updater.Tests -{ - [TestClass] - public class SolutionHelperTests - { - [Ignore("hardcoded local path")] - [TestMethod] - public async Task GivenSolution_PackageReferencesAreFound() - { - var solution = @"C:\Git\MyMD\MyMD\MyMD.sln"; - - var references = await SolutionHelper.GetPackageReferences(CancellationToken.None, solution, FileType.Csproj, ConsoleLogger.Instance); - - Assert.IsTrue(references.Any()); - } - } -} diff --git a/src/NuGet.Updater.Tool/Arguments/ConsoleArgsContext.cs b/src/NuGet.Updater.Tool/Arguments/ConsoleArgsContext.cs index 67f97f8..3ae98eb 100644 --- a/src/NuGet.Updater.Tool/Arguments/ConsoleArgsContext.cs +++ b/src/NuGet.Updater.Tool/Arguments/ConsoleArgsContext.cs @@ -97,14 +97,24 @@ Action TryParseAndSet(Func parse, Action set) public void WriteOptionDescriptions(TextWriter writer) => CreateOptionsFor(default).WriteOptionDescriptions(writer); - internal static Dictionary LoadManualOperations(string inputFilePath) + internal static Dictionary LoadManualOperations(string inputFilePath) { using(var fileReader = File.OpenText(inputFilePath)) using(var jsonReader = new JsonTextReader(fileReader)) { var result = JsonSerializer.CreateDefault().Deserialize>(jsonReader); - return result.ToDictionary(r => r.PackageId, r => new NuGetVersion(r.UpdatedVersion)); + return result.ToDictionary( + r => r.PackageId, + r => NuGetVersion.TryParse(r.UpdatedVersion, out var version) ? + (true, new VersionRange( + minVersion: version, + includeMinVersion: true, + maxVersion: version, + includeMaxVersion: true, + floatRange: null, + originalString: null)) : + (false, VersionRange.Parse(r.UpdatedVersion))); } } } diff --git a/src/NuGet.Updater.Tool/Readme.md b/src/NuGet.Updater.Tool/Readme.md index ab508f4..dbf937c 100644 --- a/src/NuGet.Updater.Tool/Readme.md +++ b/src/NuGet.Updater.Tool/Readme.md @@ -52,3 +52,21 @@ nugetupdater -s=MySolution.sln -n -f=https://pkgs.dev.azure.com/account/_packagi ``` nugetupdater -s=MySolution.sln -n --allowDowngrade ``` + +- Update packages to specific versions (forcefully and/or with nuget version ranges). See : https://docs.microsoft.com/en-us/nuget/concepts/package-versioning#version-ranges +``` +nugetupdater -s=MySolution.sln -n -v=dev -v=stable --allowDowngrade --versionOverrides=versions.json +``` +Versions.json example: +``` +[ + { + "PackageId": "Uno.UI", + "UpdatedVersion": "2.3.0-dev.76" -> Force 2.3.0-dev.76 + }, + { + "PackageId": "Uno.Wasm.Bootstrap", + "UpdatedVersion": "(,1.2.0-dev.18]" -> Resolves 1.2.0-dev.18 (-v=dev + -v=stable), 1.0.10 (-v=stable) + } +] +``` diff --git a/src/NuGet.Updater.sln b/src/NuGet.Updater.sln index 254b661..5be5713 100644 --- a/src/NuGet.Updater.sln +++ b/src/NuGet.Updater.sln @@ -39,7 +39,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGet.Downloader.Tests", "N EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution + NuGet.Shared\NuGet.Shared.projitems*{29277270-8efe-41a3-8cd8-d54ebf514c41}*SharedItemsImports = 5 NuGet.Shared\NuGet.Shared.projitems*{3890cca3-b7cf-450b-a6cd-4a4106b0008c}*SharedItemsImports = 13 + NuGet.Shared\NuGet.Shared.projitems*{912018bd-d988-4c90-b4ec-ba1c171207c3}*SharedItemsImports = 5 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/src/NuGet.Updater/Entities/UpdaterParameters.cs b/src/NuGet.Updater/Entities/UpdaterParameters.cs index 6184332..52f75d7 100644 --- a/src/NuGet.Updater/Entities/UpdaterParameters.cs +++ b/src/NuGet.Updater/Entities/UpdaterParameters.cs @@ -52,9 +52,9 @@ public class UpdaterParameters public string PackageAuthor { get; set; } /// - /// Gets the version to set for specific packages. + /// Gets the version range overrides for specific packages. /// - public IDictionary VersionOverrides { get; } = new Dictionary(); + public IDictionary VersionOverrides { get; } = new Dictionary(); /// /// Gets or sets a value indicating whether to actually write the updates to the files. diff --git a/src/NuGet.Updater/Extensions/PackageReferenceExtensions.cs b/src/NuGet.Updater/Extensions/PackageReferenceExtensions.cs index d95f646..6f4964a 100644 --- a/src/NuGet.Updater/Extensions/PackageReferenceExtensions.cs +++ b/src/NuGet.Updater/Extensions/PackageReferenceExtensions.cs @@ -50,19 +50,20 @@ public static async Task GetLatestVersion( UpdaterParameters parameters ) { - if(parameters.VersionOverrides.TryGetValue(reference.Identity.Id, out var manualVersion)) + if(parameters.VersionOverrides.TryGetValue(reference.Identity.Id, out var manualVersion) && manualVersion.forceVersion) { PackageFeed.Logger.LogInformation($"Overriding version for {reference.Identity.Id}"); - return new FeedVersion(manualVersion); + return new FeedVersion(manualVersion.range.MinVersion); } var availableVersions = await Task.WhenAll(parameters .Feeds .Select(f => f.GetPackageVersions(ct, reference, parameters.PackageAuthor)) ); - + var versionsPerTarget = availableVersions .SelectMany(x => x) + .Where(v => manualVersion.range?.Satisfies(v.Version) ?? true) .OrderByDescending(v => v) .GroupBy(version => parameters.TargetVersions.FirstOrDefault(t => version.IsMatchingVersion(t, parameters.Strict))) .Where(g => g.Key.HasValue());