Skip to content

Commit

Permalink
Adjust the algorithm in GetVersionForSingleSegment (#7769)
Browse files Browse the repository at this point in the history
* Adjust the algorithm in GetVersionForSingleSegment

    GetVersionForSingleSegment assumes that if we find a fully formed major.minor.patch in the name of a file, followed by something that is not part of the version, that is definitely the version of the file. However, there are instances where there are two well formed major.minor.patch versions 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`. Mono puts the Sdk version in the name of their packages, in addition to the version of the package itself. GetVersionForSingleSegment sees the 6.0.100 followed by .Msi, recognizes that .Msi is not part of a major.minor.patch, and returns 6.0.100, without considering that there is considerably more in the file name that should be considered.

    This change adds a dictionary to track every potential version in a segment, and where in the segment the potential version was found. It then will return the version that occurs the latest in the segment.

* Add the asset name that broke to the csv

* Address feedback

* Fix testcase file

* name them
  • Loading branch information
michellemcdaniel authored Aug 19, 2021
1 parent 65029c8 commit 23372e9
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> majorMinorPatchStack = new Stack<int>(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<int,string> majorMinorPatchDictionary = new Dictionary<int, string>();
while (true)
{
string nextSegment;
Expand Down Expand Up @@ -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 &&
Expand All @@ -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;
}
}

Expand All @@ -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
{
Expand All @@ -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];
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 23372e9

Please sign in to comment.