Skip to content

Commit 2054c86

Browse files
committed
C#: Fix buildless fallback restore logic
When dotnet core projects are restored, the dependency manager precisely tracks the referenced package folders. The fallback restore logic ignored the precise usage list and instead considered all subfolders in the restore location to be referenced, even though not all subfolders were added to the dependency list. This meant that packages downloaded in partially successful restores were available on disk, but not added to the dependency list by the normal restore process, and skipped by the fallback restore process. This commit fixes this problem by ensuring that the fallback restore logic doesn't consider all subfolders in the restore location to be referenced, but only those that were added to the dependency list by the normal restore process.
1 parent bed7ab5 commit 2054c86

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

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

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public HashSet<AssemblyLookupLocation> Restore()
109109
if (checkNugetFeedResponsiveness && !CheckFeeds(out explicitFeeds))
110110
{
111111
// 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.
112-
var unresponsiveMissingPackageLocation = DownloadMissingPackagesFromSpecificFeeds(explicitFeeds);
112+
var unresponsiveMissingPackageLocation = DownloadMissingPackagesFromSpecificFeeds([], explicitFeeds);
113113
return unresponsiveMissingPackageLocation is null
114114
? []
115115
: [unresponsiveMissingPackageLocation];
@@ -166,11 +166,11 @@ public HashSet<AssemblyLookupLocation> Restore()
166166
.ToList();
167167
assemblyLookupLocations.UnionWith(paths.Select(p => new AssemblyLookupLocation(p)));
168168

169-
LogAllUnusedPackages(dependencies);
169+
var usedPackageNames = GetAllUsedPackageDirNames(dependencies);
170170

171171
var missingPackageLocation = checkNugetFeedResponsiveness
172-
? DownloadMissingPackagesFromSpecificFeeds(explicitFeeds)
173-
: DownloadMissingPackages();
172+
? DownloadMissingPackagesFromSpecificFeeds(usedPackageNames, explicitFeeds)
173+
: DownloadMissingPackages(usedPackageNames);
174174

175175
if (missingPackageLocation is not null)
176176
{
@@ -297,21 +297,21 @@ private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<Dep
297297
compilationInfoContainer.CompilationInfos.Add(("Failed project restore with package source error", nugetSourceFailures.ToString()));
298298
}
299299

300-
private AssemblyLookupLocation? DownloadMissingPackagesFromSpecificFeeds(HashSet<string>? feedsFromNugetConfigs)
300+
private AssemblyLookupLocation? DownloadMissingPackagesFromSpecificFeeds(IEnumerable<string> usedPackageNames, HashSet<string>? feedsFromNugetConfigs)
301301
{
302302
var reachableFallbackFeeds = GetReachableFallbackNugetFeeds(feedsFromNugetConfigs);
303303
if (reachableFallbackFeeds.Count > 0)
304304
{
305-
return DownloadMissingPackages(fallbackNugetFeeds: reachableFallbackFeeds);
305+
return DownloadMissingPackages(usedPackageNames, fallbackNugetFeeds: reachableFallbackFeeds);
306306
}
307307

308308
logger.LogWarning("Skipping download of missing packages from specific feeds as no fallback Nuget feeds are reachable.");
309309
return null;
310310
}
311311

312-
private AssemblyLookupLocation? DownloadMissingPackages(IEnumerable<string>? fallbackNugetFeeds = null)
312+
private AssemblyLookupLocation? DownloadMissingPackages(IEnumerable<string> usedPackageNames, IEnumerable<string>? fallbackNugetFeeds = null)
313313
{
314-
var alreadyDownloadedPackages = GetRestoredPackageDirectoryNames(PackageDirectory.DirInfo);
314+
var alreadyDownloadedPackages = usedPackageNames.Select(p => p.ToLowerInvariant());
315315
var alreadyDownloadedLegacyPackages = GetRestoredLegacyPackageNames();
316316

317317
var notYetDownloadedPackages = new HashSet<PackageReference>(fileContent.AllPackages);
@@ -418,17 +418,23 @@ private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<Dep
418418
return nugetConfig;
419419
}
420420

421-
private void LogAllUnusedPackages(DependencyContainer dependencies)
421+
private IEnumerable<string> GetAllUsedPackageDirNames(DependencyContainer dependencies)
422422
{
423423
var allPackageDirectories = GetAllPackageDirectories();
424424

425425
logger.LogInfo($"Restored {allPackageDirectories.Count} packages");
426426
logger.LogInfo($"Found {dependencies.Packages.Count} packages in project.assets.json files");
427427

428-
allPackageDirectories
429-
.Where(package => !dependencies.Packages.Contains(package))
428+
var usage = allPackageDirectories.Select(package => (package, isUsed: dependencies.Packages.Contains(package)));
429+
430+
usage
431+
.Where(package => !package.isUsed)
430432
.Order()
431-
.ForEach(package => logger.LogDebug($"Unused package: {package}"));
433+
.ForEach(package => logger.LogDebug($"Unused package: {package.package}"));
434+
435+
return usage
436+
.Where(package => package.isUsed)
437+
.Select(package => package.package);
432438
}
433439

434440
private ICollection<string> GetAllPackageDirectories()

0 commit comments

Comments
 (0)