Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(GH-132) List command #225

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ public override void Because()
[Fact]
public void should_call_service_list_run()
{
packageService.Verify(c => c.list_run(configuration, true), Times.Once);
packageService.Verify(c => c.list_run(configuration), Times.Once);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,10 +337,12 @@ public override void Context()
configuration.Sources = ApplicationParameters.PackagesLocation;
configuration.ListCommand.LocalOnly = true;
configuration.AllVersions = true;
var packageResults = new ConcurrentDictionary<string, PackageResult>();
packageResults.GetOrAdd("regular", new PackageResult(package.Object, null));
packageResults.GetOrAdd("pinned", new PackageResult(pinnedPackage.Object, null));
nugetService.Setup(n => n.list_run(It.IsAny<ChocolateyConfiguration>(), false)).Returns(packageResults);
var packageResults = new []
{
new PackageResult(package.Object, null),
new PackageResult(pinnedPackage.Object, null)
};
nugetService.Setup(n => n.list_run(It.IsAny<ChocolateyConfiguration>())).Returns(packageResults);
configuration.PinCommand.Command = PinCommandType.list;
}

Expand Down Expand Up @@ -412,7 +414,7 @@ public void should_call_nuget_service_list_run_when_command_is_list()
configuration.PinCommand.Command = PinCommandType.list;
command.run(configuration);

nugetService.Verify(n => n.list_run(It.IsAny<ChocolateyConfiguration>(), false), Times.Once);
nugetService.Verify(n => n.list_run(It.IsAny<ChocolateyConfiguration>()), Times.Once);
}

[Pending("NuGet is killing me with extension methods. Need to find proper item to mock out to return the package object.")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@
namespace chocolatey.infrastructure.app.commands
{
using System.Collections.Generic;
using System.Linq;
using attributes;
using commandline;
using configuration;
using domain;
using infrastructure.commands;
using logging;
using results;
using services;

[CommandFor(CommandNameType.list)]
[CommandFor(CommandNameType.search)]
public sealed class ChocolateyListCommand : ICommand
public sealed class ChocolateyListCommand : IListCommand<PackageResult>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Jaykul I don't see IListCommand<T> at all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up reimplementing it, but didn't constrain T as I am unsure how you would have constrained it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found that it was already in master only.

{
private readonly IChocolateyPackageService _packageService;

Expand Down Expand Up @@ -60,12 +62,6 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati
public void handle_additional_argument_parsing(IList<string> unparsedArguments, ChocolateyConfiguration configuration)
{
configuration.Input = string.Join(" ", unparsedArguments);

if (configuration.ListCommand.LocalOnly)
{
configuration.Sources = ApplicationParameters.PackagesLocation;
configuration.Prerelease = true;
}
}

public void handle_validation(ChocolateyConfiguration configuration)
Expand Down Expand Up @@ -107,7 +103,15 @@ public void noop(ChocolateyConfiguration configuration)

public void run(ChocolateyConfiguration configuration)
{
_packageService.list_run(configuration, logResults: true);
// you must leave the .ToList() here or else the method won't be evaluated!
_packageService.list_run(configuration).ToList();
}

public IEnumerable<PackageResult> list(ChocolateyConfiguration configuration)
{
configuration.Quiet = true;
// here it's up to the caller to enumerate the results
return _packageService.list_run(configuration);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,9 @@ public void run(ChocolateyConfiguration configuration)

public void list_pins(IPackageManager packageManager, ChocolateyConfiguration config)
{
var localPackages = _nugetService.list_run(config, logResults: false);
foreach (var pkg in localPackages.or_empty_list_if_null())
foreach (var pkg in _nugetService.list_run(config))
{
var pkgInfo = _packageInfoService.get_package_information(pkg.Value.Package);
var pkgInfo = _packageInfoService.get_package_information(pkg.Package);
if (pkgInfo != null && pkgInfo.IsPinned)
{
this.Log().Info(() => "{0}|{1}".format_with(pkgInfo.Package.Id,pkgInfo.Package.Version));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public override void run(ChocolateyConfiguration configuration)
{
if (configuration.ListCommand.LocalOnly)
{
_packageService.list_run(configuration,logResults:true);
_packageService.list_run(configuration);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,19 @@ private void append_output(StringBuilder propertyValues, string append)
public bool Force { get; set; }
public bool Noop { get; set; }
public bool HelpRequested { get; set; }
// TODO: Should just use output levels: Debug, Verbose, Info (Regular), Important, Error (Quiet)
/// <summary>
/// Gets or sets a value indicating whether output should be limited.
/// This supports the --limit-output parameter.
/// </summary>
/// <value><c>true</c> for regular output; <c>false</c> for limited output.</value>
public bool RegularOutput { get; set; }
/// <summary>
/// Gets or sets a value indicating whether console logging should be supressed.
/// This is for use by API calls which surface results in alternate forms.
/// </summary>
/// <value><c>true</c> for no output; <c>false</c> for regular or limited output.</value>
public bool Quiet { get; set; }
public bool PromptForConfirmation { get; set; }
public bool AcceptLicense { get; set; }
public bool AllowUnofficialBuild { get; set; }
Expand Down
16 changes: 9 additions & 7 deletions src/chocolatey/infrastructure.app/nuget/NugetList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace chocolatey.infrastructure.app.nuget

// ReSharper disable InconsistentNaming

public sealed class NugetList
public static class NugetList
{
public static IEnumerable<IPackage> GetPackages(ChocolateyConfiguration configuration, ILogger nugetLogger)
{
Expand All @@ -31,7 +31,8 @@ public static IEnumerable<IPackage> GetPackages(ChocolateyConfiguration configur

if (configuration.AllVersions)
{
return results.Where(PackageExtensions.IsListed).OrderBy(p => p.Id).ToList();
// just trust the server order, don't sort because that's a blocking operation
return results.Where(PackageExtensions.IsListed);
}

if (configuration.Prerelease && packageRepository.SupportsPrereleasePackages)
Expand All @@ -43,11 +44,12 @@ public static IEnumerable<IPackage> GetPackages(ChocolateyConfiguration configur
results = results.Where(p => p.IsLatestVersion);
}

return results.OrderBy(p => p.Id)
.AsEnumerable()
.Where(PackageExtensions.IsListed)
.Where(p => configuration.Prerelease || p.IsReleaseVersion())
.distinct_last(PackageEqualityComparer.Id, PackageComparer.Version).ToList();
// just trust the server order, don't sort because that's a blocking operation
// also don't worry about multiple versions, considering Is*LatestVersion only applies to one
return results.Where(PackageExtensions.IsListed)
.Where(p => configuration.Prerelease || p.IsReleaseVersion());
// .OrderBy(p => p.Id).ThenByDescending(p => p.Version)
// .GroupBy(p => p.Id).Select(g => g.First());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ namespace chocolatey.infrastructure.app.services
using commandline;
using configuration;
using domain;
using filesystem;
using infrastructure.services;
using logging;
using NuGet;
using platforms;
using results;
using tolerance;
using IFileSystem = filesystem.IFileSystem;

public class ChocolateyPackageService : IChocolateyPackageService
public class ChocolateyPackageService : IChocolateyPackageService
{
private readonly INugetService _nugetService;
private readonly IPowershellService _powershellService;
Expand Down Expand Up @@ -64,7 +65,7 @@ public void list_noop(ChocolateyConfiguration config)
}
}

public void list_run(ChocolateyConfiguration config, bool logResults)
public IEnumerable<PackageResult> list_run(ChocolateyConfiguration config)
{
this.Log().Debug(() => "Searching for package information");

Expand All @@ -74,51 +75,68 @@ public void list_run(ChocolateyConfiguration config, bool logResults)
//install webpi if not installed
//run the webpi command
this.Log().Warn("Command not yet functional, stay tuned...");
yield break;
}
else
{
var list = _nugetService.list_run(config, logResults: true);
if (config.RegularOutput)
var packages = new List<IPackage>();

if (config.ListCommand.LocalOnly)
{
config.Sources = ApplicationParameters.PackagesLocation;
config.Prerelease = true;
}
foreach (var package in _nugetService.list_run(config))
{
this.Log().Warn(() => @"{0} packages {1}.".format_with(list.Count, config.ListCommand.LocalOnly ? "installed" : "found"));
if (!config.ListCommand.LocalOnly || !config.ListCommand.IncludeRegistryPrograms)
{
yield return package;
}

if (config.ListCommand.LocalOnly && config.ListCommand.IncludeRegistryPrograms)
if (config.ListCommand.LocalOnly && config.ListCommand.IncludeRegistryPrograms && package.Package != null)
{
report_registry_programs(config, list);
packages.Add(package.Package);
}
}
}
}

private void report_registry_programs(ChocolateyConfiguration config, ConcurrentDictionary<string, PackageResult> list)
{
var itemsToRemoveFromMachine = new List<string>();
foreach (var packageResult in list)
{
if (packageResult.Value != null && packageResult.Value.Package != null)
if (config.ListCommand.LocalOnly && config.ListCommand.IncludeRegistryPrograms)
{
var pkginfo = _packageInfoService.get_package_information(packageResult.Value.Package);
if (pkginfo.RegistrySnapshot == null)
foreach (var installed in report_registry_programs(config, packages))
{
continue;
}
var key = pkginfo.RegistrySnapshot.RegistryKeys.FirstOrDefault();
if (key != null)
{
itemsToRemoveFromMachine.Add(key.DisplayName);
yield return installed;
}
}
}
var machineInstalled = _registryService.get_installer_keys().RegistryKeys.Where((p) => p.is_in_programs_and_features() && !itemsToRemoveFromMachine.Contains(p.DisplayName)).OrderBy((p) => p.DisplayName).Distinct().ToList();
if (machineInstalled.Count != 0)
}

private IEnumerable<PackageResult> report_registry_programs(ChocolateyConfiguration config, IEnumerable<IPackage> list)
{
var itemsToRemoveFromMachine = list.Select(package => _packageInfoService.get_package_information(package)).
Where(p => p.RegistrySnapshot != null).
Select(p => p.RegistrySnapshot.RegistryKeys.FirstOrDefault()).
Where(p => p != null).
Select(p => p.DisplayName).ToList();

var count = 0;
var machineInstalled = _registryService.get_installer_keys().RegistryKeys.
Where((p) => p.is_in_programs_and_features() && !itemsToRemoveFromMachine.Contains(p.DisplayName)).
OrderBy((p) => p.DisplayName).Distinct();
this.Log().Info(() => "");
foreach (var key in machineInstalled)
{
this.Log().Info(() => "");
foreach (var key in machineInstalled.or_empty_list_if_null())
{
this.Log().Info("{0}|{1}".format_with(key.DisplayName, key.DisplayVersion));
if (config.Verbose) this.Log().Info(" InstallLocation: {0}{1} Uninstall:{2}".format_with(key.InstallLocation.escape_curly_braces(), Environment.NewLine, key.UninstallString.escape_curly_braces()));
}
this.Log().Warn(() => @"{0} applications not managed with Chocolatey.".format_with(machineInstalled.Count));
if (config.RegularOutput)
{
this.Log().Info("{0}|{1}".format_with(key.DisplayName, key.DisplayVersion));
if (config.Verbose) this.Log().Info(" InstallLocation: {0}{1} Uninstall:{2}".format_with(key.InstallLocation.escape_curly_braces(), Environment.NewLine, key.UninstallString.escape_curly_braces()));
}
count++;

yield return new PackageResult(key.DisplayName, key.DisplayName, key.InstallLocation);
}

if (config.RegularOutput)
{
this.Log().Warn(() => @"{0} applications not managed with Chocolatey.".format_with(count));
}
}

Expand Down Expand Up @@ -415,7 +433,7 @@ public ConcurrentDictionary<string, PackageResult> uninstall_run(ChocolateyConfi
this.Log().Info(@"Uninstalling the following packages:");
this.Log().Info(ChocolateyLoggers.Important, @"{0}".format_with(config.PackageNames));

foreach (var packageConfigFile in config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).or_empty_list_if_null().Where(p => p.EndsWith(".config")).ToList())
if (config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).or_empty_list_if_null().Any(p => p.EndsWith(".config")))
{
throw new ApplicationException("A packages.config file is only used with installs.");
}
Expand Down Expand Up @@ -635,4 +653,4 @@ private void remove_rollback_if_exists(PackageResult packageResult)
_nugetService.remove_rollback_directory_if_exists(packageResult.Name);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
namespace chocolatey.infrastructure.app.services
{
using System.Collections.Concurrent;
using System.Collections.Generic;
using configuration;
using results;

Expand All @@ -34,9 +35,8 @@ public interface IChocolateyPackageService
/// Lists/searches for packages that meet a search criteria
/// </summary>
/// <param name="config">The configuration.</param>
/// <param name="logResults">Should results be logged?</param>
/// <returns></returns>
void list_run(ChocolateyConfiguration config, bool logResults);
IEnumerable<PackageResult> list_run(ChocolateyConfiguration config);

/// <summary>
/// Run pack in noop mode
Expand Down
3 changes: 2 additions & 1 deletion src/chocolatey/infrastructure.app/services/INugetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace chocolatey.infrastructure.app.services
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using configuration;
using results;

Expand All @@ -34,7 +35,7 @@ public interface INugetService
/// <param name="config">The configuration.</param>
/// <param name="logResults">Should results be logged?</param>
/// <returns></returns>
ConcurrentDictionary<string, PackageResult> list_run(ChocolateyConfiguration config, bool logResults);
IEnumerable<PackageResult> list_run(ChocolateyConfiguration config);

/// <summary>
/// Run pack in noop mode.
Expand Down
Loading