| File: Utility\AddPackageCommandUtility.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.CommandLine.XPlat\NuGet.CommandLine.XPlat.csproj (NuGet.CommandLine.XPlat) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. #nullable disable using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using NuGet.Common; using NuGet.Configuration; using NuGet.Protocol; using NuGet.Protocol.Core.Types; using NuGet.Versioning; namespace NuGet.CommandLine.XPlat.Utility { internal static class AddPackageCommandUtility { /// <summary> /// Return the latest version available in the sources /// </summary> /// <param name="sources">Sources to look at</param> /// <param name="logger">Logger</param> /// <param name="packageId">Package to look for</param> /// <param name="prerelease">Whether to include prerelease versions</param> /// <param name="cancellationToken"></param> /// <returns>Return the latest version available from multiple sources and if no version is found returns null.</returns> public static async Task<NuGetVersion> GetLatestVersionFromSourcesAsync(IList<PackageSource> sources, ILogger logger, string packageId, bool prerelease, CancellationToken cancellationToken) { var maxTasks = Environment.ProcessorCount; var tasks = new List<Task<NuGetVersion>>(); var latestReleaseList = new List<NuGetVersion>(); foreach (var source in sources) { tasks.Add(Task.Run(() => GetLatestVersionFromSourceAsync(source, logger, packageId, prerelease, cancellationToken))); if (maxTasks <= tasks.Count) { var finishedTask = await Task.WhenAny(tasks); tasks.Remove(finishedTask); latestReleaseList.Add(await finishedTask); } } await Task.WhenAll(tasks); foreach (var t in tasks) { var result = await t; if (result != null) { latestReleaseList.Add(result); } } return latestReleaseList.Max(); } /// <summary> /// Return the latest version of the source /// </summary> /// <param name="source">Source to look at</param> /// <param name="logger">Logger</param> /// <param name="packageId">Package to look for</param> /// <param name="prerelease">Whether to include prerelease versions</param> /// <param name="cancellationToken"></param> /// <returns>Returns the latest version available from a source or a null if non is found.</returns> public static async Task<NuGetVersion> GetLatestVersionFromSourceAsync(PackageSource source, ILogger logger, string packageId, bool prerelease, CancellationToken cancellationToken) { SourceRepository repository = Repository.Factory.GetCoreV3(source); PackageMetadataResource resource = await repository.GetResourceAsync<PackageMetadataResource>(cancellationToken); using (var cache = new SourceCacheContext()) { IEnumerable<IPackageSearchMetadata> packages = await resource.GetMetadataAsync( packageId, includePrerelease: prerelease, includeUnlisted: false, cache, logger, CancellationToken.None ); return packages?.Max(x => x.Identity.Version); } } /// <summary> /// Returns the PackageSource with its credentials if available /// </summary> /// <param name="requestedSources">Sources to match</param> /// <param name="configFilePaths">Config to use for credentials</param> /// <returns>Return a list of package sources</returns> public static List<PackageSource> EvaluateSources(IList<PackageSource> requestedSources, IList<string> configFilePaths) { using (var settingsLoadingContext = new SettingsLoadingContext()) { ISettings settings = Settings.LoadImmutableSettingsGivenConfigPaths(configFilePaths, settingsLoadingContext); var packageSources = new List<PackageSource>(); var packageSourceProvider = new PackageSourceProvider(settings); IEnumerable<PackageSource> packageProviderSources = packageSourceProvider.LoadPackageSources(); for (int i = 0; i < requestedSources.Count; i++) { PackageSource matchedSource = packageProviderSources.FirstOrDefault(e => e.Source == requestedSources[i].Source); if (matchedSource == null) { packageSources.Add(requestedSources[i]); } else { packageSources.Add(matchedSource); } } return packageSources; } } } }