Skip to content

Commit

Permalink
(chocolateyGH-14) ChocolateyPackageService implement source runners
Browse files Browse the repository at this point in the history
ChocolateyPackageService will determine based on the ISourceRunners it
has in the list on ensuring that an app/tool is installed, and then use
the correct source runner to perform all applicable ISourceRunner
actions.
  • Loading branch information
ferventcoder committed Jun 4, 2015
1 parent e2c0a59 commit 45166b2
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 59 deletions.
194 changes: 135 additions & 59 deletions src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class ChocolateyPackageService : IChocolateyPackageService
{
private readonly INugetService _nugetService;
private readonly IPowershellService _powershellService;
private readonly IEnumerable<ISourceRunner> _sourceRunners;
private readonly IShimGenerationService _shimgenService;
private readonly IFileSystem _fileSystem;
private readonly IRegistryService _registryService;
Expand All @@ -42,12 +43,14 @@ public class ChocolateyPackageService : IChocolateyPackageService
private readonly IXmlService _xmlService;

public ChocolateyPackageService(INugetService nugetService, IPowershellService powershellService,
IShimGenerationService shimgenService, IFileSystem fileSystem, IRegistryService registryService,
IEnumerable<ISourceRunner> sourceRunners, IShimGenerationService shimgenService,
IFileSystem fileSystem, IRegistryService registryService,
IChocolateyPackageInformationService packageInfoService, IFilesService filesService,
IAutomaticUninstallerService autoUninstallerService, IXmlService xmlService)
{
_nugetService = nugetService;
_powershellService = powershellService;
_sourceRunners = sourceRunners;
_shimgenService = shimgenService;
_fileSystem = fileSystem;
_registryService = registryService;
Expand All @@ -57,32 +60,49 @@ public ChocolateyPackageService(INugetService nugetService, IPowershellService p
_xmlService = xmlService;
}

public void list_noop(ChocolateyConfiguration config)
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)));
}

private void perform_source_runner_action(ChocolateyConfiguration config, Action<ISourceRunner> action)
{
if (config.Sources.is_equal_to(SourceType.webpi.to_string()))
var runner = _sourceRunners.FirstOrDefault(r => r.SourceType == config.SourceType);
if (runner != null && action != null)
{
//todo: webpi
action.Invoke(runner);
}
else
{
_nugetService.list_noop(config);
this.Log().Warn("No runner was found that implements source type '{0}' or action was missing".format_with(config.SourceType.to_string()));
}
}

private T perform_source_runner_function<T>(ChocolateyConfiguration config, Func<ISourceRunner, T> function)
{
var runner = _sourceRunners.FirstOrDefault(r => r.SourceType == config.SourceType);
if (runner != null && function != null)
{
return function.Invoke(runner);
}

this.Log().Warn("No runner was found that implements source type '{0}' or function was missing.".format_with(config.SourceType.to_string()));
return default(T);
}

public void list_noop(ChocolateyConfiguration config)
{
perform_source_runner_action(config, r => r.list_noop(config));
}

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

if (config.Sources.is_equal_to(SourceType.webpi.to_string()))
{
//todo: webpi
//install webpi if not installed
//run the webpi command
this.Log().Warn("Command not yet functional, stay tuned...");
}
else
var list = perform_source_runner_function(config, r => r.list_run(config, logResults));

if (config.SourceType == SourceType.normal)
{
var list = _nugetService.list_run(config, logResults: true);
if (config.RegularOutput)
{
this.Log().Warn(() => @"{0} packages {1}.".format_with(list.Count, config.ListCommand.LocalOnly ? "installed" : "found"));
Expand Down Expand Up @@ -129,21 +149,45 @@ private void report_registry_programs(ChocolateyConfiguration config, Concurrent

public void pack_noop(ChocolateyConfiguration config)
{
if (config.SourceType != SourceType.normal)
{
this.Log().Warn(ChocolateyLoggers.Important, "This source doesn't provide a facility for packaging.");
return;
}

_nugetService.pack_noop(config);
}

public void pack_run(ChocolateyConfiguration config)
{
if (config.SourceType != SourceType.normal)
{
this.Log().Warn(ChocolateyLoggers.Important, "This source doesn't provide a facility for packaging.");
return;
}

_nugetService.pack_run(config);
}

public void push_noop(ChocolateyConfiguration config)
{
if (config.SourceType != SourceType.normal)
{
this.Log().Warn(ChocolateyLoggers.Important, "This source doesn't provide a facility for pushing.");
return;
}

_nugetService.push_noop(config);
}

public void push_run(ChocolateyConfiguration config)
{
if (config.SourceType != SourceType.normal)
{
this.Log().Warn(ChocolateyLoggers.Important, "This source doesn't provide a facility for pushing.");
return;
}

_nugetService.push_run(config);
}

Expand All @@ -152,7 +196,13 @@ public void install_noop(ChocolateyConfiguration config)
// each package can specify its own configuration values
foreach (var packageConfig in set_config_from_package_names_and_packages_config(config, new ConcurrentDictionary<string, PackageResult>()).or_empty_list_if_null())
{
_nugetService.install_noop(packageConfig, (pkg) => _powershellService.install_noop(pkg));
Action<PackageResult> action = null;
if (packageConfig.SourceType == SourceType.normal)
{
action = (pkg) => _powershellService.install_noop(pkg);
}

perform_source_runner_action(packageConfig, r => r.install_noop(packageConfig, action));
}
}

Expand Down Expand Up @@ -226,8 +276,6 @@ public void handle_package_result(PackageResult packageResult, ChocolateyConfigu

public ConcurrentDictionary<string, PackageResult> install_run(ChocolateyConfiguration config)
{
//todo:are we installing from an alternate source? If so run that command instead

this.Log().Info(@"Installing the following packages:");
this.Log().Info(ChocolateyLoggers.Important, @"{0}".format_with(config.PackageNames));
this.Log().Info(@"By installing you accept licenses for the packages.");
Expand All @@ -236,10 +284,13 @@ public ConcurrentDictionary<string, PackageResult> install_run(ChocolateyConfigu

foreach (var packageConfig in set_config_from_package_names_and_packages_config(config, packageInstalls).or_empty_list_if_null())
{
var results = _nugetService.install_run(
packageConfig,
(packageResult) => handle_package_result(packageResult, packageConfig, CommandNameType.install)
);
Action<PackageResult> action = null;
if (packageConfig.SourceType == SourceType.normal)
{
action = (packageResult) => handle_package_result(packageResult, packageConfig, CommandNameType.install);
}
var results = perform_source_runner_function(packageConfig, r => r.install_run(packageConfig, action));

foreach (var result in results)
{
packageInstalls.GetOrAdd(result.Key, result.Value);
Expand Down Expand Up @@ -293,6 +344,12 @@ Would have determined packages that are out of date based on what is

public void outdated_run(ChocolateyConfiguration config)
{
if (config.SourceType != SourceType.normal)
{
this.Log().Warn(ChocolateyLoggers.Important, "This source doesn't provide a facility for outdated.");
return;
}

this.Log().Info(ChocolateyLoggers.Important, @"Outdated Packages
Output is package name | current version | available version | pinned?
");
Expand Down Expand Up @@ -380,7 +437,13 @@ private IEnumerable<ChocolateyConfiguration> get_packages_from_config(string pac

public void upgrade_noop(ChocolateyConfiguration config)
{
var noopUpgrades = _nugetService.upgrade_noop(config, (pkg) => _powershellService.install_noop(pkg));
Action<PackageResult> action = null;
if (config.SourceType == SourceType.normal)
{
action = (pkg) => _powershellService.install_noop(pkg);
}

var noopUpgrades = perform_source_runner_function(config, r => r.upgrade_noop(config, action));
if (config.RegularOutput)
{
var upgradeWarnings = noopUpgrades.Count(p => p.Value.Warning);
Expand All @@ -406,8 +469,6 @@ public void upgrade_noop(ChocolateyConfiguration config)

public ConcurrentDictionary<string, PackageResult> upgrade_run(ChocolateyConfiguration config)
{
//todo:are we upgrading an alternate source? If so run that command instead

this.Log().Info(@"Upgrading the following packages:");
this.Log().Info(ChocolateyLoggers.Important, @"{0}".format_with(config.PackageNames));
this.Log().Info(@"By upgrading you accept licenses for the packages.");
Expand All @@ -417,10 +478,13 @@ public ConcurrentDictionary<string, PackageResult> upgrade_run(ChocolateyConfigu
throw new ApplicationException("A packages.config file is only used with installs.");
}

var packageUpgrades = _nugetService.upgrade_run(
config,
(packageResult) => handle_package_result(packageResult, config, CommandNameType.upgrade)
);
Action<PackageResult> action = null;
if (config.SourceType == SourceType.normal)
{
action = (packageResult) => handle_package_result(packageResult, config, CommandNameType.upgrade);
}

var packageUpgrades = perform_source_runner_function(config, r => r.upgrade_run(config, action));

var upgradeFailures = packageUpgrades.Count(p => !p.Value.Success);
var upgradeWarnings = packageUpgrades.Count(p => p.Value.Warning);
Expand Down Expand Up @@ -462,7 +526,13 @@ public ConcurrentDictionary<string, PackageResult> upgrade_run(ChocolateyConfigu

public void uninstall_noop(ChocolateyConfiguration config)
{
_nugetService.uninstall_noop(config, (pkg) => _powershellService.uninstall_noop(pkg));
Action<PackageResult> action = null;
if (config.SourceType == SourceType.normal)
{
action = (pkg) => _powershellService.uninstall_noop(pkg);
}

perform_source_runner_action(config, r => r.uninstall_noop(config, action));
}

public ConcurrentDictionary<string, PackageResult> uninstall_run(ChocolateyConfiguration config)
Expand All @@ -475,37 +545,13 @@ public ConcurrentDictionary<string, PackageResult> uninstall_run(ChocolateyConfi
throw new ApplicationException("A packages.config file is only used with installs.");
}

var packageUninstalls = _nugetService.uninstall_run(
config,
(packageResult) =>
{
if (!_fileSystem.directory_exists(packageResult.InstallLocation))
{
packageResult.InstallLocation += ".{0}".format_with(packageResult.Package.Version.to_string());
}

_shimgenService.uninstall(config, packageResult);

if (!config.SkipPackageInstallProvider)
{
_powershellService.uninstall(config, packageResult);
}

_autoUninstallerService.run(packageResult, config);

if (packageResult.Success)
{
//todo: v2 clean up package information store for things no longer installed (call it compact?)
uninstall_cleanup(config, packageResult);
}
else
{
this.Log().Error(ChocolateyLoggers.Important, "{0} {1} not successful.".format_with(packageResult.Name, "uninstall"));
handle_unsuccessful_operation(config, packageResult, movePackageToFailureLocation: false, attemptRollback: false);
}
Action<PackageResult> action = null;
if (config.SourceType == SourceType.normal)
{
action = (packageResult) => handle_package_uninstall(packageResult, config);
}

//todo:prevent reboots
});
var packageUninstalls = perform_source_runner_function(config, r => r.uninstall_run(config, action));

var uninstallFailures = packageUninstalls.Count(p => !p.Value.Success);
this.Log().Warn(() => @"{0}{1} uninstalled {2}/{3} packages. {4} packages failed.{0} See the log for details ({5}).".format_with(
Expand Down Expand Up @@ -534,6 +580,36 @@ public ConcurrentDictionary<string, PackageResult> uninstall_run(ChocolateyConfi
return packageUninstalls;
}

public void handle_package_uninstall(PackageResult packageResult, ChocolateyConfiguration config)
{
if (!_fileSystem.directory_exists(packageResult.InstallLocation))
{
packageResult.InstallLocation += ".{0}".format_with(packageResult.Package.Version.to_string());
}

_shimgenService.uninstall(config, packageResult);

if (!config.SkipPackageInstallProvider)
{
_powershellService.uninstall(config, packageResult);
}

_autoUninstallerService.run(packageResult, config);

if (packageResult.Success)
{
//todo: v2 clean up package information store for things no longer installed (call it compact?)
uninstall_cleanup(config, packageResult);
}
else
{
this.Log().Error(ChocolateyLoggers.Important, "{0} {1} not successful.".format_with(packageResult.Name, "uninstall"));
handle_unsuccessful_operation(config, packageResult, movePackageToFailureLocation: false, attemptRollback: false);
}

//todo:prevent reboots
}

private void uninstall_cleanup(ChocolateyConfiguration config, PackageResult packageResult)
{
_packageInfoService.remove_package_information(packageResult.Package);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ namespace chocolatey.infrastructure.app.services
/// </summary>
public interface IChocolateyPackageService
{

/// <summary>
/// Ensures the application that controls a source is installed
/// </summary>
/// <param name="config">The configuration.</param>
void ensure_source_app_installed(ChocolateyConfiguration config);

/// <summary>
/// Run list in noop mode
/// </summary>
Expand Down

0 comments on commit 45166b2

Please sign in to comment.