Skip to content

Commit 69c1895

Browse files
committed
C#: Add fallback logic to nuget install
1 parent ce07d6a commit 69c1895

File tree

2 files changed

+50
-9
lines changed

2 files changed

+50
-9
lines changed

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Security.Cryptography;
77
using System.Text;
8+
using System.Text.RegularExpressions;
89
using System.Threading.Tasks;
910
using Semmle.Util;
1011
using Semmle.Util.Logging;
@@ -14,7 +15,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
1415
/// <summary>
1516
/// Main implementation of the build analysis.
1617
/// </summary>
17-
public sealed class DependencyManager : IDisposable
18+
public sealed partial class DependencyManager : IDisposable
1819
{
1920
private readonly AssemblyCache assemblyCache;
2021
private readonly ILogger logger;
@@ -783,13 +784,38 @@ private void RestoreProjects(IEnumerable<string> projects, out IEnumerable<strin
783784
CompilationInfos.Add(("Successfully restored project files", successCount.ToString()));
784785
}
785786

787+
[GeneratedRegex(@"^(.+)\.(\d+\.\d+\.\d+(-(.+))?)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
788+
private static partial Regex LegacyNugetPackage();
789+
786790
private void DownloadMissingPackages(List<FileInfo> allFiles, ISet<string> dllPaths)
787791
{
788792
var alreadyDownloadedPackages = Directory.GetDirectories(packageDirectory.DirInfo.FullName)
789793
.Select(d => Path.GetFileName(d).ToLowerInvariant());
790794
var notYetDownloadedPackages = fileContent.AllPackages
791795
.Except(alreadyDownloadedPackages)
792-
.ToList();
796+
.ToHashSet();
797+
798+
var oldPackageDirectories = Directory.GetDirectories(legacyPackageDirectory.DirInfo.FullName)
799+
.Select(d => Path.GetFileName(d).ToLowerInvariant());
800+
foreach (var oldPackageDirectory in oldPackageDirectories)
801+
{
802+
// nuget install restores packages to 'packagename.version' folders (dotnet restore to 'packagename/version' folders)
803+
// typical folder names look like:
804+
// newtonsoft.json.13.0.3
805+
// there are more complex ones too, such as:
806+
// runtime.tizen.4.0.0-armel.Microsoft.NETCore.DotNetHostResolver.2.0.0-preview2-25407-01
807+
808+
var match = LegacyNugetPackage().Match(oldPackageDirectory);
809+
if (!match.Success)
810+
{
811+
logger.LogWarning($"Package directory '{oldPackageDirectory}' doesn't match the expected pattern.");
812+
continue;
813+
}
814+
815+
var packageName = match.Groups[1].Value.ToLowerInvariant();
816+
notYetDownloadedPackages.Remove(packageName);
817+
}
818+
793819
if (notYetDownloadedPackages.Count == 0)
794820
{
795821
return;

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

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,23 +157,35 @@ private static bool IsGroupMatch(ReadOnlySpan<char> line, Regex regex, string gr
157157
return false;
158158
}
159159

160+
private void AddPackageReference(ReadOnlySpan<char> line, string groupName, Func<Regex> regex)
161+
{
162+
foreach (var valueMatch in regex().EnumerateMatches(line))
163+
{
164+
// We can't get the group from the ValueMatch, so doing it manually:
165+
var packageName = GetGroup(line, valueMatch, groupName).ToLowerInvariant();
166+
if (!string.IsNullOrEmpty(packageName))
167+
{
168+
allPackages.Add(packageName);
169+
}
170+
}
171+
}
172+
160173
private void DoInitialize()
161174
{
162175
foreach (var file in files)
163176
{
164177
try
165178
{
179+
var isPackagesConfig = file.EndsWith("packages.config", StringComparison.OrdinalIgnoreCase);
180+
166181
foreach (ReadOnlySpan<char> line in unsafeFileReader.ReadLines(file))
167182
{
168183
// Find all the packages.
169-
foreach (var valueMatch in PackageReference().EnumerateMatches(line))
184+
AddPackageReference(line, "Include", PackageReference);
185+
186+
if (isPackagesConfig)
170187
{
171-
// We can't get the group from the ValueMatch, so doing it manually:
172-
var packageName = GetGroup(line, valueMatch, "Include").ToLowerInvariant();
173-
if (!string.IsNullOrEmpty(packageName))
174-
{
175-
allPackages.Add(packageName);
176-
}
188+
AddPackageReference(line, "id", LegacyPackageReference);
177189
}
178190

179191
// Determine if ASP.NET is used.
@@ -223,6 +235,9 @@ private void DoInitialize()
223235
[GeneratedRegex("(?<!<!--.*)<PackageReference.*\\sInclude=\"(.*?)\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
224236
private static partial Regex PackageReference();
225237

238+
[GeneratedRegex("(?<!<!--.*)<package.*\\sid=\"(.*?)\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
239+
private static partial Regex LegacyPackageReference();
240+
226241
[GeneratedRegex("(?<!<!--.*)<FrameworkReference.*\\sInclude=\"(.*?)\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
227242
private static partial Regex FrameworkReference();
228243

0 commit comments

Comments
 (0)