private void uninstall_cleanup(ChocolateyConfiguration config, PackageResult packageResult) { _packageInfoService.remove_package_information(packageResult.Package); ensure_bad_package_path_is_clean(config, packageResult); remove_rollback_if_exists(packageResult); handle_extension_packages(config, packageResult); if (config.Force) { var packageDirectory = _fileSystem.combine_paths(packageResult.InstallLocation); if (string.IsNullOrWhiteSpace(packageDirectory) || !_fileSystem.directory_exists(packageDirectory)) { return; } if (packageDirectory.is_equal_to(ApplicationParameters.InstallLocation) || packageDirectory.is_equal_to(ApplicationParameters.PackagesLocation)) { packageResult.Messages.Add( new ResultMessage( ResultType.Error, "Install location is not specific enough, cannot force remove directory:{0} Erroneous install location captured as '{1}'".format_with(Environment.NewLine, packageResult.InstallLocation) ) ); return; } FaultTolerance.try_catch_with_logging_exception( () => _fileSystem.delete_directory_if_exists(packageDirectory, recursive: true), "Attempted to remove '{0}' but had an error".format_with(packageDirectory), logWarningInsteadOfError: true); } }
public void remove_package_information(IPackage package) { var pkgStorePath = _fileSystem.combine_paths(ApplicationParameters.ChocolateyPackageInfoStoreLocation, "{0}.{1}".format_with(package.Id, package.Version.to_string())); if (_config.RegularOutput) { this.Log().Info("Removing Package Information for {0}".format_with(pkgStorePath)); } _fileSystem.delete_directory_if_exists(pkgStorePath, recursive: true); }
private void remove_existing_rollback_directory(string packageName) { var rollbackDirectory = _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, packageName) + ApplicationParameters.RollbackPackageSuffix; try { _fileSystem.delete_directory_if_exists(rollbackDirectory, recursive: true); } catch (Exception ex) { this.Log().Warn("Attempted to remove '{0}' but had an error:{1} {2}".format_with(rollbackDirectory, Environment.NewLine, ex.Message)); } }
public void remove_rollback_directory_if_exists(string packageName) { var rollbackDirectory = _fileSystem.combine_paths(ApplicationParameters.PackageBackupLocation, packageName); if (!_fileSystem.directory_exists(rollbackDirectory)) { //search for folder var possibleRollbacks = _fileSystem.get_directories(ApplicationParameters.PackageBackupLocation, packageName + "*"); if (possibleRollbacks != null && possibleRollbacks.Count() != 0) { rollbackDirectory = possibleRollbacks.OrderByDescending(p => p).DefaultIfEmpty(string.Empty).FirstOrDefault(); } } if (string.IsNullOrWhiteSpace(rollbackDirectory) || !_fileSystem.directory_exists(rollbackDirectory)) { return; } FaultTolerance.try_catch_with_logging_exception( () => _fileSystem.delete_directory_if_exists(rollbackDirectory, recursive: true), "Attempted to remove '{0}' but had an error:".format_with(rollbackDirectory), logWarningInsteadOfError: true); }
public void remove_package_information(IPackage package) { var pkgStorePath = _fileSystem.combine_paths(ApplicationParameters.ChocolateyPackageInfoStoreLocation, "{0}.{1}".format_with(package.Id, package.Version.to_string())); _fileSystem.delete_directory_if_exists(pkgStorePath, recursive: true); }
public void generate(ChocolateyConfiguration configuration) { var logger = ChocolateyLoggers.Normal; if (configuration.QuietOutput) { logger = ChocolateyLoggers.LogFileOnly; } var packageLocation = _fileSystem.combine_paths(configuration.OutputDirectory ?? _fileSystem.get_current_directory(), configuration.NewCommand.Name); if (_fileSystem.directory_exists(packageLocation) && !configuration.Force) { throw new ApplicationException( "The location for the template already exists. You can:{0} 1. Remove '{1}'{0} 2. Use --force{0} 3. Specify a different name".format_with(Environment.NewLine, packageLocation)); } if (configuration.RegularOutput) { this.Log().Info(logger, () => "Creating a new package specification at {0}".format_with(packageLocation)); } try { _fileSystem.delete_directory_if_exists(packageLocation, recursive: true); } catch (Exception ex) { if (configuration.RegularOutput) { this.Log().Warn(() => "{0}".format_with(ex.Message)); } } _fileSystem.create_directory_if_not_exists(packageLocation); var packageToolsLocation = _fileSystem.combine_paths(packageLocation, "tools"); _fileSystem.create_directory_if_not_exists(packageToolsLocation); var tokens = new TemplateValues(); if (configuration.NewCommand.AutomaticPackage) { tokens.set_auto(); } // now override those values foreach (var property in configuration.NewCommand.TemplateProperties) { try { tokens.GetType().GetProperty(property.Key, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase).SetValue(tokens, property.Value, null); this.Log().Debug(() => "Set token for '{0}' to '{1}'".format_with(property.Key, property.Value)); } catch (Exception) { if (configuration.RegularOutput) { this.Log().Debug("Property {0} will be added to additional properties.".format_with(property.Key)); } tokens.AdditionalProperties.Add(property.Key, property.Value); } } this.Log().Debug(() => "Token Values after merge:"); foreach (var propertyInfo in tokens.GetType().GetProperties()) { this.Log().Debug(() => " {0}={1}".format_with(propertyInfo.Name, propertyInfo.GetValue(tokens, null))); } foreach (var additionalProperty in tokens.AdditionalProperties.or_empty_list_if_null()) { this.Log().Debug(() => " {0}={1}".format_with(additionalProperty.Key, additionalProperty.Value)); } // Attempt to set the name of the template that will be used to generate the new package // If no template name has been passed at the command line, check to see if there is a defaultTemplateName set in the // chocolatey.config file. If there is, and this template exists on disk, use it. // Otherwise, revert to the built in default template. // In addition, if the command line option to use the built-in template has been set, respect that // and use the built in template. var defaultTemplateName = configuration.DefaultTemplateName; if (string.IsNullOrWhiteSpace(configuration.NewCommand.TemplateName) && !string.IsNullOrWhiteSpace(defaultTemplateName) && !configuration.NewCommand.UseOriginalTemplate) { var defaultTemplateNameLocation = _fileSystem.combine_paths(ApplicationParameters.TemplatesLocation, defaultTemplateName); if (!_fileSystem.directory_exists(defaultTemplateNameLocation)) { this.Log().Warn(() => "defaultTemplateName configuration value has been set to '{0}', but no template with that name exists in '{1}'. Reverting to default template.".format_with(defaultTemplateName, ApplicationParameters.TemplatesLocation)); } else { this.Log().Debug(() => "Setting TemplateName to '{0}'".format_with(defaultTemplateName)); configuration.NewCommand.TemplateName = defaultTemplateName; } } var defaultTemplateOverride = _fileSystem.combine_paths(ApplicationParameters.TemplatesLocation, "default"); if (string.IsNullOrWhiteSpace(configuration.NewCommand.TemplateName) && (!_fileSystem.directory_exists(defaultTemplateOverride) || configuration.NewCommand.UseOriginalTemplate)) { generate_file_from_template(configuration, tokens, NuspecTemplate.Template, _fileSystem.combine_paths(packageLocation, "{0}.nuspec".format_with(tokens.PackageNameLower)), utf8WithoutBOM); generate_file_from_template(configuration, tokens, ChocolateyInstallTemplate.Template, _fileSystem.combine_paths(packageToolsLocation, "chocolateyinstall.ps1"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyBeforeModifyTemplate.Template, _fileSystem.combine_paths(packageToolsLocation, "chocolateybeforemodify.ps1"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyUninstallTemplate.Template, _fileSystem.combine_paths(packageToolsLocation, "chocolateyuninstall.ps1"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyLicenseFileTemplate.Template, _fileSystem.combine_paths(packageToolsLocation, "LICENSE.txt"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyVerificationFileTemplate.Template, _fileSystem.combine_paths(packageToolsLocation, "VERIFICATION.txt"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyReadMeTemplate.Template, _fileSystem.combine_paths(packageLocation, "ReadMe.md"), Encoding.UTF8); generate_file_from_template(configuration, tokens, ChocolateyTodoTemplate.Template, _fileSystem.combine_paths(packageLocation, "_TODO.txt"), Encoding.UTF8); } else { configuration.NewCommand.TemplateName = string.IsNullOrWhiteSpace(configuration.NewCommand.TemplateName) ? "default" : configuration.NewCommand.TemplateName; var templatePath = _fileSystem.combine_paths(ApplicationParameters.TemplatesLocation, configuration.NewCommand.TemplateName); if (!_fileSystem.directory_exists(templatePath)) { throw new ApplicationException("Unable to find path to requested template '{0}'. Path should be '{1}'".format_with(configuration.NewCommand.TemplateName, templatePath)); } this.Log().Info(configuration.QuietOutput ? logger : ChocolateyLoggers.Important, "Generating package from custom template at '{0}'.".format_with(templatePath)); // Create directory structure from template so as to include empty directories foreach (var directory in _fileSystem.get_directories(templatePath, "*.*", SearchOption.AllDirectories)) { var packageDirectoryLocation = directory.Replace(templatePath, packageLocation); this.Log().Debug("Creating directory {0}".format_with(packageDirectoryLocation)); _fileSystem.create_directory_if_not_exists(packageDirectoryLocation); } foreach (var file in _fileSystem.get_files(templatePath, "*.*", SearchOption.AllDirectories)) { var packageFileLocation = file.Replace(templatePath, packageLocation); var fileExtension = _fileSystem.get_file_extension(packageFileLocation); if (fileExtension.is_equal_to(".nuspec")) { packageFileLocation = _fileSystem.combine_paths(packageLocation, "{0}.nuspec".format_with(tokens.PackageNameLower)); generate_file_from_template(configuration, tokens, _fileSystem.read_file(file), packageFileLocation, utf8WithoutBOM); } else if (_templateBinaryExtensions.Contains(fileExtension)) { this.Log().Debug(" Treating template file ('{0}') as binary instead of replacing templated values.".format_with(_fileSystem.get_file_name(file))); _fileSystem.copy_file(file, packageFileLocation, overwriteExisting: true); } else { generate_file_from_template(configuration, tokens, _fileSystem.read_file(file), packageFileLocation, Encoding.UTF8); } } } this.Log().Info(configuration.QuietOutput ? logger : ChocolateyLoggers.Important, "Successfully generated {0}{1} package specification files{2} at '{3}'".format_with( configuration.NewCommand.Name, configuration.NewCommand.AutomaticPackage ? " (automatic)" : string.Empty, Environment.NewLine, packageLocation)); }
public ConcurrentDictionary <string, PackageResult> install_run(ChocolateyConfiguration config, Action <PackageResult> continueAction) { _fileSystem.create_directory_if_not_exists(ApplicationParameters.PackagesLocation); var packageInstalls = new ConcurrentDictionary <string, PackageResult>(); //todo: handle all SemanticVersion version = config.Version != null ? new SemanticVersion(config.Version) : null; IList <string> packageNames = config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).or_empty_list_if_null().ToList(); if (packageNames.Count == 1) { var packageName = packageNames.DefaultIfEmpty(string.Empty).FirstOrDefault(); if (packageName.EndsWith(Constants.PackageExtension) || packageName.EndsWith(Constants.ManifestExtension)) { this.Log().Debug("Updating source and package name to handle *.nupkg or *.nuspec file."); packageNames.Clear(); packageNames.Add(_fileSystem.get_file_name_without_extension(packageName)); config.Sources = _fileSystem.get_directory_name(_fileSystem.get_full_path(packageName)); if (packageName.EndsWith(Constants.ManifestExtension)) { this.Log().Debug("Building nuspec file prior to install."); config.Input = packageName; // build package pack_run(config); } } } // this is when someone points the source directly at a nupkg // e.g. -s c:\somelocation\somewhere\packagename.nupkg if (config.Sources.to_string().EndsWith(Constants.PackageExtension)) { config.Sources = _fileSystem.get_directory_name(_fileSystem.get_full_path(config.Sources)); } var packageManager = NugetCommon.GetPackageManager( config, _nugetLogger, installSuccessAction: (e) => { var pkg = e.Package; var results = packageInstalls.GetOrAdd(pkg.Id.to_lower(), new PackageResult(pkg, e.InstallPath)); results.InstallLocation = e.InstallPath; results.Messages.Add(new ResultMessage(ResultType.Debug, ApplicationParameters.Messages.ContinueChocolateyAction)); if (continueAction != null) { continueAction.Invoke(results); } }, uninstallSuccessAction: null, addUninstallHandler: true); foreach (string packageName in packageNames.or_empty_list_if_null()) { //todo: get smarter about realizing multiple versions have been installed before and allowing that remove_rollback_directory_if_exists(packageName); IPackage installedPackage = packageManager.LocalRepository.FindPackage(packageName); if (installedPackage != null && (version == null || version == installedPackage.Version) && !config.Force) { string logMessage = "{0} v{1} already installed.{2} Use --force to reinstall, specify a version to install, or try upgrade.".format_with(installedPackage.Id, installedPackage.Version, Environment.NewLine); var results = packageInstalls.GetOrAdd(packageName, new PackageResult(installedPackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id))); results.Messages.Add(new ResultMessage(ResultType.Warn, logMessage)); results.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); this.Log().Warn(ChocolateyLoggers.Important, logMessage); continue; } if (installedPackage != null && (version == null || version == installedPackage.Version) && config.Force) { this.Log().Debug(() => "{0} v{1} already installed. Forcing reinstall.".format_with(installedPackage.Id, installedPackage.Version)); version = installedPackage.Version; } IPackage availablePackage = packageManager.SourceRepository.FindPackage(packageName, version, config.Prerelease, allowUnlisted: false); if (availablePackage == null) { var logMessage = "{0} not installed. The package was not found with the source(s) listed.{1} If you specified a particular version and are receiving this message, it is possible that the package name exists but the version does not.{1} Version: \"{2}\"{1} Source(s): \"{3}\"".format_with(packageName, Environment.NewLine, config.Version, config.Sources); this.Log().Error(ChocolateyLoggers.Important, logMessage); var results = packageInstalls.GetOrAdd(packageName, new PackageResult(packageName, version.to_string(), null)); results.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); continue; } if (installedPackage != null && (installedPackage.Version == availablePackage.Version) && config.Force) { var results = packageInstalls.GetOrAdd(packageName, new PackageResult(installedPackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id))); results.Messages.Add(new ResultMessage(ResultType.Note, "Backing up and removing old version")); backup_existing_version(config, installedPackage); try { packageManager.UninstallPackage(installedPackage, forceRemove: config.Force, removeDependencies: config.ForceDependencies); if (!results.InstallLocation.is_equal_to(ApplicationParameters.PackagesLocation)) { _fileSystem.delete_directory_if_exists(results.InstallLocation, recursive: true); } } catch (Exception ex) { string logMessage = "{0}:{1} {2}".format_with("Unable to remove existing package prior to forced reinstall", Environment.NewLine, ex.Message); this.Log().Warn(logMessage); results.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); } } try { using (packageManager.SourceRepository.StartOperation( RepositoryOperationNames.Install, packageName, version == null ? null : version.ToString())) { packageManager.InstallPackage(availablePackage, ignoreDependencies: config.IgnoreDependencies, allowPrereleaseVersions: config.Prerelease); //packageManager.InstallPackage(packageName, version, configuration.IgnoreDependencies, configuration.Prerelease); } } catch (Exception ex) { var logMessage = "{0} not installed. An error occurred during installation:{1} {2}".format_with(packageName, Environment.NewLine, ex.Message); this.Log().Error(ChocolateyLoggers.Important, logMessage); var results = packageInstalls.GetOrAdd(packageName, new PackageResult(packageName, version.to_string(), null)); results.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); if (continueAction != null) { continueAction.Invoke(results); } } } return(packageInstalls); }