Skip to content

Commit 10c0183

Browse files
authored
Merge pull request #20964 from michaelnebel/csharp/nugetversionsorting
C#: Fix NuGet version bug and a .NET10 compatibility issue.
2 parents 3230df0 + 5a33f9f commit 10c0183

File tree

13 files changed

+45
-50
lines changed

13 files changed

+45
-50
lines changed

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ codeql_csharp_library(
1616
"//csharp/extractor/Semmle.Extraction.CSharp",
1717
"//csharp/extractor/Semmle.Util",
1818
"@paket.main//newtonsoft.json",
19+
"@paket.main//nuget.versioning",
1920
],
2021
)

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ private void AddNetFrameworkDlls(ISet<AssemblyLookupLocation> dllLocations, ISet
283283
{
284284
foreach (var fp in frameworkPaths)
285285
{
286-
dotnetFrameworkVersionVariantCount += NugetPackageRestorer.GetOrderedPackageVersionSubDirectories(fp.Path!).Length;
286+
dotnetFrameworkVersionVariantCount += nugetPackageRestorer.GetOrderedPackageVersionSubDirectories(fp.Path!).Length;
287287
}
288288

289289
var folder = nugetPackageRestorer.GetNewestNugetPackageVersionFolder(frameworkPath.Path, ".NET Framework");

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ private string GetRestoreArgs(RestoreSettings restoreSettings)
7777
Directory.CreateDirectory(path);
7878
}
7979

80-
args += $" /p:TargetFrameworkRootPath=\"{path}\" /p:NetCoreTargetingPackRoot=\"{path}\"";
80+
args += $" /p:TargetFrameworkRootPath=\"{path}\" /p:NetCoreTargetingPackRoot=\"{path}\" /p:AllowMissingPrunePackageData=true";
8181
}
8282

8383
if (restoreSettings.PathToNugetConfig != null)

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetVersion.cs

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
11
using System;
22
using System.IO;
3+
using NuGet.Versioning;
34

45
namespace Semmle.Extraction.CSharp.DependencyFetching
56
{
67
internal record DotNetVersion : IComparable<DotNetVersion>
78
{
89
private readonly string dir;
9-
private readonly Version version;
10-
private readonly Version? preReleaseVersion;
11-
private readonly string? preReleaseVersionType;
12-
private bool IsPreRelease => preReleaseVersionType is not null && preReleaseVersion is not null;
10+
private readonly NuGetVersion version;
1311

14-
private string FullVersion
15-
{
16-
get
17-
{
18-
var preRelease = IsPreRelease ? $"-{preReleaseVersionType}.{preReleaseVersion}" : "";
19-
return this.version + preRelease;
20-
}
21-
}
12+
private string FullVersion =>
13+
version.ToString();
2214

2315
public string FullPath => Path.Combine(dir, FullVersion);
2416

@@ -48,37 +40,14 @@ public string? FullPathReferenceAssemblies
4840
}
4941

5042

51-
public DotNetVersion(string dir, string version, string preReleaseVersionType, string preReleaseVersion)
43+
public DotNetVersion(string dir, NuGetVersion version)
5244
{
5345
this.dir = dir;
54-
this.version = Version.Parse(version);
55-
if (!string.IsNullOrEmpty(preReleaseVersion) && !string.IsNullOrEmpty(preReleaseVersionType))
56-
{
57-
this.preReleaseVersionType = preReleaseVersionType;
58-
this.preReleaseVersion = Version.Parse(preReleaseVersion);
59-
}
46+
this.version = version;
6047
}
6148

62-
public int CompareTo(DotNetVersion? other)
63-
{
64-
var c = version.CompareTo(other?.version);
65-
if (c == 0 && IsPreRelease)
66-
{
67-
if (!other!.IsPreRelease)
68-
{
69-
return -1;
70-
}
71-
72-
// Both are pre-release like runtime versions.
73-
// The pre-release version types are sorted alphabetically (e.g. alpha, beta, preview, rc)
74-
// and the pre-release version types are more important that the pre-release version numbers.
75-
return preReleaseVersionType != other!.preReleaseVersionType
76-
? preReleaseVersionType!.CompareTo(other!.preReleaseVersionType)
77-
: preReleaseVersion!.CompareTo(other!.preReleaseVersion);
78-
}
79-
80-
return c;
81-
}
49+
public int CompareTo(DotNetVersion? other) =>
50+
version.CompareTo(other?.version);
8251

8352
public override string ToString() => FullPath;
8453
}

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Text.RegularExpressions;
1111
using System.Threading;
1212
using System.Threading.Tasks;
13+
using NuGet.Versioning;
1314
using Semmle.Util;
1415
using Semmle.Util.Logging;
1516

@@ -87,11 +88,22 @@ public string GetNewestNugetPackageVersionFolder(string packagePath, string pack
8788
return selectedFrameworkFolder;
8889
}
8990

90-
public static DirectoryInfo[] GetOrderedPackageVersionSubDirectories(string packagePath)
91+
public DirectoryInfo[] GetOrderedPackageVersionSubDirectories(string packagePath)
9192
{
93+
// Only consider directories with valid NuGet version names.
9294
return new DirectoryInfo(packagePath)
9395
.EnumerateDirectories("*", new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = false })
94-
.OrderByDescending(d => d.Name) // TODO: Improve sorting to handle pre-release versions.
96+
.SelectMany(d =>
97+
{
98+
if (NuGetVersion.TryParse(d.Name, out var version))
99+
{
100+
return new[] { new { Directory = d, NuGetVersion = version } };
101+
}
102+
logger.LogInfo($"Ignoring package directory '{d.FullName}' as it does not have a valid NuGet version name.");
103+
return [];
104+
})
105+
.OrderByDescending(dw => dw.NuGetVersion)
106+
.Select(dw => dw.Directory)
95107
.ToArray();
96108
}
97109

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using System.Runtime.InteropServices;
66
using System.Text.RegularExpressions;
7+
using NuGet.Versioning;
78
using Semmle.Util;
89
using Semmle.Util.Logging;
910

@@ -27,7 +28,7 @@ public Runtime(IDotNet dotNet)
2728
this.newestRuntimes = new(GetNewestRuntimes);
2829
}
2930

30-
[GeneratedRegex(@"^(\S+)\s(\d+\.\d+\.\d+)(-([a-z]+)\.(\d+\.\d+\.\d+))?\s\[(.+)\]$")]
31+
[GeneratedRegex(@"^(\S+)\s(\d+\.\d+\.\d+(-[a-z]+\.\d+\.\d+\.\d+)?)\s\[(.+)\]$")]
3132
private static partial Regex RuntimeRegex();
3233

3334
/// <summary>
@@ -44,9 +45,9 @@ private static Dictionary<string, DotNetVersion> ParseRuntimes(IList<string> lis
4445
listed.ForEach(r =>
4546
{
4647
var match = regex.Match(r);
47-
if (match.Success)
48+
if (match.Success && NuGetVersion.TryParse(match.Groups[2].Value, out var version))
4849
{
49-
runtimes.AddOrUpdateToLatest(match.Groups[1].Value, new DotNetVersion(match.Groups[6].Value, match.Groups[2].Value, match.Groups[4].Value, match.Groups[5].Value));
50+
runtimes.AddOrUpdateToLatest(match.Groups[1].Value, new DotNetVersion(match.Groups[4].Value, version));
5051
}
5152
});
5253

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Sdk.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Linq;
55
using System.Text.RegularExpressions;
6+
using NuGet.Versioning;
67
using Semmle.Util;
78
using Semmle.Util.Logging;
89

@@ -27,7 +28,7 @@ public Sdk(IDotNet dotNet, ILogger logger)
2728
cscPath = new Lazy<string?>(GetCscPath);
2829
}
2930

30-
[GeneratedRegex(@"^(\d+\.\d+\.\d+)(-([a-z]+)\.(\d+\.\d+\.\d+))?\s\[(.+)\]$")]
31+
[GeneratedRegex(@"^(\d+\.\d+\.\d+(-[a-z]+\.\d+\.\d+\.\d+)?)\s\[(.+)\]$")]
3132
private static partial Regex SdkRegex();
3233

3334
private static HashSet<DotNetVersion> ParseSdks(IList<string> listed)
@@ -37,9 +38,9 @@ private static HashSet<DotNetVersion> ParseSdks(IList<string> listed)
3738
listed.ForEach(r =>
3839
{
3940
var match = regex.Match(r);
40-
if (match.Success)
41+
if (match.Success && NuGetVersion.TryParse(match.Groups[1].Value, out var version))
4142
{
42-
sdks.Add(new DotNetVersion(match.Groups[5].Value, match.Groups[1].Value, match.Groups[3].Value, match.Groups[4].Value));
43+
sdks.Add(new DotNetVersion(match.Groups[3].Value, version));
4344
}
4445
});
4546

@@ -73,4 +74,4 @@ private static HashSet<DotNetVersion> ParseSdks(IList<string> listed)
7374
return path;
7475
}
7576
}
76-
}
77+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
Newtonsoft.Json
2+
NuGet.Versioning

csharp/paket.dependencies

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ strategy: max
77
nuget Basic.CompilerLog.Util 0.9.21
88
nuget Mono.Posix.NETStandard
99
nuget Newtonsoft.Json
10+
nuget NuGet.Versioning
1011
nuget xunit
1112
nuget xunit.runner.visualstudio
1213
nuget xunit.runner.utility

csharp/paket.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)