diff --git a/CHANGELOG.md b/CHANGELOG.md index a0c58cfd5a..50330fdf08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,9 +56,10 @@ If you need the previous behavior, be sure to disable the feature `usePackageExi * Provide PowerShell tab completion for Chocolatey - see [#412](https://github.com/chocolatey/choco/issues/412) * [Security] Sign the powershell scripts and assemblies - see [#501](https://github.com/chocolatey/choco/issues/501) * Add a `choco info` command to show info for one package - see [#644](https://github.com/chocolatey/choco/issues/644) + * Resolve sources by name - see [#356](https://github.com/chocolatey/choco/issues/356) * Pro/Business - Ubiquitous Install Directory Switch - see [#258](https://github.com/chocolatey/choco/issues/258) - * Pro/Business - Runtime Virus Scanning - see [virus scanning](https://www.kickstarter.com/projects/ferventcoder/chocolatey-the-alternative-windows-store-like-yum/posts/1518468) - * Pro/Business - Permanent private download location - see [alternate download location](https://www.kickstarter.com/projects/ferventcoder/chocolatey-the-alternative-windows-store-like-yum/posts/1479944) + * Pro/Business - Runtime Virus Scanning - see [virus scanning](https://chocolatey.org/docs/features-virus-check) + * Pro/Business - Private CDN cache for downloads - see [private CDN cache](https://chocolatey.org/docs/features-private-cdn) ### BUG FIXES @@ -89,6 +90,7 @@ If you need the previous behavior, be sure to disable the feature `usePackageExi * [POSH Host] Fix - Write-Host adding multiple line breaks - see [#672](https://github.com/chocolatey/choco/issues/672) * [POSH Host] Fix - PowerShell Host doesn't show colorization overrides - see [#674](https://github.com/chocolatey/choco/issues/674) * [POSH Host] Fix - $profile is empty string when installing packages - does not automatically install the ChocolateyProfile - see [#667](https://github.com/chocolatey/choco/issues/667) + * [POSH Host] Fix - Getting LCID doesn't work properly with the built-in PowerShell - see [#741](https://github.com/chocolatey/choco/issues/741) * Fix - Verbose shows in output on debug switch - see [#611](https://github.com/chocolatey/choco/issues/611) * Fix - Get-ChocolateyUnzip captures files that don't belong to the package / Unzip should not do a full disk scan - see [#616](https://github.com/chocolatey/choco/issues/616) and [#155](https://github.com/chocolatey/choco/issues/155) * Fix - Package succeeds but software install silently fails when Install-ChocolateyInstallPackage has the wrong arguments - see [#629](https://github.com/chocolatey/choco/issues/629) @@ -106,6 +108,9 @@ If you need the previous behavior, be sure to disable the feature `usePackageExi * Fix - Removing environment variables sets empty environment variables - see [#724](https://github.com/chocolatey/choco/issues/724) * Fix - Environment Variable Changes Require Reboot - see [#728](https://github.com/chocolatey/choco/issues/728) * Fix - Get-WebFileName determines strange file name - see [#727](https://github.com/chocolatey/choco/issues/727) + * Fix - Package params are also applied to dependent package - see [#733](https://github.com/chocolatey/choco/issues/733) + * Fix - Use package name/version from environment, not parameters - see [#751](https://github.com/chocolatey/choco/issues/751) + * Fix - Get-WebFileName Does Not Match on Invalid Characters - see [#753](https://github.com/chocolatey/choco/issues/753) ### IMPROVEMENTS @@ -141,6 +146,9 @@ If you need the previous behavior, be sure to disable the feature `usePackageExi * Interactively prompt with timeout on some questions - see [#710](https://github.com/chocolatey/choco/issues/710) * [POSH Host] Exit code from PowerShell Host should be useful - see [#709](https://github.com/chocolatey/choco/issues/709) * Update environment for scripts after setting environment variables - see [#729](https://github.com/chocolatey/choco/issues/729) + * Clean up any temp nuget folder actions after NuGet operations - see [#622](https://github.com/chocolatey/choco/issues/622) + * Ensure Web Requests and Responses Do Not Timeout - make configurable - see [#732](https://github.com/chocolatey/choco/issues/732) + * Combine timeout from push and execution timeout as one parameter - see [#752](https://github.com/chocolatey/choco/issues/752) * Pro/Business - Also check for license in User Profile location - see [#606](https://github.com/chocolatey/choco/issues/606) * Pro/Business - Set download cache information if available - see [#562](https://github.com/chocolatey/choco/issues/562) * Pro/Business - Allow commands to be added - see [#583](https://github.com/chocolatey/choco/issues/583) diff --git a/README.md b/README.md index f939a68ae8..95d6b4f97e 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Please make sure you've read over and agree with the [etiquette regarding commun ## Support Chocolatey! - * Purchase [Chocolatey Professional / Chocolatey for Business](https://chocolatey.org/pricing) + * Purchase [Chocolatey Pro / Chocolatey for Business](https://chocolatey.org/compare) * [Donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=E8ZPVL5PNTABW) ## See Chocolatey In Action @@ -36,9 +36,9 @@ Chocolatey FOSS install showing tab completion and `refreshenv` (a way to update ![install](https://raw.githubusercontent.com/wiki/chocolatey/choco/images/gifs/choco_install.gif "Wat? Tab completion and updating environment variables!") -[Chocolatey Professional](https://chocolatey.org/pricing) showing private download cache and virus scan protection: +[Chocolatey Pro](https://chocolatey.org/compare) showing private CDN download cache and virus scan protection: -![install pro](https://raw.githubusercontent.com/wiki/chocolatey/choco/images/gifs/chocopro_install_stopped.gif "Get ready! Chocolatey Professional availability is May 2nd, 2016") +![install w/pro](https://raw.githubusercontent.com/wiki/chocolatey/choco/images/gifs/chocopro_install_stopped.gif "Chocolatey Pro availability now! A great option for individuals looking for that community PLUS option.") ## Etiquette Regarding Communication diff --git a/nuget/chocolatey/chocolatey.nuspec b/nuget/chocolatey/chocolatey.nuspec index a342f70b27..161b92288d 100644 --- a/nuget/chocolatey/chocolatey.nuspec +++ b/nuget/chocolatey/chocolatey.nuspec @@ -111,9 +111,10 @@ If you need the previous behavior, be sure to disable the feature `usePackageExi * Provide PowerShell tab completion for Chocolatey - see [#412](https://github.com/chocolatey/choco/issues/412) * [Security] Sign the powershell scripts and assemblies - see [#501](https://github.com/chocolatey/choco/issues/501) * Add a `choco info` command to show info for one package - see [#644](https://github.com/chocolatey/choco/issues/644) + * Resolve sources by name - see [#356](https://github.com/chocolatey/choco/issues/356) * Pro/Business - Ubiquitous Install Directory Switch - see [#258](https://github.com/chocolatey/choco/issues/258) - * Pro/Business - Runtime Virus Scanning - see [virus scanning](https://www.kickstarter.com/projects/ferventcoder/chocolatey-the-alternative-windows-store-like-yum/posts/1518468) - * Pro/Business - Permanent private download location - see [alternate download location](https://www.kickstarter.com/projects/ferventcoder/chocolatey-the-alternative-windows-store-like-yum/posts/1479944) + * Pro/Business - Runtime Virus Scanning - see [virus scanning](https://chocolatey.org/docs/features-virus-check) + * Pro/Business - Private CDN cache for downloads - see [private CDN cache](https://chocolatey.org/docs/features-private-cdn) ### BUG FIXES @@ -144,6 +145,7 @@ If you need the previous behavior, be sure to disable the feature `usePackageExi * [POSH Host] Fix - Write-Host adding multiple line breaks - see [#672](https://github.com/chocolatey/choco/issues/672) * [POSH Host] Fix - PowerShell Host doesn't show colorization overrides - see [#674](https://github.com/chocolatey/choco/issues/674) * [POSH Host] Fix - $profile is empty string when installing packages - does not automatically install the ChocolateyProfile - see [#667](https://github.com/chocolatey/choco/issues/667) + * [POSH Host] Fix - Getting LCID doesn't work properly with the built-in PowerShell - see [#741](https://github.com/chocolatey/choco/issues/741) * Fix - Verbose shows in output on debug switch - see [#611](https://github.com/chocolatey/choco/issues/611) * Fix - Get-ChocolateyUnzip captures files that don't belong to the package / Unzip should not do a full disk scan - see [#616](https://github.com/chocolatey/choco/issues/616) and [#155](https://github.com/chocolatey/choco/issues/155) * Fix - Package succeeds but software install silently fails when Install-ChocolateyInstallPackage has the wrong arguments - see [#629](https://github.com/chocolatey/choco/issues/629) @@ -161,6 +163,9 @@ If you need the previous behavior, be sure to disable the feature `usePackageExi * Fix - Removing environment variables sets empty environment variables - see [#724](https://github.com/chocolatey/choco/issues/724) * Fix - Environment Variable Changes Require Reboot - see [#728](https://github.com/chocolatey/choco/issues/728) * Fix - Get-WebFileName determines strange file name - see [#727](https://github.com/chocolatey/choco/issues/727) + * Fix - Package params are also applied to dependent package - see [#733](https://github.com/chocolatey/choco/issues/733) + * Fix - Use package name/version from environment, not parameters - see [#751](https://github.com/chocolatey/choco/issues/751) + * Fix - Get-WebFileName Does Not Match on Invalid Characters - see [#753](https://github.com/chocolatey/choco/issues/753) ### IMPROVEMENTS @@ -196,6 +201,9 @@ If you need the previous behavior, be sure to disable the feature `usePackageExi * Interactively prompt with timeout on some questions - see [#710](https://github.com/chocolatey/choco/issues/710) * [POSH Host] Exit code from PowerShell Host should be useful - see [#709](https://github.com/chocolatey/choco/issues/709) * Update environment for scripts after setting environment variables - see [#729](https://github.com/chocolatey/choco/issues/729) + * Clean up any temp nuget folder actions after NuGet operations - see [#622](https://github.com/chocolatey/choco/issues/622) + * Ensure Web Requests and Responses Do Not Timeout - make configurable - see [#732](https://github.com/chocolatey/choco/issues/732) + * Combine timeout from push and execution timeout as one parameter - see [#752](https://github.com/chocolatey/choco/issues/752) * Pro/Business - Also check for license in User Profile location - see [#606](https://github.com/chocolatey/choco/issues/606) * Pro/Business - Set download cache information if available - see [#562](https://github.com/chocolatey/choco/issues/562) * Pro/Business - Allow commands to be added - see [#583](https://github.com/chocolatey/choco/issues/583) diff --git a/src/chocolatey.console/Program.cs b/src/chocolatey.console/Program.cs index 03b44a7eff..30554ce404 100644 --- a/src/chocolatey.console/Program.cs +++ b/src/chocolatey.console/Program.cs @@ -27,15 +27,13 @@ namespace chocolatey.console using infrastructure.commandline; using infrastructure.configuration; using infrastructure.extractors; - using infrastructure.filesystem; - using infrastructure.information; using infrastructure.licensing; using infrastructure.logging; using infrastructure.registration; using resources; - using SimpleInjector; using Console = System.Console; using Environment = System.Environment; + using IFileSystem = infrastructure.filesystem.IFileSystem; public sealed class Program { @@ -52,33 +50,7 @@ private static void Main(string[] args) Log4NetAppenderConfiguration.configure(loggingLocation); Bootstrap.initialize(); Bootstrap.startup(); - - var license = LicenseValidation.validate(); - if (license.is_licensed_version()) - { - try - { - var licensedAssembly = Assembly.LoadFile(ApplicationParameters.LicensedAssemblyLocation); - license.AssemblyLoaded = true; - license.Assembly = licensedAssembly; - license.Version = VersionInformation.get_current_informational_version(licensedAssembly); - Type licensedComponent = licensedAssembly.GetType(ApplicationParameters.LicensedComponentRegistry, throwOnError: false, ignoreCase: true); - SimpleInjectorContainer.add_component_registry_class(licensedComponent); - } - catch (Exception ex) - { - "chocolatey".Log().Error( -@"Error when attempting to load chocolatey licensed assembly. Ensure - that chocolatey.licensed.dll exists at - '{0}'. - Install with `choco install chocolatey.extension`. - The error message itself may be helpful as well:{1} {2}".format_with( - ApplicationParameters.LicensedAssemblyLocation, - Environment.NewLine, - ex.Message - )); - } - } + var license = License.validate_license(); var container = SimpleInjectorContainer.Container; var config = container.GetInstance(); @@ -185,7 +157,6 @@ Install with `choco install chocolatey.extension`. #endif pause_execution_if_debug(); Bootstrap.shutdown(); - Environment.Exit(Environment.ExitCode); } } diff --git a/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 b/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 index 05084dd3c6..5947e4007f 100644 --- a/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 @@ -71,6 +71,13 @@ param( $req.AllowAutoRedirect = $true $req.MaximumAutomaticRedirections = 20 #$req.KeepAlive = $true + # use the default request timeout of 100000 + if ($env:chocolateyRequestTimeout -ne $null -and $env:chocolateyRequestTimeout -ne '') { + $req.Timeout = $env:chocolateyRequestTimeout + } + if ($env:chocolateyResponseTimeout -ne $null -and $env:chocolateyResponseTimeout -ne '') { + $req.ReadWriteTimeout = $env:chocolateyResponseTimeout + } #http://stackoverflow.com/questions/518181/too-many-automatic-redirections-were-attempted-error-message-when-using-a-httpw $req.CookieContainer = New-Object System.Net.CookieContainer diff --git a/src/chocolatey.resources/helpers/functions/Get-WebFileName.ps1 b/src/chocolatey.resources/helpers/functions/Get-WebFileName.ps1 index 5afc1c25f1..b0f1f7376f 100644 --- a/src/chocolatey.resources/helpers/functions/Get-WebFileName.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-WebFileName.ps1 @@ -83,12 +83,20 @@ param( $request.AllowAutoRedirect = $true $request.MaximumAutomaticRedirections = 20 #$request.KeepAlive = $true - $request.Timeout = 20000 + $request.Timeout = 30000 + if ($env:chocolateyRequestTimeout -ne $null -and $env:chocolateyRequestTimeout -ne '') { + $request.Timeout = $env:chocolateyRequestTimeout + } + if ($env:chocolateyResponseTimeout -ne $null -and $env:chocolateyResponseTimeout -ne '') { + $request.ReadWriteTimeout = $env:chocolateyResponseTimeout + } #http://stackoverflow.com/questions/518181/too-many-automatic-redirections-were-attempted-error-message-when-using-a-httpw $request.CookieContainer = New-Object System.Net.CookieContainer $request.UserAgent = $userAgent + [System.Text.RegularExpressions.Regex]$containsABadCharacter = New-Object Regex("[" + [System.Text.RegularExpressions.Regex]::Escape([System.IO.Path]::GetInvalidFileNameChars() -join '') + "\=\;]"); + try { [System.Net.HttpWebResponse]$response = $request.GetResponse() @@ -110,6 +118,7 @@ param( $fileName = $header.Substring($index + $fileHeaderName.Length).Replace('"', '') } } + if ($containsABadCharacter.IsMatch($fileName)) { $fileName = $null } # If empty, check location header next if ($fileName -eq $null -or $fileName -eq '') { @@ -118,9 +127,7 @@ param( $fileName = [System.IO.Path]::GetFileName($headerLocation) } } - - #$containsQuery = [System.IO.Path]::GetFileName($url).Contains('?') - #$containsEquals = [System.IO.Path]::GetFileName($url).Contains('=') + if ($containsABadCharacter.IsMatch($fileName)) { $fileName = $null } # Next comes using the response url value if ($fileName -eq $null -or $fileName -eq '') { @@ -130,6 +137,7 @@ param( $fileName = [System.IO.Path]::GetFileName($responseUrl) } } + if ($containsABadCharacter.IsMatch($fileName)) { $fileName = $null } # Next comes using the request url value if ($fileName -eq $null -or $fileName -eq '') { @@ -141,8 +149,6 @@ param( } } - [System.Text.RegularExpressions.Regex]$containsABadCharacter = New-Object Regex("[" + [System.Text.RegularExpressions.Regex]::Escape([System.IO.Path]::GetInvalidFileNameChars()) + "]", [System.Text.RegularExpressions.RegexOptions]::IgnorePatternWhitespace); - # when all else fails, default the name if ($fileName -eq $null -or $fileName -eq '' -or $containsABadCharacter.IsMatch($fileName)) { Write-Debug "File name is null or illegal. Using $originalFileName instead." diff --git a/src/chocolatey.resources/helpers/functions/Get-WebHeaders.ps1 b/src/chocolatey.resources/helpers/functions/Get-WebHeaders.ps1 index b3f7d4ff31..776e97553b 100644 --- a/src/chocolatey.resources/helpers/functions/Get-WebHeaders.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-WebHeaders.ps1 @@ -67,7 +67,13 @@ param( $request.AllowAutoRedirect = $true $request.MaximumAutomaticRedirections = 20 #$request.KeepAlive = $true - $request.Timeout = 20000 + $request.Timeout = 30000 + if ($env:chocolateyRequestTimeout -ne $null -and $env:chocolateyRequestTimeout -ne '') { + $request.Timeout = $env:chocolateyRequestTimeout + } + if ($env:chocolateyResponseTimeout -ne $null -and $env:chocolateyResponseTimeout -ne '') { + $request.ReadWriteTimeout = $env:chocolateyResponseTimeout + } #http://stackoverflow.com/questions/518181/too-many-automatic-redirections-were-attempted-error-message-when-using-a-httpw $request.CookieContainer = New-Object System.Net.CookieContainer diff --git a/src/chocolatey.resources/helpers/functions/Install-ChocolateyInstallPackage.ps1 b/src/chocolatey.resources/helpers/functions/Install-ChocolateyInstallPackage.ps1 index 87046a9ae4..6a6b4eedb1 100644 --- a/src/chocolatey.resources/helpers/functions/Install-ChocolateyInstallPackage.ps1 +++ b/src/chocolatey.resources/helpers/functions/Install-ChocolateyInstallPackage.ps1 @@ -95,7 +95,7 @@ param( Pro / Business supports a single, ubiquitous install directory option. Stop the hassle of determining how to pass install directory overrides to install arguments for each package / installer type. - Check out Pro / Business - https://chocolatey.org/pricing" + Check out Pro / Business - https://chocolatey.org/compare" "@ | Write-Warning } } diff --git a/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 b/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 index 397bb8ad39..a377d7f4cd 100644 --- a/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 +++ b/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 @@ -102,8 +102,8 @@ param( Write-Debug "Running 'Install-ChocolateyPackage' for $packageName with url:`'$url`', args: `'$silentArgs`', fileType: `'$fileType`', url64bit: `'$url64bit`', checksum: `'$checksum`', checksumType: `'$checksumType`', checksum64: `'$checksum64`', checksumType64: `'$checksumType64`', validExitCodes: `'$validExitCodes`' "; $chocTempDir = $env:TEMP - $tempDir = Join-Path $chocTempDir "$packageName" - if ($env:packageVersion -ne $null) {$tempDir = Join-Path $tempDir "$env:packageVersion"; } + $tempDir = Join-Path $chocTempDir "$($env:chocolateyPackageName)" + if ($env:chocolateyPackageVersion -ne $null) {$tempDir = Join-Path $tempDir "$($env:chocolateyPackageVersion)"; } if (![System.IO.Directory]::Exists($tempDir)) { [System.IO.Directory]::CreateDirectory($tempDir) | Out-Null } $file = Join-Path $tempDir "$($packageName)Install.$fileType" diff --git a/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 b/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 index 80c27ce04e..7f7db83232 100644 --- a/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 +++ b/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 @@ -94,8 +94,8 @@ param( $fileType = 'zip' $chocTempDir = $env:TEMP - $tempDir = Join-Path $chocTempDir "$packageName" - if ($env:packageVersion -ne $null) {$tempDir = Join-Path $tempDir "$env:packageVersion"; } + $tempDir = Join-Path $chocTempDir "$($env:chocolateyPackageName)" + if ($env:chocolateyPackageVersion -ne $null) {$tempDir = Join-Path $tempDir "$($env:chocolateyPackageVersion)"; } if (![System.IO.Directory]::Exists($tempDir)) {[System.IO.Directory]::CreateDirectory($tempDir) | Out-Null} $file = Join-Path $tempDir "$($packageName)Install.$fileType" diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPushCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPushCommandSpecs.cs index 4cad545e65..5b11ae953d 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPushCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPushCommandSpecs.cs @@ -105,13 +105,7 @@ public void should_add_short_version_of_apikey_to_the_option_set() { optionSet.Contains("k").ShouldBeTrue(); } - - [Fact] - public void should_add_timeout_to_the_option_set() - { - optionSet.Contains("timeout").ShouldBeTrue(); - } - + [Fact] public void should_add_short_version_of_timeout_to_the_option_set() { diff --git a/src/chocolatey/GetChocolatey.cs b/src/chocolatey/GetChocolatey.cs index de3e8f11a9..5110c34487 100644 --- a/src/chocolatey/GetChocolatey.cs +++ b/src/chocolatey/GetChocolatey.cs @@ -18,6 +18,7 @@ namespace chocolatey using System; using System.Collections.Generic; using infrastructure.licensing; + using NuGet; using SimpleInjector; using infrastructure.adapters; using infrastructure.app; @@ -26,11 +27,10 @@ namespace chocolatey using infrastructure.app.runners; using infrastructure.configuration; using infrastructure.extractors; - using infrastructure.filesystem; using infrastructure.logging; using infrastructure.registration; - using infrastructure.services; using resources; + using IFileSystem = infrastructure.filesystem.IFileSystem; // ReSharper disable InconsistentNaming @@ -61,7 +61,7 @@ public GetChocolatey() { Log4NetAppenderConfiguration.configure(); Bootstrap.initialize(); - _license = LicenseValidation.validate(); + _license = License.validate_license(); _container = SimpleInjectorContainer.Container; } @@ -221,7 +221,13 @@ public int ListCount() private ChocolateyConfiguration create_configuration(IList args) { var configuration = new ChocolateyConfiguration(); - ConfigurationBuilder.set_up_configuration(args, configuration, _container, _license, null); + ConfigurationBuilder.set_up_configuration( + args, + configuration, + _container, + _license, + null); + Config.initialize_with(configuration); configuration.PromptForConfirmation = false; diff --git a/src/chocolatey/chocolatey.csproj b/src/chocolatey/chocolatey.csproj index 2c4a7e3f45..576d0fdc5f 100644 --- a/src/chocolatey/chocolatey.csproj +++ b/src/chocolatey/chocolatey.csproj @@ -144,6 +144,7 @@ + diff --git a/src/chocolatey/infrastructure.app/ApplicationParameters.cs b/src/chocolatey/infrastructure.app/ApplicationParameters.cs index 546d43907d..340e12449f 100644 --- a/src/chocolatey/infrastructure.app/ApplicationParameters.cs +++ b/src/chocolatey/infrastructure.app/ApplicationParameters.cs @@ -78,6 +78,7 @@ public static class Environment /// Default is 45 minutes /// public static int DefaultWaitForExitInSeconds = 2700; + public static int DefaultWebRequestTimeoutInSeconds = 45; public static readonly string[] ConfigFileExtensions = new string[] {".autoconf",".config",".conf",".cfg",".jsc",".json",".jsonp",".ini",".xml",".yaml"}; public static readonly string ConfigFileTransformExtension = ".install.xdt"; @@ -100,6 +101,7 @@ public static class ConfigSettings public static readonly string Proxy = "proxy"; public static readonly string ProxyUser = "proxyUser"; public static readonly string ProxyPassword = "proxyPassword"; + public static readonly string WebRequestTimeoutSeconds = "webRequestTimeoutSeconds"; } public static class Features diff --git a/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs b/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs index 32a0c8147a..b1a3279e09 100644 --- a/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs +++ b/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs @@ -205,6 +205,21 @@ private static void set_config_items(ChocolateyConfiguration config, ConfigFileS config.CommandExecutionTimeoutSeconds = ApplicationParameters.DefaultWaitForExitInSeconds; } + var webRequestTimeoutSeconds = -1; + int.TryParse( + set_config_item( + ApplicationParameters.ConfigSettings.WebRequestTimeoutSeconds, + configFileSettings, + ApplicationParameters.DefaultWebRequestTimeoutInSeconds.to_string(), + "Default timeout for web requests. Available in 0.9.10+."), + out webRequestTimeoutSeconds); + if (webRequestTimeoutSeconds <= 0) + { + webRequestTimeoutSeconds = ApplicationParameters.DefaultWebRequestTimeoutInSeconds; + set_config_item(ApplicationParameters.ConfigSettings.WebRequestTimeoutSeconds,configFileSettings, ApplicationParameters.DefaultWebRequestTimeoutInSeconds.to_string(),"Default timeout for web requests. Available in 0.9.10+.", forceSettingValue: true); + } + config.WebRequestTimeoutSeconds = webRequestTimeoutSeconds; + config.ContainsLegacyPackageInstalls = set_config_item(ApplicationParameters.ConfigSettings.ContainsLegacyPackageInstalls, configFileSettings, "true", "Install has packages installed prior to 0.9.9 series.").is_equal_to(bool.TrueString); config.Proxy.Location = set_config_item(ApplicationParameters.ConfigSettings.Proxy, configFileSettings, string.Empty, "Explicit proxy location."); config.Proxy.User = set_config_item(ApplicationParameters.ConfigSettings.ProxyUser, configFileSettings, string.Empty, "Optional proxy user."); @@ -311,9 +326,17 @@ private static void set_global_options(IList args, ChocolateyConfigurati .Add("r|limitoutput|limit-output", "LimitOutput - Limit the output to essential information", option => config.RegularOutput = option == null) - .Add("execution-timeout=", - "CommandExecutionTimeoutSeconds - Override the default execution timeout in the configuration of {0} seconds.".format_with(config.CommandExecutionTimeoutSeconds.to_string()), - option => config.CommandExecutionTimeoutSeconds = int.Parse(option.remove_surrounding_quotes())) + .Add("timeout=|execution-timeout=", + "CommandExecutionTimeout (in seconds) - The time to allow a command to finish before timing out. Overrides the default execution timeout in the configuration of {0} seconds.".format_with(config.CommandExecutionTimeoutSeconds.to_string()), + option => + { + int timeout = 0; + int.TryParse(option.remove_surrounding_quotes(), out timeout); + if (timeout > 0) + { + config.CommandExecutionTimeoutSeconds = timeout; + } + }) .Add("c=|cache=|cachelocation=|cache-location=", "CacheLocation - Location for download cache, defaults to %TEMP% or value in chocolatey.config file.", option => config.CacheLocation = option.remove_surrounding_quotes()) @@ -429,6 +452,8 @@ public static void set_environment_variables(ChocolateyConfiguration config) if (config.Debug) Environment.SetEnvironmentVariable("ChocolateyEnvironmentDebug", "true"); if (config.Verbose) Environment.SetEnvironmentVariable("ChocolateyEnvironmentVerbose", "true"); if (!config.Features.CheckSumFiles) Environment.SetEnvironmentVariable("ChocolateyIgnoreChecksums", "true"); + Environment.SetEnvironmentVariable("chocolateyRequestTimeout", config.WebRequestTimeoutSeconds.to_string() + "000"); + Environment.SetEnvironmentVariable("chocolateyResponseTimeout", config.CommandExecutionTimeoutSeconds.to_string() + "000"); if (!string.IsNullOrWhiteSpace(config.Proxy.Location)) { diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyNewCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyNewCommand.cs index 05cb5c4535..d84f307be8 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyNewCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyNewCommand.cs @@ -109,7 +109,7 @@ public virtual void handle_validation(ChocolateyConfiguration configuration) if (configuration.NewCommand.Name.StartsWith("-file", StringComparison.OrdinalIgnoreCase) || configuration.NewCommand.Name.StartsWith("--file", StringComparison.OrdinalIgnoreCase)) { throw new ApplicationException(@"Automatic package creation from installer files only available in Business - edition. See https://chocolatey.org/pricing for details."); + edition. See https://chocolatey.org/compare for details."); } } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyPushCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyPushCommand.cs index 6b0b3a5078..842f75dab7 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyPushCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyPushCommand.cs @@ -39,7 +39,6 @@ public ChocolateyPushCommand(IChocolateyPackageService packageService, IChocolat public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { configuration.Sources = null; - configuration.PushCommand.TimeoutInSeconds = 300; optionSet .Add("s=|source=", @@ -48,15 +47,16 @@ public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyCon .Add("k=|key=|apikey=|api-key=", "ApiKey - The api key for the source. If not specified (and not local file source), does a lookup. If not specified and one is not found for an https source, push will fail.", option => configuration.PushCommand.Key = option.remove_surrounding_quotes()) - .Add("t=|timeout=", - "Timeout (in seconds) - The time to allow a package push to occur before timing out. Defaults to 300 seconds (5 minutes).", + .Add("t=", + "Timeout (in seconds) - The time to allow a package push to occur before timing out. Defaults to execution timeout {0}.".format_with(configuration.CommandExecutionTimeoutSeconds), option => { + this.Log().Warn("Using -t for timeout has been deprecated and will be removed in v1. Please update to use --timeout or --execution-timeout instead."); int timeout = 0; int.TryParse(option, out timeout); if (timeout > 0) { - configuration.PushCommand.TimeoutInSeconds = timeout; + configuration.CommandExecutionTimeoutSeconds = timeout; } }) //.Add("b|disablebuffering|disable-buffering", diff --git a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs index 509cecb245..4cedf855fb 100644 --- a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs +++ b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs @@ -141,6 +141,7 @@ private void append_output(StringBuilder propertyValues, string append) public string CacheLocation { get; set; } public bool ContainsLegacyPackageInstalls { get; set; } public int CommandExecutionTimeoutSeconds { get; set; } + public int WebRequestTimeoutSeconds { get; set; } /// /// One or more source locations set by configuration or by command line. Separated by semi-colon @@ -444,7 +445,6 @@ public sealed class ApiKeyCommandConfiguration public sealed class PushCommandConfiguration { public string Key { get; set; } - public int TimeoutInSeconds { get; set; } //DisableBuffering? } diff --git a/src/chocolatey/infrastructure.app/nuget/NugetCommon.cs b/src/chocolatey/infrastructure.app/nuget/NugetCommon.cs index 7cf9a46704..8318b79f67 100644 --- a/src/chocolatey/infrastructure.app/nuget/NugetCommon.cs +++ b/src/chocolatey/infrastructure.app/nuget/NugetCommon.cs @@ -17,7 +17,10 @@ namespace chocolatey.infrastructure.app.nuget { using System; using System.Collections.Generic; + using System.Linq; using System.Net; + using System.Text; + using infrastructure.configuration; using NuGet; using configuration; using logging; @@ -71,8 +74,26 @@ public static IPackageRepository GetRemoteRepository(ChocolateyConfiguration con ProxyCache.Instance.Override(proxy); } - foreach (var source in sources.or_empty_list_if_null()) + var updatedSources = new StringBuilder(); + foreach (var sourceValue in sources.or_empty_list_if_null()) { + + var source = sourceValue; + if (configuration.MachineSources.Any(m => m.Name.is_equal_to(source))) + { + "chocolatey".Log().Debug("Switching source name {0} to actual source value.".format_with(sourceValue)); + try + { + source = configuration.MachineSources.FirstOrDefault(m => m.Name.is_equal_to(source)).Key; + } + catch (Exception ex) + { + "chocolatey".Log().Warn("Attempted to use a source name {0} to get default source but failed:{1} {2}".format_with(sourceValue, Environment.NewLine, ex.Message)); + } + } + + updatedSources.AppendFormat("{0};", source); + try { var uri = new Uri(source); @@ -91,6 +112,11 @@ public static IPackageRepository GetRemoteRepository(ChocolateyConfiguration con } } + if (updatedSources.Length != 0) + { + configuration.Sources = updatedSources.Remove(updatedSources.Length - 1, 1).to_string(); + } + //todo well that didn't work on failing repos... grrr var repository = new AggregateRepository(repositories) {IgnoreFailingRepositories = true}; repository.ResolveDependenciesVertically = true; @@ -136,7 +162,6 @@ public static IPackageManager GetPackageManager(ChocolateyConfiguration configur { // NOTE DO NOT EVER use this method, or endless loop - packageManager.PackageUninstalling += (s, e) => - packageManager.PackageUninstalled += (s, e) => { IPackage pkg = packageManager.LocalRepository.FindPackage(e.Package.Id, e.Package.Version); diff --git a/src/chocolatey/infrastructure.app/nuget/NugetPush.cs b/src/chocolatey/infrastructure.app/nuget/NugetPush.cs index 4f6903ea3b..4028d96a5a 100644 --- a/src/chocolatey/infrastructure.app/nuget/NugetPush.cs +++ b/src/chocolatey/infrastructure.app/nuget/NugetPush.cs @@ -25,7 +25,7 @@ public class NugetPush { public static void push_package(ChocolateyConfiguration config, string nupkgFilePath) { - var timeout = TimeSpan.FromSeconds(Math.Abs(config.PushCommand.TimeoutInSeconds)); + var timeout = TimeSpan.FromSeconds(Math.Abs(config.CommandExecutionTimeoutSeconds)); if (timeout.Seconds <= 0) { timeout = TimeSpan.FromMinutes(5); // Default to 5 minutes @@ -33,6 +33,7 @@ public static void push_package(ChocolateyConfiguration config, string nupkgFile const bool disableBuffering = false; var packageServer = new PackageServer(config.Sources, ApplicationParameters.UserAgent); + packageServer.SendingRequest += (sender, e) => { if (config.Verbose) "chocolatey".Log().Info(ChocolateyLoggers.Verbose, "{0} {1}".format_with(e.Request.Method, e.Request.RequestUri)); }; var package = new OptimizedZipPackage(nupkgFilePath); @@ -57,7 +58,6 @@ public static void push_package(ChocolateyConfiguration config, string nupkgFile throw; } - "chocolatey".Log().Info(ChocolateyLoggers.Important, () => "{0} was pushed successfully to {1}".format_with(package.GetFullName(), config.Sources)); } } diff --git a/src/chocolatey/infrastructure.app/runners/GenericRunner.cs b/src/chocolatey/infrastructure.app/runners/GenericRunner.cs index d6853a53df..d92901cce6 100644 --- a/src/chocolatey/infrastructure.app/runners/GenericRunner.cs +++ b/src/chocolatey/infrastructure.app/runners/GenericRunner.cs @@ -19,6 +19,7 @@ namespace chocolatey.infrastructure.app.runners using System; using System.Linq; using System.Collections.Generic; + using filesystem; using SimpleInjector; using adapters; using attributes; @@ -37,7 +38,7 @@ private ICommand find_command(ChocolateyConfiguration config, Container containe var commands = container.GetAllInstances(); var command = commands.Where((c) => { - var attributes = c.GetType().GetCustomAttributes(typeof (CommandForAttribute), false); + var attributes = c.GetType().GetCustomAttributes(typeof(CommandForAttribute), false); return attributes.Cast().Any(attribute => attribute.CommandName.is_equal_to(config.CommandName)); }).FirstOrDefault(); @@ -119,13 +120,13 @@ private void set_source_type(ChocolateyConfiguration config) Enum.TryParse(config.Sources, true, out sourceType); config.SourceType = sourceType; - this.Log().Debug(()=> "The source '{0}' evaluated to a '{1}' source type".format_with(config.Sources,sourceType.to_string())); + this.Log().Debug(() => "The source '{0}' evaluated to a '{1}' source type".format_with(config.Sources, sourceType.to_string())); } public void fail_when_license_is_missing_or_invalid_if_requested(ChocolateyConfiguration config) { if (!config.Features.FailOnInvalidOrMissingLicense) return; - + if (!config.Information.IsLicensedVersion) throw new ApplicationException("License is missing or invalid."); } @@ -134,11 +135,33 @@ public void run(ChocolateyConfiguration config, Container container, bool isCons fail_when_license_is_missing_or_invalid_if_requested(config); var command = find_command(config, container, isConsole, parseArgs); - if(command != null) + if (command != null) { this.Log().Debug("_ {0}:{1} - Normal Run Mode _".format_with(ApplicationParameters.Name, command.GetType().Name)); command.run(config); } + + remove_nuget_cache(container); + } + + /// + /// if there is a NuGetScratch cache found, kill it with fire + /// + /// The container. + private void remove_nuget_cache(Container container) + { + try + { + var fileSystem = container.GetInstance(); + var scratch = fileSystem.combine_paths(fileSystem.get_temp_path(), "NuGetScratch"); + fileSystem.delete_directory_if_exists(scratch, recursive: true, overrideAttributes: true, isSilent: true); + var nugetX = fileSystem.combine_paths(fileSystem.get_temp_path(), "x", "nuget"); + fileSystem.delete_directory_if_exists(nugetX, recursive: true, overrideAttributes: true, isSilent: true); + } + catch (Exception ex) + { + this.Log().Debug(ChocolateyLoggers.Important, "Not able to cleanup NuGet temp folders. Failure was {0}".format_with(ex.Message)); + } } public IEnumerable list(ChocolateyConfiguration config, Container container, bool isConsole, Action parseArgs) diff --git a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs index 0df0b6d622..b912cd290b 100644 --- a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs +++ b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs @@ -48,10 +48,10 @@ public class ChocolateyPackageService : IChocolateyPackageService private readonly IXmlService _xmlService; private readonly IConfigTransformService _configTransformService; private const string PRO_BUSINESS_MESSAGE = @" -Check out Pro / Business for more features! https://chocolatey.org/pricing"; +Check out Pro / Business for more features! https://chocolatey.org/compare"; private const string PRO_BUSINESS_LIST_MESSAGE = @" -Did you know Pro/Business automatically syncs with Programs and - Features? Find out more at https://chocolatey.org/pricing"; +Did you know Pro / Business automatically syncs with Programs and + Features? Find out more at https://chocolatey.org/compare"; private readonly string _shutdownExe = Environment.ExpandEnvironmentVariables("%systemroot%\\System32\\shutdown.exe"); diff --git a/src/chocolatey/infrastructure.app/services/PowershellService.cs b/src/chocolatey/infrastructure.app/services/PowershellService.cs index 97f325b091..ab25e317d2 100644 --- a/src/chocolatey/infrastructure.app/services/PowershellService.cs +++ b/src/chocolatey/infrastructure.app/services/PowershellService.cs @@ -200,21 +200,39 @@ public bool run_action(ChocolateyConfiguration configuration, PackageResult pack Environment.SetEnvironmentVariable("packageVersion", package.Version.to_string()); Environment.SetEnvironmentVariable("chocolateyPackageFolder", packageDirectory); Environment.SetEnvironmentVariable("packageFolder", packageDirectory); - Environment.SetEnvironmentVariable("installArguments", configuration.InstallArguments); - Environment.SetEnvironmentVariable("installerArguments", configuration.InstallArguments); - Environment.SetEnvironmentVariable("chocolateyInstallArguments", configuration.InstallArguments); - Environment.SetEnvironmentVariable("packageParameters", configuration.PackageParameters); - Environment.SetEnvironmentVariable("chocolateyPackageParameters", configuration.PackageParameters); - if (configuration.ForceX86) + + // unset variables that may not be updated so they don't get passed again + Environment.SetEnvironmentVariable("installArguments", null); + Environment.SetEnvironmentVariable("installerArguments", null); + Environment.SetEnvironmentVariable("chocolateyInstallArguments", null); + Environment.SetEnvironmentVariable("packageParameters", null); + Environment.SetEnvironmentVariable("chocolateyPackageParameters", null); + Environment.SetEnvironmentVariable("chocolateyInstallOverride", null); + + // we only want to pass the following args to packages that would apply. + // like choco install git -params '' should pass those params to git.install, + // but not another package + if (!package_is_a_dependency_not_a_virtual(configuration, package.Id)) { - Environment.SetEnvironmentVariable("chocolateyForceX86", "true"); + this.Log().Debug(ChocolateyLoggers.Verbose, "Setting installer args and package parameters for {0}".format_with(package.Id)); + Environment.SetEnvironmentVariable("installArguments", configuration.InstallArguments); + Environment.SetEnvironmentVariable("installerArguments", configuration.InstallArguments); + Environment.SetEnvironmentVariable("chocolateyInstallArguments", configuration.InstallArguments); + Environment.SetEnvironmentVariable("packageParameters", configuration.PackageParameters); + Environment.SetEnvironmentVariable("chocolateyPackageParameters", configuration.PackageParameters); + + if (configuration.OverrideArguments) + { + Environment.SetEnvironmentVariable("chocolateyInstallOverride", "true"); + } } - if (configuration.OverrideArguments) + + if (configuration.ForceX86) { - Environment.SetEnvironmentVariable("chocolateyInstallOverride", "true"); + Environment.SetEnvironmentVariable("chocolateyForceX86", "true"); } - + if (configuration.NotSilent) { Environment.SetEnvironmentVariable("chocolateyInstallOverride", "true"); @@ -353,6 +371,26 @@ public bool run_action(ChocolateyConfiguration configuration, PackageResult pack return installerRun; } + /// + /// Is the package we are installing a dependency? Semi-virtual packages do not count: + /// .install / .app / .portable / .tool / .commandline + /// + /// The configuration. + /// Name of the package. + /// + private bool package_is_a_dependency_not_a_virtual(ChocolateyConfiguration config, string packageName) + { + foreach (var package in config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).or_empty_list_if_null()) + { + if (packageName.is_equal_to(package) || packageName.contains(package + ".")) + { + return false; + } + } + + return true; + } + private class PowerShellExecutionResults { public int ExitCode { get; set; } diff --git a/src/chocolatey/infrastructure/filesystem/DotNetFileSystem.cs b/src/chocolatey/infrastructure/filesystem/DotNetFileSystem.cs index 26e1d37426..468a521ec7 100644 --- a/src/chocolatey/infrastructure/filesystem/DotNetFileSystem.cs +++ b/src/chocolatey/infrastructure/filesystem/DotNetFileSystem.cs @@ -41,13 +41,14 @@ public sealed class DotNetFileSystem : IFileSystem private readonly int TIMES_TO_TRY_OPERATION = 3; private static Lazy environment_initializer = new Lazy(() => new Environment()); - private void allow_retries(Action action) + private void allow_retries(Action action, bool isSilent = false) { FaultTolerance.retry( TIMES_TO_TRY_OPERATION, action, waitDurationMilliseconds: 200, - increaseRetryByMilliseconds: 100); + increaseRetryByMilliseconds: 100, + isSilent:isSilent); } [EditorBrowsable(EditorBrowsableState.Never)] @@ -511,10 +512,15 @@ public void create_directory_if_not_exists(string directoryPath, bool ignoreErro public void delete_directory(string directoryPath, bool recursive) { - delete_directory(directoryPath, recursive, overrideAttributes: false); + delete_directory(directoryPath, recursive, overrideAttributes: false, isSilent: false); } public void delete_directory(string directoryPath, bool recursive, bool overrideAttributes) + { + delete_directory(directoryPath, recursive, overrideAttributes: overrideAttributes, isSilent: false); + } + + public void delete_directory(string directoryPath, bool recursive, bool overrideAttributes, bool isSilent) { if (string.IsNullOrWhiteSpace(directoryPath)) throw new ApplicationException("You must provide a directory to delete."); if (combine_paths(directoryPath, "").is_equal_to(combine_paths(Environment.GetEnvironmentVariable("SystemDrive"), ""))) throw new ApplicationException("Cannot move or delete the root of the system drive"); @@ -532,20 +538,26 @@ public void delete_directory(string directoryPath, bool recursive, bool override } } - this.Log().Debug(ChocolateyLoggers.Verbose, () => "Attempting to delete directory \"{0}\".".format_with(get_full_path(directoryPath))); - allow_retries(() => Directory.Delete(directoryPath, recursive)); + if (!isSilent) this.Log().Debug(ChocolateyLoggers.Verbose, () => "Attempting to delete directory \"{0}\".".format_with(get_full_path(directoryPath))); + allow_retries(() => Directory.Delete(directoryPath, recursive),isSilent: isSilent); } + public void delete_directory_if_exists(string directoryPath, bool recursive) { - delete_directory_if_exists(directoryPath, recursive, overrideAttributes: false); + delete_directory_if_exists(directoryPath, recursive, overrideAttributes: false, isSilent: false); } public void delete_directory_if_exists(string directoryPath, bool recursive, bool overrideAttributes) + { + delete_directory_if_exists(directoryPath, recursive, overrideAttributes: overrideAttributes, isSilent: false); + } + + public void delete_directory_if_exists(string directoryPath, bool recursive, bool overrideAttributes, bool isSilent) { if (directory_exists(directoryPath)) { - delete_directory(directoryPath, recursive, overrideAttributes); + delete_directory(directoryPath, recursive, overrideAttributes, isSilent); } } diff --git a/src/chocolatey/infrastructure/filesystem/IFileSystem.cs b/src/chocolatey/infrastructure/filesystem/IFileSystem.cs index cebd04fc36..bc86e4cb5d 100644 --- a/src/chocolatey/infrastructure/filesystem/IFileSystem.cs +++ b/src/chocolatey/infrastructure/filesystem/IFileSystem.cs @@ -356,12 +356,21 @@ public interface IFileSystem /// Override the attributes, e.g. delete readonly and/or system files. void delete_directory(string directoryPath, bool recursive, bool overrideAttributes); + /// + /// Deletes a directory + /// + /// The directory path. + /// Would you like to delete the directories inside of this directory? Almost always true. + /// Override the attributes, e.g. delete readonly and/or system files. + /// Should this method be silent? false by default + void delete_directory(string directoryPath, bool recursive, bool overrideAttributes, bool isSilent); + /// /// Deletes a directory if it exists /// /// The directory path. /// Would you like to delete the directories inside of this directory? Almost always true. - void delete_directory_if_exists(string directoryPath, bool recursive); + void delete_directory_if_exists(string directoryPath, bool recursive); /// /// Deletes a directory if it exists @@ -371,6 +380,15 @@ public interface IFileSystem /// Override the attributes, e.g. delete readonly and/or system files. void delete_directory_if_exists(string directoryPath, bool recursive, bool overrideAttributes); + /// + /// Deletes a directory if it exists + /// + /// The directory path. + /// Would you like to delete the directories inside of this directory? Almost always true. + /// Override the attributes, e.g. delete readonly and/or system files. + /// Should this method be silent? false by default + void delete_directory_if_exists(string directoryPath, bool recursive, bool overrideAttributes, bool isSilent); + #endregion /// diff --git a/src/chocolatey/infrastructure/licensing/License.cs b/src/chocolatey/infrastructure/licensing/License.cs new file mode 100644 index 0000000000..783942b2b4 --- /dev/null +++ b/src/chocolatey/infrastructure/licensing/License.cs @@ -0,0 +1,59 @@ +// 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.licensing +{ + using System; + using adapters; + using app; + using information; + using registration; + using Environment = System.Environment; + + public static class License + { + public static ChocolateyLicense validate_license() + { + var license = LicenseValidation.validate(); + if (license.is_licensed_version()) + { + try + { + var licensedAssembly = Assembly.LoadFile(ApplicationParameters.LicensedAssemblyLocation); + license.AssemblyLoaded = true; + license.Assembly = licensedAssembly; + license.Version = VersionInformation.get_current_informational_version(licensedAssembly); + Type licensedComponent = licensedAssembly.GetType(ApplicationParameters.LicensedComponentRegistry, throwOnError: false, ignoreCase: true); + SimpleInjectorContainer.add_component_registry_class(licensedComponent); + } + catch (Exception ex) + { + "chocolatey".Log().Error( +@"Error when attempting to load chocolatey licensed assembly. Ensure + that chocolatey.licensed.dll exists at + '{0}'. + Install with `choco install chocolatey.extension`. + The error message itself may be helpful as well:{1} {2}".format_with( + ApplicationParameters.LicensedAssemblyLocation, + Environment.NewLine, + ex.Message + )); + } + } + + return license; + } + } +} diff --git a/src/chocolatey/infrastructure/tolerance/FaultTolerance.cs b/src/chocolatey/infrastructure/tolerance/FaultTolerance.cs index 0854be3d63..9d12f923e1 100644 --- a/src/chocolatey/infrastructure/tolerance/FaultTolerance.cs +++ b/src/chocolatey/infrastructure/tolerance/FaultTolerance.cs @@ -18,6 +18,7 @@ namespace chocolatey.infrastructure.tolerance using System; using System.Threading; using configuration; + using logging; /// /// Provides methods that are able to tolerate faults and recover @@ -46,7 +47,8 @@ private static bool log_is_in_debug_mode() /// The action. /// The wait duration in milliseconds. /// The time for each try to increase the wait duration by in milliseconds. - public static void retry(int numberOfTries, Action action, int waitDurationMilliseconds = 100, int increaseRetryByMilliseconds = 0) + /// Log messages? + public static void retry(int numberOfTries, Action action, int waitDurationMilliseconds = 100, int increaseRetryByMilliseconds = 0, bool isSilent = false) { if (action == null) return; @@ -58,7 +60,8 @@ public static void retry(int numberOfTries, Action action, int waitDurationMilli return true; }, waitDurationMilliseconds, - increaseRetryByMilliseconds); + increaseRetryByMilliseconds, + isSilent); } /// @@ -71,13 +74,16 @@ public static void retry(int numberOfTries, Action action, int waitDurationMilli /// The time for each try to increase the wait duration by in milliseconds. /// The return value from the function /// You must specify a number of retries greater than zero. - public static T retry(int numberOfTries, Func function, int waitDurationMilliseconds = 100, int increaseRetryByMilliseconds = 0) + /// Log messages? + public static T retry(int numberOfTries, Func function, int waitDurationMilliseconds = 100, int increaseRetryByMilliseconds = 0, bool isSilent = false) { if (function == null) return default(T); if (numberOfTries == 0) throw new ApplicationException("You must specify a number of retries greater than zero."); var returnValue = default(T); var debugging = log_is_in_debug_mode(); + var logLocation = ChocolateyLoggers.Normal; + if (isSilent) logLocation = ChocolateyLoggers.LogFileOnly; for (int i = 1; i <= numberOfTries; i++) { @@ -90,7 +96,7 @@ public static T retry(int numberOfTries, Func function, int waitDurationMi { if (i == numberOfTries) { - "chocolatey".Log().Error("Maximum tries of {0} reached. Throwing error.".format_with(numberOfTries)); + "chocolatey".Log().Error(logLocation, "Maximum tries of {0} reached. Throwing error.".format_with(numberOfTries)); throw; } @@ -98,7 +104,7 @@ public static T retry(int numberOfTries, Func function, int waitDurationMi var exceptionMessage = debugging ? ex.ToString() : ex.Message; - "chocolatey".Log().Warn("This is try {3}/{4}. Retrying after {2} milliseconds.{0} Error converted to warning:{0} {1}".format_with( + "chocolatey".Log().Warn(logLocation, "This is try {3}/{4}. Retrying after {2} milliseconds.{0} Error converted to warning:{0} {1}".format_with( Environment.NewLine, exceptionMessage, retryWait,