| File: ListCommand\ListCommandRunner.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Commands\NuGet.Commands.csproj (NuGet.Commands) |
// 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.Globalization; using System.Linq; using System.Threading.Tasks; using NuGet.Common; using NuGet.Configuration; using NuGet.Packaging.Core; using NuGet.Protocol; using NuGet.Protocol.Core.Types; namespace NuGet.Commands { /// <summary> /// Command Runner used to run the business logic for nuget list command /// </summary> public class ListCommandRunner : IListCommandRunner { /// <summary> /// Executes the logic for nuget list command. /// </summary> /// <returns></returns> public async Task ExecuteCommand(ListArgs listArgs) { //Create SourceFeed for each packageSource var sourceFeeds = new List<ListResource>(); // this is to avoid duplicate remote calls in case of duplicate final endpoints (Ex. api/index.json and /api/v2/ point to the same target) var sources = new HashSet<string>(); foreach (PackageSource packageSource in listArgs.ListEndpoints) { var sourceRepository = Repository.Factory.GetCoreV3(packageSource); var feed = await sourceRepository.GetResourceAsync<ListResource>(listArgs.CancellationToken); if (feed != null) { if (sources.Add(feed.Source)) { sourceFeeds.Add(feed); } } else { listArgs.Logger.LogWarning(string.Format(CultureInfo.CurrentCulture, listArgs.ListCommandListNotSupported, packageSource.Source)); } } AvoidHttpSources(listArgs); var allPackages = new List<IEnumerableAsync<IPackageSearchMetadata>>(); var log = listArgs.IsDetailed ? listArgs.Logger : NullLogger.Instance; foreach (var feed in sourceFeeds) { var packagesFromSource = await feed.ListAsync(listArgs.Arguments.FirstOrDefault(), listArgs.Prerelease, listArgs.AllVersions, listArgs.IncludeDelisted, log, listArgs.CancellationToken); allPackages.Add(packagesFromSource); } ComparePackageSearchMetadata comparer = new ComparePackageSearchMetadata(); await PrintPackages(listArgs, new AggregateEnumerableAsync<IPackageSearchMetadata>(allPackages, comparer, comparer).GetEnumeratorAsync()); } private static void AvoidHttpSources(ListArgs listArgs) { List<PackageSource> httpPackageSources = null; foreach (PackageSource packageSource in listArgs.ListEndpoints) { if (packageSource.IsHttp && !packageSource.IsHttps && !packageSource.AllowInsecureConnections) { if (httpPackageSources == null) { httpPackageSources = new(); } httpPackageSources.Add(packageSource); } } if (httpPackageSources != null && httpPackageSources.Count != 0) { if (httpPackageSources.Count == 1) { throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSource_Single, "list", httpPackageSources[0])); } else { throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSources_Multiple, "list", Environment.NewLine + string.Join(Environment.NewLine, httpPackageSources.Select(e => e.Name)))); } } } private class ComparePackageSearchMetadata : IComparer<IPackageSearchMetadata>, IEqualityComparer<IPackageSearchMetadata> { public PackageIdentityComparer _comparer { get; set; } = PackageIdentityComparer.Default; public int Compare(IPackageSearchMetadata x, IPackageSearchMetadata y) { if (ReferenceEquals(x, y)) { return 0; } if (ReferenceEquals(x, null)) { return -1; } if (ReferenceEquals(y, null)) { return 1; } return _comparer.Compare(x.Identity, y.Identity); } public bool Equals(IPackageSearchMetadata x, IPackageSearchMetadata y) { if (ReferenceEquals(x, y)) { return true; } if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) { return false; } return _comparer.Equals(x.Identity, y.Identity); } public int GetHashCode(IPackageSearchMetadata obj) { if (ReferenceEquals(obj, null)) { return 0; } return _comparer.GetHashCode(obj.Identity); } } private async Task PrintPackages(ListArgs listArgs, IEnumeratorAsync<IPackageSearchMetadata> asyncEnumerator) { bool hasPackages = false; if (asyncEnumerator != null) { if (listArgs.IsDetailed) { /*********************************************** * Package-Name * 1.0.0.2010 * This is the package Description * * Package-Name-Two * 2.0.0.2010 * This is the second package Description ***********************************************/ while (await asyncEnumerator.MoveNextAsync()) { var p = asyncEnumerator.Current; listArgs.PrintJustified(0, p.Identity.Id); listArgs.PrintJustified(1, p.Identity.Version.ToFullString()); listArgs.PrintJustified(1, p.Description); if (!string.IsNullOrEmpty(p.LicenseUrl?.OriginalString)) { listArgs.PrintJustified(1, string.Format( CultureInfo.InvariantCulture, listArgs.ListCommandLicenseUrl, p.LicenseUrl.OriginalString)); } Console.WriteLine(); hasPackages = true; } } else { /*********************************************** * Package-Name 1.0.0.2010 * Package-Name-Two 2.0.0.2010 ***********************************************/ while (await asyncEnumerator.MoveNextAsync()) { var p = asyncEnumerator.Current; listArgs.PrintJustified(0, p.Identity.Id + " " + p.Identity.Version.ToFullString()); hasPackages = true; } } } if (!hasPackages) { Console.WriteLine(listArgs.ListCommandNoPackages); } } } }