Skip to content

Commit

Permalink
Load packages from local cache only, to avoid network access.
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-englert committed Sep 14, 2023
1 parent 78145a6 commit 676ecea
Showing 1 changed file with 43 additions and 52 deletions.
95 changes: 43 additions & 52 deletions src/LicenseGenerator/Builder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
using NuGet.Packaging;
using NuGet.Packaging.Core;
using NuGet.ProjectModel;
using NuGet.Protocol.Core.Types;
using NuGet.Protocol;
using NuGet.Versioning;

using TomsToolbox.Essentials;
Expand Down Expand Up @@ -89,11 +89,8 @@ public async Task<int> Build()

private async Task<ICollection<PackageArchiveReader>> LoadPackages()
{
var packageSourceProvider = new PackageSourceProvider(Settings.LoadDefaultSettings(_solutionDirectory));
var sourceRepositoryProvider = new SourceRepositoryProvider(packageSourceProvider, Repository.Provider.GetCoreV3());
var repositories = sourceRepositoryProvider.GetRepositories().ToArray();

using var cacheContext = new SourceCacheContext();
var settings = Settings.LoadDefaultSettings(_solutionDirectory);
var globalPackagesFolder = SettingsUtility.GetGlobalPackagesFolder(settings);

var resolvedPackages = new Dictionary<string, PackageArchiveReader>(StringComparer.OrdinalIgnoreCase);

Expand All @@ -105,7 +102,7 @@ private async Task<ICollection<PackageArchiveReader>> LoadPackages()
{
foreach (var packageIdentity in GetPackageIdentities(frameworkSpecificProject))
{
await LoadPackage(frameworkSpecificProject, packageIdentity, repositories, cacheContext, resolvedPackages);
await LoadPackage(frameworkSpecificProject, packageIdentity, resolvedPackages, globalPackagesFolder);
}
}
}
Expand Down Expand Up @@ -182,7 +179,7 @@ private static NuGetFramework ToPlatformVersionIndependent(NuGetFramework framew
?? NuGetFrameworkUtility.GetNearest(items, ToPlatformVersionIndependent(framework), item => ToPlatformVersionIndependent(item.TargetFramework));
}

private async Task LoadPackage(FrameworkSpecificProject project, PackageIdentity packageIdentity, SourceRepository[] repositories, SourceCacheContext cacheContext, Dictionary<string, PackageArchiveReader> resolvedPackages)
private async Task LoadPackage(FrameworkSpecificProject project, PackageIdentity packageIdentity, IDictionary<string, PackageArchiveReader> resolvedPackages, string globalPackagesFolder)
{
if (resolvedPackages.TryGetValue(packageIdentity.Id, out var existingPackage) && existingPackage.GetIdentity().Version >= packageIdentity.Version)
{
Expand All @@ -191,66 +188,60 @@ private async Task LoadPackage(FrameworkSpecificProject project, PackageIdentity

Output.WriteLine($"Load: {packageIdentity}");

foreach (var repository in repositories)
var localCached = GlobalPackagesFolderUtility.GetPackage(packageIdentity, globalPackagesFolder);
if (localCached == null)
{
var resource = await repository.GetResourceAsync<FindPackageByIdResource>();

var packageStream = new MemoryStream();
if (!await resource.CopyNupkgToStreamAsync(packageIdentity.Id, packageIdentity.Version, packageStream, cacheContext, NullLogger.Instance, CancellationToken.None).ConfigureAwait(false))
continue; // Try next repo
throw new InvalidOperationException($"Unable to find package {packageIdentity} in the local cache, restoring nuget packages first may fix this.");
}

packageStream.Position = 0;
if (packageStream.Length == 0)
continue; // Try next repo
var packageStream = localCached.PackageStream;
packageStream.Position = 0;

var package = new PackageArchiveReader(packageStream);
var package = new PackageArchiveReader(packageStream);

resolvedPackages[packageIdentity.Id] = package;
resolvedPackages[packageIdentity.Id] = package;

await using var nuspec = package.GetNuspec();
await using var nuspec = package.GetNuspec();

bool ScanDependencies()
{
// Don't scan packages with pseudo-references, they don't get physically included.
if (string.Equals(packageIdentity.Id, "NETStandard.Library", StringComparison.OrdinalIgnoreCase))
return false;
bool ScanDependencies()
{
// Don't scan packages with pseudo-references, they don't get physically included.
if (string.Equals(packageIdentity.Id, "NETStandard.Library", StringComparison.OrdinalIgnoreCase))
return false;

if (_recursive)
return true;
if (_recursive)
return true;

if (!string.IsNullOrEmpty(new NuspecReader(nuspec).GetProjectUrl()))
return false;
if (!string.IsNullOrEmpty(new NuspecReader(nuspec).GetProjectUrl()))
return false;

Output.WriteLine($" - No project url found in {packageIdentity}, scanning dependencies");
return true;
Output.WriteLine($" - No project url found in {packageIdentity}, scanning dependencies");
return true;

}
}

if (!ScanDependencies())
return;
if (!ScanDependencies())
return;

var packageDependencies = package.GetPackageDependencies()?.ToArray();
if (packageDependencies is null)
return;
var packageDependencies = package.GetPackageDependencies()?.ToArray();
if (packageDependencies is null)
return;

var bestMatching = GetNearestFramework(packageDependencies, project.TargetFramework);
var dependencies = bestMatching?.Packages
?? packageDependencies.SelectMany(item => item.Packages).Distinct();
var bestMatching = GetNearestFramework(packageDependencies, project.TargetFramework);
var dependencies = bestMatching?.Packages
?? packageDependencies.SelectMany(item => item.Packages).Distinct();

foreach (var dependency in dependencies)
foreach (var dependency in dependencies)
{
try
{
try
{
var identity = GetPackageIdentity(project, dependency.Id);
await LoadPackage(project, identity, repositories, cacheContext, resolvedPackages);
}
catch (InvalidOperationException)
{
// Ignore dependencies that can't be loaded.
}
var identity = GetPackageIdentity(project, dependency.Id);
await LoadPackage(project, identity, resolvedPackages, globalPackagesFolder);
}
catch (InvalidOperationException)
{
// Ignore dependencies that can't be loaded.
}

return;
}
}

Expand Down

0 comments on commit 676ecea

Please sign in to comment.