diff --git a/src/Microsoft.DotNet.VersionTools/lib/src/BuildManifest/VersionIdentifier.cs b/src/Microsoft.DotNet.VersionTools/lib/src/BuildManifest/VersionIdentifier.cs index 39d44ed7a95..0f010d83037 100644 --- a/src/Microsoft.DotNet.VersionTools/lib/src/BuildManifest/VersionIdentifier.cs +++ b/src/Microsoft.DotNet.VersionTools/lib/src/BuildManifest/VersionIdentifier.cs @@ -87,14 +87,19 @@ private static string GetVersionForSingleSegment(string assetPathSegment) // then look for a minor.patch, completing the major.minor.patch. Continue to do so until we get // to something that is NOT major.minor.patch (this is necessary because we sometimes see things like: // VS.Redist.Common.NetCore.Templates.x86.2.2.3.0.101-servicing-014320.nupkg + // Continue iterating until we find ALL potential versions. Return the one that is the latest in the segment + // This is to deal with files with multiple major.minor.patchs in the file name, for example: + // Microsoft.NET.Workload.Mono.ToolChain.Manifest-6.0.100.Msi.x64.6.0.0-rc.1.21380.2.symbols.nupkg int currentIndex = 0; // Stack of major.minor.patch. - Stack majorMinorPatchStack = new Stack(3); + Stack<(int versionNumber, int index)> majorMinorPatchStack = new Stack<(int,int)>(3); string majorMinorPatch = null; + int majorMinorPatchIndex = 0; StringBuilder versionSuffix = new StringBuilder(); char prevDelimiterCharacter = char.MinValue; char nextDelimiterCharacter = char.MinValue; + Dictionary majorMinorPatchDictionary = new Dictionary(); while (true) { string nextSegment; @@ -124,7 +129,7 @@ private static string GetVersionForSingleSegment(string assetPathSegment) if ((majorMinorPatchStack.Count == 0 && isNumber) || (majorMinorPatchStack.Count > 0 && prevDelimiterCharacter == '.' && isNumber)) { - majorMinorPatchStack.Push(potentialVersionSegment); + majorMinorPatchStack.Push((potentialVersionSegment, currentIndex)); } // Check for partial major.minor.patch cases, like: 2.2.bar or 2.2-100.bleh else if (majorMinorPatchStack.Count > 0 && majorMinorPatchStack.Count < 3 && @@ -137,10 +142,11 @@ private static string GetVersionForSingleSegment(string assetPathSegment) if (majorMinorPatchStack.Count >= 3 && (prevDelimiterCharacter != '.' || !isNumber || nextDelimiterIndex == -1)) { // Done with major.minor.patch, found. Pop the top 3 elements off the stack. - int patch = majorMinorPatchStack.Pop(); - int minor = majorMinorPatchStack.Pop(); - int major = majorMinorPatchStack.Pop(); + (int patch, int patchIndex) = majorMinorPatchStack.Pop(); + (int minor, int minorIndex) = majorMinorPatchStack.Pop(); + (int major, int majorIndex) = majorMinorPatchStack.Pop(); majorMinorPatch = $"{major}.{minor}.{patch}"; + majorMinorPatchIndex = majorIndex; } } @@ -160,11 +166,15 @@ private static string GetVersionForSingleSegment(string assetPathSegment) if (versionSuffix.Length == 0 && (prevDelimiterCharacter != '-' || !_knownTags.Any(tag => nextSegment.StartsWith(tag, StringComparison.OrdinalIgnoreCase)))) { - return majorMinorPatch; + majorMinorPatchDictionary.Add(majorMinorPatchIndex, majorMinorPatch); + majorMinorPatch = null; + versionSuffix = new StringBuilder(); } else if (versionSuffix.Length != 0 && !int.TryParse(nextSegment, out int potentialVersionSegment) && nextSegment != _finalSuffix) { - return $"{majorMinorPatch}{versionSuffix.ToString()}"; + majorMinorPatchDictionary.Add(majorMinorPatchIndex, $"{majorMinorPatch}{versionSuffix.ToString()}"); + majorMinorPatch = null; + versionSuffix = new StringBuilder(); } else { @@ -184,12 +194,18 @@ private static string GetVersionForSingleSegment(string assetPathSegment) } } - if (string.IsNullOrEmpty(majorMinorPatch)) + if(majorMinorPatch != null) + { + majorMinorPatchDictionary.Add(majorMinorPatchIndex, $"{majorMinorPatch}{versionSuffix.ToString()}"); + } + + if (!majorMinorPatchDictionary.Any()) { return null; } - return $"{majorMinorPatch}{versionSuffix.ToString()}"; + int maxKey = majorMinorPatchDictionary.Keys.Max(); + return majorMinorPatchDictionary[maxKey]; } /// diff --git a/src/Microsoft.DotNet.VersionTools/tests/BuildManifest/VersionIdentiferTests.cs b/src/Microsoft.DotNet.VersionTools/tests/BuildManifest/VersionIdentiferTests.cs index eaa6ad85c8d..4982b09128a 100644 --- a/src/Microsoft.DotNet.VersionTools/tests/BuildManifest/VersionIdentiferTests.cs +++ b/src/Microsoft.DotNet.VersionTools/tests/BuildManifest/VersionIdentiferTests.cs @@ -34,6 +34,7 @@ public class VersionTests [InlineData("What-Is-A.FooPackage.2.2.10.0.1", "10.0.1")] [InlineData("What-Is-A.FooPackage.2.2.10.0.1-beta.final", "10.0.1-beta.final")] [InlineData("What-Is-A.FooPackage.2.2.10.0.1-preview1.12345.1", "10.0.1-preview1.12345.1")] + [InlineData("What-Is-A.FooPackage.2.2.0.Extra.Stuff.10.0.1-preview1.12345.1", "10.0.1-preview1.12345.1")] [InlineData("What-Is-A.FooPackage", null)] [InlineData("What-Is-A.FooPackage-2.2-64", null)] [InlineData("What-Is-A.FooPackage-2.2.nupkg", null)] diff --git a/src/Microsoft.DotNet.VersionTools/tests/BuildManifest/VersionIdentifierTestsAssets.csv b/src/Microsoft.DotNet.VersionTools/tests/BuildManifest/VersionIdentifierTestsAssets.csv index b059326b8fa..0a98976aafc 100644 --- a/src/Microsoft.DotNet.VersionTools/tests/BuildManifest/VersionIdentifierTestsAssets.csv +++ b/src/Microsoft.DotNet.VersionTools/tests/BuildManifest/VersionIdentifierTestsAssets.csv @@ -4960,3 +4960,4 @@ Microsoft.DotNet.Web.ProjectTemplates.2.2.2.2.7.nupkg,2.2.7,Microsoft.DotNet.Web Microsoft.DotNet.Web.Spa.ProjectTemplates.2.2.2.2.7.nupkg,2.2.7,Microsoft.DotNet.Web.Spa.ProjectTemplates.2.2.nupkg runtime.win-x64.Microsoft.AspNetCore.All.2.2.7.nupkg,2.2.7,runtime.win-x64.Microsoft.AspNetCore.All.nupkg runtime.win-x64.Microsoft.AspNetCore.App.2.2.7.nupkg,2.2.7,runtime.win-x64.Microsoft.AspNetCore.App.nupkg +assets/symbols/Microsoft.NET.Workload.Mono.ToolChain.Manifest-6.0.100.Msi.x64.6.0.0-preview.7.21377.20.symbols.nupkg,6.0.0-preview.7.21377.20,assets/symbols/Microsoft.NET.Workload.Mono.ToolChain.Manifest-6.0.100.Msi.x64.symbols.nupkg