From ff4a1f028cdebb6448b8f1e39cf40f4cf7a3cfec Mon Sep 17 00:00:00 2001 From: Joel Bennett Date: Wed, 11 Mar 2015 01:59:26 -0400 Subject: [PATCH] (GH-132) PackageService / ListCommand List for API Ensure that PackageService and List command are able to list output for API purposes. --- src/chocolatey/chocolatey.csproj | 1 + .../commands/ChocolateyListCommand.cs | 8 +++- .../services/ChocolateyPackageService.cs | 46 +++++++++++++------ .../services/IChocolateyPackageService.cs | 3 +- .../services/NugetService.cs | 2 +- .../infrastructure/commands/IListCommand.cs | 25 ++++++++++ .../infrastructure/results/PackageResult.cs | 32 +++++++++++-- 7 files changed, 98 insertions(+), 19 deletions(-) create mode 100644 src/chocolatey/infrastructure/commands/IListCommand.cs diff --git a/src/chocolatey/chocolatey.csproj b/src/chocolatey/chocolatey.csproj index 7ffb13a536..8eee6d9aeb 100644 --- a/src/chocolatey/chocolatey.csproj +++ b/src/chocolatey/chocolatey.csproj @@ -170,6 +170,7 @@ + diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs index 7d12c3cde1..2bb30a4885 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs @@ -22,11 +22,12 @@ namespace chocolatey.infrastructure.app.commands 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 { private readonly IChocolateyPackageService _packageService; @@ -117,6 +118,11 @@ public void run(ChocolateyConfiguration configuration) _packageService.list_run(configuration, logResults: true); } + public IEnumerable list(ChocolateyConfiguration configuration) + { + return _packageService.list_run(configuration, logResults: false); + } + public bool may_require_admin_access() { return false; diff --git a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs index 1c781faac0..c386f7a2e5 100644 --- a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs +++ b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs @@ -73,7 +73,7 @@ public void list_noop(ChocolateyConfiguration config) } } - public void list_run(ChocolateyConfiguration config, bool logResults) + public IEnumerable list_run(ChocolateyConfiguration config, bool logResults) { this.Log().Debug(() => "Searching for package information"); @@ -83,23 +83,32 @@ 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..."); + return new PackageResult[]{}; } else { - var list = _nugetService.list_run(config, logResults: true); + var list = _nugetService.list_run(config, logResults: logResults).ToList(); if (config.RegularOutput) { - this.Log().Warn(() => @"{0} packages {1}.".format_with(list.Count(), config.ListCommand.LocalOnly ? "installed" : "found")); + this.Log().Warn(() => @"{0} packages {1}.".format_with(list.Count, config.ListCommand.LocalOnly ? "installed" : "found")); + } + if (!config.ListCommand.LocalOnly && !config.ListCommand.IncludeRegistryPrograms) + { + return list; + } - if (config.ListCommand.LocalOnly && config.ListCommand.IncludeRegistryPrograms) - { - report_registry_programs(config, list); - } + // in this case, we need to a list we can enumerate multiple times and append to + + if (config.ListCommand.LocalOnly && config.ListCommand.IncludeRegistryPrograms) + { + report_registry_programs(config, list); } + + return list; } } - private void report_registry_programs(ChocolateyConfiguration config, IEnumerable list) + private void report_registry_programs(ChocolateyConfiguration config, List list) { var itemsToRemoveFromMachine = new List(); foreach (var packageResult in list) @@ -111,6 +120,7 @@ private void report_registry_programs(ChocolateyConfiguration config, IEnumerabl { continue; } + var key = pkginfo.RegistrySnapshot.RegistryKeys.FirstOrDefault(); if (key != null) { @@ -118,16 +128,26 @@ private void report_registry_programs(ChocolateyConfiguration config, IEnumerabl } } } + 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) { this.Log().Info(() => ""); - foreach (var key in machineInstalled.or_empty_list_if_null()) + foreach (var key in machineInstalled) + { + 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())); + } + + list.Add( new PackageResult(key.DisplayName, key.DisplayName, key.InstallLocation) ); + } + + 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())); + this.Log().Warn(() => @"{0} applications not managed with Chocolatey.".format_with(machineInstalled.Count)); } - this.Log().Warn(() => @"{0} applications not managed with Chocolatey.".format_with(machineInstalled.Count)); } } @@ -708,4 +728,4 @@ private void remove_rollback_if_exists(PackageResult packageResult) _nugetService.remove_rollback_directory_if_exists(packageResult.Name); } } -} \ No newline at end of file +} diff --git a/src/chocolatey/infrastructure.app/services/IChocolateyPackageService.cs b/src/chocolatey/infrastructure.app/services/IChocolateyPackageService.cs index 45b0e2f206..66c14895bb 100644 --- a/src/chocolatey/infrastructure.app/services/IChocolateyPackageService.cs +++ b/src/chocolatey/infrastructure.app/services/IChocolateyPackageService.cs @@ -16,6 +16,7 @@ namespace chocolatey.infrastructure.app.services { using System.Collections.Concurrent; + using System.Collections.Generic; using configuration; using results; @@ -36,7 +37,7 @@ public interface IChocolateyPackageService /// The configuration. /// Should results be logged? /// - void list_run(ChocolateyConfiguration config, bool logResults); + IEnumerable list_run(ChocolateyConfiguration config, bool logResults); /// /// Run pack in noop mode diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index d581eacf13..f11d6ff9c0 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -99,7 +99,7 @@ public IEnumerable list_run(ChocolateyConfiguration config, bool this.Log().Debug(() => "{0} {1}".format_with(pkg.Id, pkg.Version.to_string())); } - yield return new PackageResult(pkg, null); + yield return new PackageResult(pkg, null, config.Sources); } if (config.RegularOutput) this.Log().Debug(() => "--- End of List ---"); } diff --git a/src/chocolatey/infrastructure/commands/IListCommand.cs b/src/chocolatey/infrastructure/commands/IListCommand.cs new file mode 100644 index 0000000000..b61daf5504 --- /dev/null +++ b/src/chocolatey/infrastructure/commands/IListCommand.cs @@ -0,0 +1,25 @@ +// Copyright © 2011 - Present RealDimensions Software, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace chocolatey.infrastructure.commands +{ + using System.Collections.Generic; + using app.configuration; + + public interface IListCommand : ICommand + { + IEnumerable list(ChocolateyConfiguration configuration); + } +} \ No newline at end of file diff --git a/src/chocolatey/infrastructure/results/PackageResult.cs b/src/chocolatey/infrastructure/results/PackageResult.cs index 29aaed8f5d..aadd6322b7 100644 --- a/src/chocolatey/infrastructure/results/PackageResult.cs +++ b/src/chocolatey/infrastructure/results/PackageResult.cs @@ -15,7 +15,9 @@ namespace chocolatey.infrastructure.results { - using System.Linq; + using System; + using System.Collections.Generic; + using System.Linq; using NuGet; /// @@ -37,17 +39,41 @@ public bool Warning public string Version { get; private set; } public IPackage Package { get; private set; } public string InstallLocation { get; set; } + public string Source { get; set; } + public string SourceUri { get; set; } - public PackageResult(IPackage package, string installLocation) : this(package.Id.to_lower(), package.Version.to_string(), installLocation) + public PackageResult(IPackage package, string installLocation, string source = null) : this(package.Id.to_lower(), package.Version.to_string(), installLocation) { Package = package; + Source = source; + var sources = new List(); + if (!string.IsNullOrEmpty(source)) + { + sources.AddRange(source.Split(new[] {";", ","}, StringSplitOptions.RemoveEmptyEntries).Select(s => new Uri(s))); + } + + var rp = Package as DataServicePackage; + if (rp != null) + { + SourceUri = rp.DownloadUrl.ToString(); + Source = sources.FirstOrDefault(uri => uri.IsBaseOf(rp.DownloadUrl)).to_string(); + if (string.IsNullOrEmpty(Source)) + { + Source = sources.FirstOrDefault(uri => uri.DnsSafeHost == rp.DownloadUrl.DnsSafeHost).to_string(); + } + } + else + { + Source = sources.FirstOrDefault(uri => uri.IsFile || uri.IsUnc).to_string(); + } } - public PackageResult(string name, string version, string installLocation) + public PackageResult(string name, string version, string installLocation, string source = null) { Name = name; Version = version; InstallLocation = installLocation; + Source = source; } } } \ No newline at end of file