Skip to content

Commit 906a323

Browse files
authored
Improved handling of local dependencies, e.g. Http depending on Primitives. (#5714)
1 parent a16f346 commit 906a323

File tree

1 file changed

+73
-21
lines changed
  • src/System.Private.ServiceModel/tools/PackageChecker

1 file changed

+73
-21
lines changed

src/System.Private.ServiceModel/tools/PackageChecker/Program.cs

Lines changed: 73 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ private static async Task<int> Main(FileInfo package, bool verbose)
3939
return 1;
4040
}
4141

42-
var dependencies = await DownloadNugetPackageDependenciesAsync(packageReader, verbose);
42+
var dependencies = await DownloadNugetPackageDependenciesAsync(packageReader, package.DirectoryName, verbose);
4343
Console.WriteLine("Downloaded all dependencies");
4444
foreach (var tfm in supportedFrameworks)
4545
{
@@ -325,7 +325,7 @@ private static bool CheckNetstandardToNetFxTypeForwards(PackageReaderBase packag
325325
}
326326
}
327327

328-
private static async Task<Dictionary<NuGetFramework, List<string>>> DownloadNugetPackageDependenciesAsync(PackageReaderBase packageReader, bool verbose)
328+
private static async Task<Dictionary<NuGetFramework, List<string>>> DownloadNugetPackageDependenciesAsync(PackageReaderBase packageReader, string packageLocation, bool verbose)
329329
{
330330
Dictionary<NuGetFramework, List<string>> dependencies = new();
331331

@@ -338,7 +338,7 @@ private static async Task<Dictionary<NuGetFramework, List<string>>> DownloadNuge
338338
if (verbose) { Console.WriteLine($"Getting dependencies for tfm: {tfm.GetFrameworkString()}"); }
339339
foreach (var dependency in group.Packages)
340340
{
341-
List<string> implementationPath = await DownloadNugetPackageAndGetImplementationPathsAsync(dependency, group.TargetFramework, verbose);
341+
List<string> implementationPath = await DownloadNugetPackageAndGetImplementationPathsAsync(dependency, group.TargetFramework, packageLocation, verbose);
342342
if (implementationPath == null)
343343
{
344344
Console.Error.WriteLine($"Failed to download {dependency.Id} {dependency.VersionRange} for {tfm}, may fail later");
@@ -365,17 +365,30 @@ private static async Task<Dictionary<NuGetFramework, List<string>>> DownloadNuge
365365
return dependencies;
366366
}
367367

368-
private static async Task<List<string>> DownloadNugetPackageAndGetImplementationPathsAsync(PackageDependency dependency, NuGetFramework tfm, bool verbose)
368+
private static async Task<List<string>> DownloadNugetPackageAndGetImplementationPathsAsync(PackageDependency dependency, NuGetFramework tfm, string packageLocation, bool verbose)
369369
{
370370
// TODO: Wire up proper logging
371371
// TODO: Wire up proper cancellation token
372372

373+
bool isServiceModelDependency = dependency.Id.StartsWith("System.ServiceModel.");
374+
373375
// Define the package sources
374-
var packageSources = new List<PackageSource>
376+
List<PackageSource> packageSources;
377+
if (isServiceModelDependency)
378+
{
379+
packageSources = new List<PackageSource>
380+
{
381+
new PackageSource(packageLocation)
382+
};
383+
}
384+
else
375385
{
376-
new PackageSource("https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json"),
377-
new PackageSource("https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json")
378-
};
386+
packageSources = new List<PackageSource>
387+
{
388+
new PackageSource("https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json"),
389+
new PackageSource("https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json")
390+
};
391+
}
379392

380393
// Create the source repositories
381394
var sourceRepositories = new List<SourceRepository>();
@@ -387,32 +400,50 @@ private static async Task<List<string>> DownloadNugetPackageAndGetImplementation
387400
var logger = NullLogger.Instance;
388401
var cacheContext = new SourceCacheContext();
389402
var downloadContext = new PackageDownloadContext(cacheContext);
390-
var globalPackagesFolder = SettingsUtility.GetGlobalPackagesFolder(Settings.LoadDefaultSettings(null));
403+
string packagesDownloadFolder;
404+
if (isServiceModelDependency)
405+
{
406+
packagesDownloadFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
407+
Directory.CreateDirectory(packagesDownloadFolder);
408+
if (verbose) { Console.WriteLine($"Using temporary packages folder {packagesDownloadFolder} to install {dependency.Id}"); }
409+
}
410+
else
411+
{
412+
packagesDownloadFolder = SettingsUtility.GetGlobalPackagesFolder(Settings.LoadDefaultSettings(null));
413+
}
391414

392415
// Loop through the repositories to find and download the package
393416
foreach (var repository in sourceRepositories)
394417
{
395-
var findPackageByIdResource = await repository.GetResourceAsync<FindPackageByIdResource>();
396-
// Find all versions that match the version range
397-
var allVersions = await findPackageByIdResource.GetAllVersionsAsync(dependency.Id, cacheContext, logger, default);
398-
if (allVersions == null)
418+
NuGetVersion matchedVersion;
419+
if (isServiceModelDependency)
399420
{
400-
if (verbose) { Console.WriteLine($"Didn't find package {dependency.Id} in repository {repository.PackageSource.SourceUri}"); }
401-
continue;
421+
matchedVersion = dependency.VersionRange.MinVersion;
402422
}
403-
var matchedVersion = allVersions.Where(dependency.VersionRange.Satisfies).OrderByDescending(v => v).FirstOrDefault();
404-
if (matchedVersion == null)
423+
else
405424
{
406-
if (verbose) { Console.WriteLine($"No version found that satisfies the {dependency.Id} package version range {dependency.VersionRange.ToNormalizedString()}."); }
407-
continue;
425+
var findPackageByIdResource = await repository.GetResourceAsync<FindPackageByIdResource>();
426+
// Find all versions that match the version range
427+
var allVersions = await findPackageByIdResource.GetAllVersionsAsync(dependency.Id, cacheContext, logger, default);
428+
if (allVersions == null)
429+
{
430+
if (verbose) { Console.WriteLine($"Didn't find package {dependency.Id} in repository {repository.PackageSource.SourceUri}"); }
431+
continue;
432+
}
433+
matchedVersion = allVersions.Where(dependency.VersionRange.Satisfies).OrderByDescending(v => v).FirstOrDefault();
434+
if (matchedVersion == null)
435+
{
436+
if (verbose) { Console.WriteLine($"No version found that satisfies the {dependency.Id} package version range {dependency.VersionRange.ToNormalizedString()}."); }
437+
continue;
438+
}
408439
}
409440

410441
// Get the DownloadResource and download the package
411442
var downloadResource = await repository.GetResourceAsync<DownloadResource>();
412443
var downloadResult = await downloadResource.GetDownloadResourceResultAsync(
413444
new PackageIdentity(dependency.Id, matchedVersion),
414445
downloadContext,
415-
globalPackagesFolder,
446+
packagesDownloadFolder,
416447
logger,
417448
CancellationToken.None);
418449

@@ -425,14 +456,35 @@ private static async Task<List<string>> DownloadNugetPackageAndGetImplementation
425456
return null; // Returning instead of continuing as we found the package with the right version but no compatible TFM. We won't find the right version elsewhere.
426457
}
427458

428-
var packageExtractPath = Path.Combine(globalPackagesFolder, dependency.Id, matchedVersion.ToNormalizedString());
459+
var packageExtractPath = Path.Combine(packagesDownloadFolder, dependency.Id, matchedVersion.ToNormalizedString());
429460
var libItems = downloadResult.PackageReader.GetLibItems().Where(fsg => fsg.TargetFramework.Equals(packageTfmToUse)).FirstOrDefault();
430461
if (libItems == null)
431462
{
432463
Console.WriteLine($"No lib items found for {packageTfmToUse} in {dependency.Id} {matchedVersion}");
433464
return null;
434465
}
435466

467+
if (isServiceModelDependency)
468+
{
469+
// GetDownloadResourceResultAsync doesn't extract the package if it's local, so we need to do it ourselves
470+
Directory.CreateDirectory(packageExtractPath);
471+
foreach(var file in libItems.Items.Where(i => i.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)))
472+
{
473+
var targetPath = Path.Combine(packageExtractPath, file);
474+
var directoryPath = Path.GetDirectoryName(targetPath);
475+
if (!string.IsNullOrEmpty(directoryPath))
476+
{
477+
Directory.CreateDirectory(directoryPath);
478+
}
479+
480+
using (var fileStream = downloadResult.PackageReader.GetStream(file))
481+
using (var outStream = new FileStream(targetPath, FileMode.Create, FileAccess.Write, FileShare.None))
482+
{
483+
await fileStream.CopyToAsync(outStream);
484+
}
485+
}
486+
}
487+
436488
return libItems.Items.Where(i => i.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)).Select(i => Path.Combine(packageExtractPath, i)).ToList();
437489
}
438490
}

0 commit comments

Comments
 (0)