Skip to content

Commit 4c123eb

Browse files
committed
C#: Push the feed fetching logic into DownloadPackages, use allfeeds instead of a specific nuget.config file, and supply a list of nuget sources when using the TryRestore.
1 parent e75c33f commit 4c123eb

2 files changed

Lines changed: 36 additions & 59 deletions

File tree

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ internal sealed partial class FeedManager : IDisposable
7878
/// </summary>
7979
public ImmutableHashSet<string> ReachableFeeds => lazyReachableFeeds.Value;
8080

81+
private readonly Lazy<ImmutableHashSet<string>> lazyReachableFallbackFeeds;
82+
/// <summary>
83+
/// Gets the list of reachable NuGet feeds that are configured as fallback feeds.
84+
/// </summary>
85+
public ImmutableHashSet<string> ReachableFallbackFeeds => lazyReachableFallbackFeeds.Value;
86+
8187
public FeedManager(ILogger logger, IDotNet dotnet, DependabotProxy? dependabotProxy, FileProvider fileProvider)
8288
{
8389
this.logger = logger;
@@ -101,6 +107,11 @@ public FeedManager(ILogger logger, IDotNet dotnet, DependabotProxy? dependabotPr
101107
CheckSpecifiedFeeds(InheritedFeeds, out var reachableInheritedFeeds);
102108
return ReachableExplicitFeeds.Union(reachableInheritedFeeds).ToImmutableHashSet();
103109
});
110+
lazyReachableFallbackFeeds = new Lazy<ImmutableHashSet<string>>(() =>
111+
{
112+
var reachableFallbackFeeds = GetReachableFallbackNugetFeeds();
113+
return reachableFallbackFeeds.ToImmutableHashSet();
114+
});
104115
}
105116

106117

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

Lines changed: 25 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Collections.Immutable;
55
using System.IO;
66
using System.Linq;
7-
using System.Text;
87
using System.Text.RegularExpressions;
98
using System.Threading;
109
using System.Threading.Tasks;
@@ -53,7 +52,9 @@ public NugetPackageRestorer(
5352

5453
public string? TryRestore(string package)
5554
{
56-
if (TryRestorePackageManually(package))
55+
var feeds = feedManager.CheckNugetFeedResponsiveness ? feedManager.ReachableFeeds : feedManager.AllFeeds;
56+
var nugetSources = feedManager.FeedsToDotnetRestoreArgument(feeds);
57+
if (TryRestorePackageManually(package, nugetSources))
5758
{
5859
var packageDir = DependencyManager.GetPackageDirectory(package, missingPackageDirectory.DirInfo);
5960
if (packageDir is not null)
@@ -133,7 +134,7 @@ public HashSet<AssemblyLookupLocation> Restore()
133134
{
134135
// If we experience a timeout, we use this fallback.
135136
// todo: we could also check the reachability of the inherited nuget feeds, but to use those in the fallback we would need to handle authentication too.
136-
var unresponsiveMissingPackageLocation = DownloadMissingPackagesAndUseFallback([]);
137+
var unresponsiveMissingPackageLocation = DownloadMissingPackages([]);
137138
return unresponsiveMissingPackageLocation is null
138139
? []
139140
: [unresponsiveMissingPackageLocation];
@@ -195,9 +196,7 @@ public HashSet<AssemblyLookupLocation> Restore()
195196

196197
var usedPackageNames = GetAllUsedPackageDirNames(dependencies);
197198

198-
var missingPackageLocation = feedManager.CheckNugetFeedResponsiveness
199-
? DownloadMissingPackagesAndUseFallback(usedPackageNames)
200-
: DownloadMissingPackages(usedPackageNames);
199+
var missingPackageLocation = DownloadMissingPackages(usedPackageNames);
201200

202201
if (missingPackageLocation is not null)
203202
{
@@ -303,22 +302,28 @@ private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<Dep
303302
compilationInfoContainer.CompilationInfos.Add(("Failed project restore with missing package error", nugetMissingPackageFailures.ToString()));
304303
}
305304

306-
private AssemblyLookupLocation? DownloadMissingPackagesAndUseFallback(IEnumerable<string> usedPackageNames)
305+
private AssemblyLookupLocation? DownloadMissingPackages(IEnumerable<string> usedPackageNames)
307306
{
308-
var reachableFallbackFeeds = feedManager.GetReachableFallbackNugetFeeds();
309-
compilationInfoContainer.CompilationInfos.Add(("Reachable fallback NuGet feed count", reachableFallbackFeeds.Count.ToString()));
307+
ImmutableHashSet<string> feeds;
308+
if (feedManager.CheckNugetFeedResponsiveness)
309+
{
310+
// Attempt to get the fallback configuration.
311+
var reachableFallbackFeeds = feedManager.ReachableFallbackFeeds;
312+
compilationInfoContainer.CompilationInfos.Add(("Reachable fallback NuGet feed count", reachableFallbackFeeds.Count.ToString()));
310313

311-
if (reachableFallbackFeeds.Count > 0)
314+
if (reachableFallbackFeeds.Count == 0)
315+
{
316+
logger.LogWarning("Skipping download of missing packages from specific feeds as no fallback NuGet feeds are reachable.");
317+
return null;
318+
}
319+
feeds = reachableFallbackFeeds;
320+
}
321+
else
312322
{
313-
return DownloadMissingPackages(usedPackageNames, fallbackNugetFeeds: reachableFallbackFeeds);
323+
feeds = feedManager.AllFeeds;
314324
}
315325

316-
logger.LogWarning("Skipping download of missing packages from specific feeds as no fallback NuGet feeds are reachable.");
317-
return null;
318-
}
319-
320-
private AssemblyLookupLocation? DownloadMissingPackages(IEnumerable<string> usedPackageNames, IEnumerable<string>? fallbackNugetFeeds = null)
321-
{
326+
var nugetSources = feedManager.FeedsToDotnetRestoreArgument(feeds);
322327
var alreadyDownloadedPackages = usedPackageNames.Select(p => p.ToLowerInvariant());
323328
var alreadyDownloadedLegacyPackages = GetRestoredLegacyPackageNames();
324329

@@ -351,26 +356,14 @@ private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<Dep
351356

352357
logger.LogInfo($"Found {notYetDownloadedPackages.Count} packages that are not yet restored");
353358

354-
IEnumerable<string> feeds = [];
355-
if (fallbackNugetFeeds is not null)
356-
{
357-
feeds = fallbackNugetFeeds;
358-
}
359-
else if (GetNugetConfig() is string config)
360-
{
361-
feeds = feedManager.FeedsToUseFromConfig(config);
362-
}
363-
364-
var nugetSources = feedManager.FeedsToDotnetRestoreArgument(feeds);
365-
366359
compilationInfoContainer.CompilationInfos.Add(("Fallback nuget restore", notYetDownloadedPackages.Count.ToString()));
367360

368361
var successCount = 0;
369362
var sync = new Lock();
370363

371364
Parallel.ForEach(notYetDownloadedPackages, new ParallelOptions { MaxDegreeOfParallelism = DependencyManager.Threads }, package =>
372365
{
373-
var success = TryRestorePackageManually(package.Name, nugetSources, package.PackageReferenceSource, tryWithoutNugetConfig: fallbackNugetFeeds is null);
366+
var success = TryRestorePackageManually(package.Name, nugetSources, package.PackageReferenceSource);
374367
if (!success)
375368
{
376369
return;
@@ -387,32 +380,6 @@ private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<Dep
387380
return missingPackageDirectory.DirInfo.FullName;
388381
}
389382

390-
private string? GetNugetConfig()
391-
{
392-
var nugetConfigs = fileProvider.NugetConfigs;
393-
string? nugetConfig;
394-
if (nugetConfigs.Count > 1)
395-
{
396-
logger.LogInfo($"Found multiple nuget.config files: {string.Join(", ", nugetConfigs)}.");
397-
nugetConfig = fileProvider.RootNugetConfig;
398-
if (nugetConfig == null)
399-
{
400-
logger.LogInfo("Could not find a top-level nuget.config file.");
401-
}
402-
}
403-
else
404-
{
405-
nugetConfig = nugetConfigs.FirstOrDefault();
406-
}
407-
408-
if (nugetConfig != null)
409-
{
410-
logger.LogInfo($"Using nuget.config file {nugetConfig}.");
411-
}
412-
413-
return nugetConfig;
414-
}
415-
416383
private IEnumerable<string> GetAllUsedPackageDirNames(DependencyContainer dependencies)
417384
{
418385
var allPackageDirectories = GetAllPackageDirectories();
@@ -476,8 +443,7 @@ private static IEnumerable<string> GetRestoredPackageDirectoryNames(DirectoryInf
476443
.Select(d => Path.GetFileName(d).ToLowerInvariant());
477444
}
478445

479-
private bool TryRestorePackageManually(string package, string? nugetSources = null, PackageReferenceSource packageReferenceSource = PackageReferenceSource.SdkCsProj,
480-
bool tryWithoutNugetConfig = true, bool tryPrereleaseVersion = true)
446+
private bool TryRestorePackageManually(string package, string? nugetSources, PackageReferenceSource packageReferenceSource = PackageReferenceSource.SdkCsProj, bool tryPrereleaseVersion = true)
481447
{
482448
logger.LogInfo($"Restoring package {package}...");
483449
using var tempDir = new TemporaryDirectory(
@@ -505,7 +471,7 @@ private bool TryRestorePackageManually(string package, string? nugetSources = nu
505471
return true;
506472
}
507473

508-
if (tryWithoutNugetConfig && res.HasNugetPackageSourceError && nugetSources is not null && !feedManager.CheckNugetFeedResponsiveness)
474+
if (!feedManager.CheckNugetFeedResponsiveness && res.HasNugetPackageSourceError && nugetSources is not null)
509475
{
510476
logger.LogDebug($"Trying to restore '{package}' without nuget.config.");
511477
// Restore could not be completed because the listed source is unavailable. Try without the nuget.config:

0 commit comments

Comments
 (0)