diff --git a/src/chocolatey/GetChocolatey.cs b/src/chocolatey/GetChocolatey.cs index c8883f2192..7c58d2fd99 100644 --- a/src/chocolatey/GetChocolatey.cs +++ b/src/chocolatey/GetChocolatey.cs @@ -222,6 +222,15 @@ public IEnumerable List() var runner = new GenericRunner(); return runner.list(configuration, _container, isConsole: false, parseArgs: null); } + + public int Count() + { + extract_resources(); + var configuration = create_configuration(new List()); + configuration.RegularOutput = true; + var runner = new GenericRunner(); + return runner.count(configuration, _container, isConsole: false, parseArgs: null); + } } // ReSharper restore InconsistentNaming diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs index 1855be78ec..32cce2b02b 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs @@ -140,6 +140,12 @@ public IEnumerable list(ChocolateyConfiguration configuration) return _packageService.list_run(configuration); } + public int count(ChocolateyConfiguration config) + { + config.QuietOutput = true; + return _packageService.count_run(config); + } + public bool may_require_admin_access() { return false; diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateySourceCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateySourceCommand.cs index d82876812a..c13331b055 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateySourceCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateySourceCommand.cs @@ -148,6 +148,11 @@ public IEnumerable list(ChocolateyConfiguration configuration) return _configSettingsService.source_list(configuration); } + public int count(ChocolateyConfiguration config) + { + return list(config).Count(); + } + public bool may_require_admin_access() { return true; diff --git a/src/chocolatey/infrastructure.app/nuget/NugetList.cs b/src/chocolatey/infrastructure.app/nuget/NugetList.cs index 88c573311e..8eea75bbac 100644 --- a/src/chocolatey/infrastructure.app/nuget/NugetList.cs +++ b/src/chocolatey/infrastructure.app/nuget/NugetList.cs @@ -17,6 +17,7 @@ namespace chocolatey.infrastructure.app.nuget { using System.Collections.Generic; using System.Linq; + using NuGet; using configuration; @@ -25,13 +26,48 @@ namespace chocolatey.infrastructure.app.nuget public static class NugetList { public static IEnumerable GetPackages(ChocolateyConfiguration configuration, ILogger nugetLogger) + { + return execute_package_search(configuration, nugetLogger); + } + + + public static int GetCount(ChocolateyConfiguration configuration, ILogger nugetLogger) + { + return execute_package_search(configuration, nugetLogger).Count(); + } + + private static IQueryable execute_package_search(ChocolateyConfiguration configuration, ILogger nugetLogger) { var packageRepository = NugetCommon.GetRemoteRepository(configuration, nugetLogger); + + // Whether or not the package is remote determines two things: + // 1. Does the repository have a notion of "listed"? + // 2. Does it support prerelease in a straight-forward way? + // Choco previosly dealt with this by taking the path of least resistance and manually filtering out and sort unwanted packages + // This result in blocking operations that didn't let service based repositories, like OData, take care of heavy lifting on the server. + bool isRemote; + var aggregateRepo = packageRepository as AggregateRepository; + if (aggregateRepo != null) + { + isRemote = aggregateRepo.Repositories.All(repo => repo is IServiceBasedRepository); + } + else + { + isRemote = packageRepository is IServiceBasedRepository; + } + IQueryable results = packageRepository.Search(configuration.Input, configuration.Prerelease); if (configuration.AllVersions) { - return results.Where(PackageExtensions.IsListed).OrderBy(p => p.Id); + if (isRemote) + { + return results.OrderBy(p => p.Id); + } + else + { + return results.Where(PackageExtensions.IsListed).OrderBy(p => p.Id).AsQueryable(); + } } if (configuration.Prerelease && packageRepository.SupportsPrereleasePackages) @@ -43,17 +79,25 @@ public static IEnumerable GetPackages(ChocolateyConfiguration configur results = results.Where(p => p.IsLatestVersion); } + if (!isRemote) + { + results = + results + .Where(PackageExtensions.IsListed) + .Where(p => configuration.Prerelease || p.IsReleaseVersion()) + .distinct_last(PackageEqualityComparer.Id, PackageComparer.Version) + .AsQueryable(); + } + if (configuration.ListCommand.Page.HasValue) { results = results.Skip(configuration.ListCommand.PageSize * configuration.ListCommand.Page.Value).Take(configuration.ListCommand.PageSize); } - return results.OrderBy(p => p.Id) - .AsEnumerable() - .Where(PackageExtensions.IsListed) - .Where(p => configuration.Prerelease || p.IsReleaseVersion()) - .distinct_last(PackageEqualityComparer.Id, PackageComparer.Version); - } + return results.OrderBy(p => p.Id); + } + + } // ReSharper restore InconsistentNaming diff --git a/src/chocolatey/infrastructure.app/runners/GenericRunner.cs b/src/chocolatey/infrastructure.app/runners/GenericRunner.cs index 5347cec8c3..43f78e6150 100644 --- a/src/chocolatey/infrastructure.app/runners/GenericRunner.cs +++ b/src/chocolatey/infrastructure.app/runners/GenericRunner.cs @@ -150,6 +150,24 @@ public IEnumerable list(ChocolateyConfiguration config, Container containe } } + public int count(ChocolateyConfiguration config, Container container, bool isConsole, Action parseArgs) + { + var command = find_command(config, container, isConsole, parseArgs) as IListCommand; + if (command == null) + { + if (!string.IsNullOrWhiteSpace(config.CommandName)) + { + throw new Exception("The implementation of '{0}' does not support listing.".format_with(config.CommandName)); + } + return 0; + } + else + { + this.Log().Debug("_ {0}:{1} - Normal Count Mode _".format_with(ApplicationParameters.Name, command.GetType().Name)); + return command.count(config); + } + } + public void warn_when_admin_needs_elevation(ChocolateyConfiguration config) { var shouldWarn = (!config.Information.IsProcessElevated && config.Information.IsUserAdministrator); diff --git a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs index 0e49b6fd98..f2646fde41 100644 --- a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs +++ b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs @@ -70,6 +70,11 @@ public void ensure_source_app_installed(ChocolateyConfiguration config) perform_source_runner_action(config, r => r.ensure_source_app_installed(config, (packageResult) => handle_package_result(packageResult, config, CommandNameType.install))); } + public int count_run(ChocolateyConfiguration config) + { + return perform_source_runner_function(config, r => r.count_run(config)); + } + private void perform_source_runner_action(ChocolateyConfiguration config, Action action) { var runner = _sourceRunners.FirstOrDefault(r => r.SourceType == config.SourceType); diff --git a/src/chocolatey/infrastructure.app/services/CygwinService.cs b/src/chocolatey/infrastructure.app/services/CygwinService.cs index c94681202b..911f87b896 100644 --- a/src/chocolatey/infrastructure.app/services/CygwinService.cs +++ b/src/chocolatey/infrastructure.app/services/CygwinService.cs @@ -156,6 +156,11 @@ public void ensure_source_app_installed(ChocolateyConfiguration config, Action

The configuration. void ensure_source_app_installed(ChocolateyConfiguration config); + ///

+ /// Retrieves the count of items that meet the search criteria. + /// + /// + /// + int count_run(ChocolateyConfiguration config); + /// /// Run list in noop mode /// diff --git a/src/chocolatey/infrastructure.app/services/ISourceRunner.cs b/src/chocolatey/infrastructure.app/services/ISourceRunner.cs index ac9826ddfd..c881f10a64 100644 --- a/src/chocolatey/infrastructure.app/services/ISourceRunner.cs +++ b/src/chocolatey/infrastructure.app/services/ISourceRunner.cs @@ -39,6 +39,13 @@ public interface ISourceRunner /// The action to continue with as part of the install void ensure_source_app_installed(ChocolateyConfiguration config, Action ensureAction); + /// + /// Retrieve the listed packages from the source feed cout + /// + /// The configuration. + /// Packages count + int count_run(ChocolateyConfiguration config); + /// /// Run list in noop mode /// diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index 64e0765d56..73666510d3 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -75,6 +75,27 @@ public void ensure_source_app_installed(ChocolateyConfiguration config, Action

: ICommand + public interface IListCommand : ICommand + { + int count(ChocolateyConfiguration config); + } + + public interface IListCommand : IListCommand { IEnumerable list(ChocolateyConfiguration config); }