diff --git a/.build.custom/ilmerge.internalize.ignore.dll.txt b/.build.custom/ilmerge.internalize.ignore.dll.txt new file mode 100644 index 0000000000..15e662b505 --- /dev/null +++ b/.build.custom/ilmerge.internalize.ignore.dll.txt @@ -0,0 +1,2 @@ +chocolatey.* +NuGet.* \ No newline at end of file diff --git a/.build.custom/ilmerge.internalize.ignore.txt b/.build.custom/ilmerge.internalize.ignore.txt index 120f0425b2..0a01835941 100644 --- a/.build.custom/ilmerge.internalize.ignore.txt +++ b/.build.custom/ilmerge.internalize.ignore.txt @@ -1,6 +1,6 @@ chocolatey.* -NuGet.Manifest -NuGet.IPackage -NuGet.PackageDependency -NuGet.IServerPackageMetadata -NuGet.SemanticVersion \ No newline at end of file +NuGet.* +SimpleInjector.* +Rhino.Licensing.* +log4net.* +Microsoft.Web.XmlTransform.* \ No newline at end of file diff --git a/.build.custom/ilmergeDLL.build b/.build.custom/ilmergeDLL.build index 860dddb781..12cb95e0a5 100644 --- a/.build.custom/ilmergeDLL.build +++ b/.build.custom/ilmergeDLL.build @@ -19,7 +19,7 @@ - + diff --git a/CHANGELOG.md b/CHANGELOG.md index 57034b7b0c..b3f337d715 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,30 +1,70 @@ ## [0.9.10](https://github.com/chocolatey/choco/issues?q=milestone%3A0.9.10+is%3Aclosed) (unreleased) -Alternative sources (webpi, windowsfeature, cygwin, etc) are back (finally, right?)! Use an internal PowerShell host to take advantage of quite a few improvements! +What will be highlighted: + +* Alternative sources (webpi, windowsfeature, cygwin, etc) are back (finally, right?)! +* Use an internal PowerShell host to take advantage of quite a few improvements! +* Introduce managing package templates, reintroduce extensions. +* Talk about using original download file name +* Talk about the improvements in search information +* Talk a little about what's coming with pro ### BREAKING CHANGES * Only fail automation scripts (chocolateyInstall.ps1) if the script returns non-zero exit code - see [#445](https://github.com/chocolatey/choco/issues/445) + * Fix - Force reinstall, force upgrade, and uninstall should delete the download cache - see [#590](https://github.com/chocolatey/choco/issues/590) + +For 445 - the 0.9.8 series would only fail a package with terminating errors. The 0.9.9 series took that a bit further and started failing packages if anything wrote to stderr. It turns out that is a bad idea. Only when PowerShell exits with non-zero (which comes with terminating errors) should the package fail due to this. If you need the old behavior of the 0.9.9 series, you can get it back with a switch (`--fail-on-standard-error` and its aliases) and/or a feature flip (`failOnStandardError`). + +For 590 - if you set a custom cache directory for downloads, it will no longer use a "chocolatey" subdirectory under that. You may need to make any adjustments if this is going to affect you. + +### KNOWN ISSUES + + * [Known Issues](https://github.com/chocolatey/choco/labels/Bug) + * [POSH Host] The handle is invalid - when output is being redirected and a package attempts to write to a filestream - see [#572](https://github.com/chocolatey/choco/issues/572) ### FEATURES * Alternative Sources - see [#14](https://github.com/chocolatey/choco/issues/14) - * Use Internal PowerShell Host - see [#8](https://github.com/chocolatey/choco/issues/8) + * [POSH Host] Use Internal PowerShell Host - see [#8](https://github.com/chocolatey/choco/issues/8) + * Manage package templates with a specially named package and special package folder - see [#542](https://github.com/chocolatey/choco/issues/542) + * Use the actual download file name instead of providing one - see [#435](https://github.com/chocolatey/choco/issues/435) * Support for custom headers - see [#332](https://github.com/chocolatey/choco/issues/332) +* [Security] Show moderation-related information in search results - see [#493](https://github.com/chocolatey/choco/issues/493) ### BUG FIXES - * Fix - Debug/Verbose messages not logged in install scripts (chocolateyInstall.ps1) - see [#520](https://github.com/chocolatey/choco/issues/520) + * [Security] Fix - Only load the Chocolatey PowerShell module from a known location - see [#560](https://github.com/chocolatey/choco/issues/560) + * Fix - Force should set allow-downgrade to true - see [#585](https://github.com/chocolatey/choco/issues/585) + * Fix - Do not use NuGet package cache - see [#479](https://github.com/chocolatey/choco/issues/479) + * Fix - TEMP environment variable is 8.3 Path on some systems - see [#532](https://github.com/chocolatey/choco/issues/532) + * Fix - `$packageName` should be present for zip uninstalls in uninstall script template - see [#534](https://github.com/chocolatey/choco/issues/534) + * Fix - Debug/Verbose messages not logged in automation scripts (chocolateyInstall.ps1) - see [#520](https://github.com/chocolatey/choco/issues/520) + * Fix - Escape log output for variables that have data from external sources - see [#565](https://github.com/chocolatey/choco/issues/565) + * Fix - Choco new silentargs can't pass in args in the param=value format - see [#510](https://github.com/chocolatey/choco/issues/510) + * Fix - Exception if no source is enabled - see [#490](https://github.com/chocolatey/choco/issues/490) + * Fix - Chocolatey command help output written to standard error instead of standard out - see [#468](https://github.com/chocolatey/choco/issues/468) * Fix - Logger doesn't clear cached NullLoggers - see [#516](https://github.com/chocolatey/choco/issues/516) * Fix - DISM "/All" argument in the wrong position - see [#480](https://github.com/chocolatey/choco/issues/480) - * Fix - Merging assemblies on a machine running .net 4.5 or higher produces binaries incompatible with .net 4 - see [#392](https://github.com/chocolatey/choco/issues/392) + * Fix - Merging assemblies on a machine running .Net 4.5 or higher produces binaries incompatible with .Net 4 - see [#392](https://github.com/chocolatey/choco/issues/392) * Fix - API - Incorrect log4net version in chocolatey.lib dependencies - see [#390](https://github.com/chocolatey/choco/issues/390) + * [POSH Host] Fix - Message after Download progress is on the same line sometimes - see [#525](https://github.com/chocolatey/choco/issues/525) + * [POSH Host] Fix - PowerShell internal process - "The handle is invalid." - see [#526](https://github.com/chocolatey/choco/issues/526) ### IMPROVEMENTS * AutoUninstaller is on by default - see [#308](https://github.com/chocolatey/choco/issues/308) + * Unset Configuration Values - see [#551](https://github.com/chocolatey/choco/issues/551) + * Ability to run "choco upgrade all" ignoring specific packages - see [#293](https://github.com/chocolatey/choco/issues/293) + * Extensions enhancements - see [#588](https://github.com/chocolatey/choco/issues/588) * Show human-readable file sizes when downloading - see [#363](https://github.com/chocolatey/choco/issues/363) - * API - Add the ability to retrieve package count for a Source - see [#431](https://github.com/chocolatey/choco/issues/431) + * [Security] Warn about environment changes - see [#563](https://github.com/chocolatey/choco/issues/563) + * Warn when execution timeout has elapsed - see [#561](https://github.com/chocolatey/choco/issues/561) + * Update nuspec to make it easier to get started - see [#535](https://github.com/chocolatey/choco/issues/535) + * Pro - Set download cache information if available - see [#562](https://github.com/chocolatey/choco/issues/562) + * Pro - Allow commands to be added - see [#583](https://github.com/chocolatey/choco/issues/583) + * Pro -Load/Provide hooks for licensed version - see [#584](https://github.com/chocolatey/choco/issues/584) + * API - Add the ability to retrieve package count for a Source - see [#431](https://github.com/chocolatey/choco/issues/431) * API - Chocolatey Lib still marks vital package information as internal - see [#433](https://github.com/chocolatey/choco/issues/433) * API - Add paging to list command - see [#427](https://github.com/chocolatey/choco/issues/427) diff --git a/lib/Rhino.Licensing/Rhino.Licensing.dll b/lib/Rhino.Licensing/Rhino.Licensing.dll index 11edab73fe..9e2570dbd2 100644 Binary files a/lib/Rhino.Licensing/Rhino.Licensing.dll and b/lib/Rhino.Licensing/Rhino.Licensing.dll differ diff --git a/nuget/chocolatey/chocolatey.nuspec b/nuget/chocolatey/chocolatey.nuspec index ce565a8571..2d15d300b5 100644 --- a/nuget/chocolatey/chocolatey.nuspec +++ b/nuget/chocolatey/chocolatey.nuspec @@ -2,10 +2,21 @@ chocolatey + 0.9.10 + + Rob Reynolds Chocolatey - 0.9.9 Rob Reynolds, The Chocolatey Team - Rob Reynolds + https://github.com/chocolatey/choco + https://github.com/chocolatey/chocolatey/raw/master/docs/logo/chocolateyicon.gif + https://raw.githubusercontent.com/chocolatey/choco/master/LICENSE + false + RealDimensions Software, LLC - 2011-Present + + nuget apt-get machine repository chocolatey Chocolatey is your machine level NuGet repository. Think apt-get for Windows (executables/application packages), not library packages. Chocolatey is a package manager for Windows (like apt-get but for Windows). It was designed to be a decentralized framework for quickly installing applications and tools that you need. It is built on the NuGet infrastructure currently using PowerShell as its focus for delivering packages from the distros to your door, err computer. @@ -23,6 +34,7 @@ There are quite a few commands you can call - you should check out the [command * Config - choco config list * Install - choco install baretail * Pin - choco pin windirstat + * Outdated - choco outdated * Upgrade - choco upgrade baretail * Uninstall - choco uninstall baretail @@ -42,42 +54,75 @@ In that mess there is a link to the [Helper Reference](https://github.com/chocol See all - https://github.com/chocolatey/choco/blob/stable/CHANGELOG.md -## 0.9.10 +## 0.9.10 -Alternative sources (webpi, windowsfeature, cygwin, etc) are back (finally, right?)! Use an internal PowerShell host to take advantage of quite a few improvements! +What will be highlighted: + +* Alternative sources (webpi, windowsfeature, cygwin, etc) are back (finally, right?)! +* Use an internal PowerShell host to take advantage of quite a few improvements! +* Introduce managing package templates, reintroduce extensions. +* Talk about using original download file name +* Talk about the improvements in search information +* Talk a little about what's coming with pro ### BREAKING CHANGES * Only fail automation scripts (chocolateyInstall.ps1) if the script returns non-zero exit code - see [#445](https://github.com/chocolatey/choco/issues/445) + * Fix - Force reinstall, force upgrade, and uninstall should delete the download cache - see [#590](https://github.com/chocolatey/choco/issues/590) + +For 445 - the 0.9.8 series would only fail a package with terminating errors. The 0.9.9 series took that a bit further and started failing packages if anything wrote to stderr. It turns out that is a bad idea. Only when PowerShell exits with non-zero (which comes with terminating errors) should the package fail due to this. If you need the old behavior of the 0.9.9 series, you can get it back with a switch (`--fail-on-standard-error` and its aliases) and/or a feature flip (`failOnStandardError`). + +For 590 - if you set a custom cache directory for downloads, it will no longer use a "chocolatey" subdirectory under that. You may need to make any adjustments if this is going to affect you. + +### KNOWN ISSUES + + * [Known Issues](https://github.com/chocolatey/choco/labels/Bug) + * [POSH Host] The handle is invalid - when output is being redirected and a package attempts to write to a filestream - see [#572](https://github.com/chocolatey/choco/issues/572) ### FEATURES * Alternative Sources - see [#14](https://github.com/chocolatey/choco/issues/14) - * Use Internal PowerShell Host - see [#8](https://github.com/chocolatey/choco/issues/8) + * [POSH Host] Use Internal PowerShell Host - see [#8](https://github.com/chocolatey/choco/issues/8) + * Manage package templates with a specially named package and special package folder - see [#542](https://github.com/chocolatey/choco/issues/542) + * Use the actual download file name instead of providing one - see [#435](https://github.com/chocolatey/choco/issues/435) * Support for custom headers - see [#332](https://github.com/chocolatey/choco/issues/332) +* [Security] Show moderation-related information in search results - see [#493](https://github.com/chocolatey/choco/issues/493) ### BUG FIXES - * Fix - Debug/Verbose messages not logged in install scripts (chocolateyInstall.ps1) - see [#520](https://github.com/chocolatey/choco/issues/520) + * [Security] Fix - Only load the Chocolatey PowerShell module from a known location - see [#560](https://github.com/chocolatey/choco/issues/560) + * Fix - Force should set allow-downgrade to true - see [#585](https://github.com/chocolatey/choco/issues/585) + * Fix - Do not use NuGet package cache - see [#479](https://github.com/chocolatey/choco/issues/479) + * Fix - TEMP environment variable is 8.3 Path on some systems - see [#532](https://github.com/chocolatey/choco/issues/532) + * Fix - `$packageName` should be present for zip uninstalls in uninstall script template - see [#534](https://github.com/chocolatey/choco/issues/534) + * Fix - Debug/Verbose messages not logged in automation scripts (chocolateyInstall.ps1) - see [#520](https://github.com/chocolatey/choco/issues/520) + * Fix - Escape log output for variables that have data from external sources - see [#565](https://github.com/chocolatey/choco/issues/565) + * Fix - Choco new silentargs can't pass in args in the param=value format - see [#510](https://github.com/chocolatey/choco/issues/510) + * Fix - Exception if no source is enabled - see [#490](https://github.com/chocolatey/choco/issues/490) + * Fix - Chocolatey command help output written to standard error instead of standard out - see [#468](https://github.com/chocolatey/choco/issues/468) * Fix - Logger doesn't clear cached NullLoggers - see [#516](https://github.com/chocolatey/choco/issues/516) * Fix - DISM "/All" argument in the wrong position - see [#480](https://github.com/chocolatey/choco/issues/480) - * Fix - Merging assemblies on a machine running .net 4.5 or higher produces binaries incompatible with .net 4 - see [#392](https://github.com/chocolatey/choco/issues/392) + * Fix - Merging assemblies on a machine running .Net 4.5 or higher produces binaries incompatible with .Net 4 - see [#392](https://github.com/chocolatey/choco/issues/392) * Fix - API - Incorrect log4net version in chocolatey.lib dependencies - see [#390](https://github.com/chocolatey/choco/issues/390) + * [POSH Host] Fix - Message after Download progress is on the same line sometimes - see [#525](https://github.com/chocolatey/choco/issues/525) + * [POSH Host] Fix - PowerShell internal process - "The handle is invalid." - see [#526](https://github.com/chocolatey/choco/issues/526) ### IMPROVEMENTS * AutoUninstaller is on by default - see [#308](https://github.com/chocolatey/choco/issues/308) + * Unset Configuration Values - see [#551](https://github.com/chocolatey/choco/issues/551) + * Ability to run "choco upgrade all" ignoring specific packages - see [#293](https://github.com/chocolatey/choco/issues/293) + * Extensions enhancements - see [#588](https://github.com/chocolatey/choco/issues/588) * Show human-readable file sizes when downloading - see [#363](https://github.com/chocolatey/choco/issues/363) - * API - Add the ability to retrieve package count for a Source - see [#431](https://github.com/chocolatey/choco/issues/431) + * [Security] Warn about environment changes - see [#563](https://github.com/chocolatey/choco/issues/563) + * Warn when execution timeout has elapsed - see [#561](https://github.com/chocolatey/choco/issues/561) + * Update nuspec to make it easier to get started - see [#535](https://github.com/chocolatey/choco/issues/535) + * Pro - Set download cache information if available - see [#562](https://github.com/chocolatey/choco/issues/562) + * Pro - Allow commands to be added - see [#583](https://github.com/chocolatey/choco/issues/583) + * Pro -Load/Provide hooks for licensed version - see [#584](https://github.com/chocolatey/choco/issues/584) + * API - Add the ability to retrieve package count for a Source - see [#431](https://github.com/chocolatey/choco/issues/431) * API - Chocolatey Lib still marks vital package information as internal - see [#433](https://github.com/chocolatey/choco/issues/433) * API - Add paging to list command - see [#427](https://github.com/chocolatey/choco/issues/427) - - https://github.com/chocolatey/choco - https://raw.githubusercontent.com/chocolatey/choco/master/LICENSE - false - RealDimensions Software, LLC - 2011-Present - nuget apt-get machine repository chocolatey - https://github.com/chocolatey/chocolatey/raw/master/docs/logo/chocolateyicon.gif diff --git a/src/chocolatey.console/Program.cs b/src/chocolatey.console/Program.cs index ba9a53ce25..059e4764de 100644 --- a/src/chocolatey.console/Program.cs +++ b/src/chocolatey.console/Program.cs @@ -28,10 +28,10 @@ namespace chocolatey.console using infrastructure.configuration; using infrastructure.extractors; using infrastructure.filesystem; + using infrastructure.information; using infrastructure.licensing; using infrastructure.logging; using infrastructure.registration; - using infrastructure.services; using resources; using Console = System.Console; using Environment = System.Environment; @@ -52,7 +52,32 @@ private static void Main(string[] args) Bootstrap.initialize(); Bootstrap.startup(); + var license = LicenseValidation.validate(); + if (license.is_licensed_version()) + { + try + { + var licensedAssembly = Assembly.LoadFile(ApplicationParameters.LicensedAssemblyLocation); + license.AssemblyLoaded = true; + license.Version = VersionInformation.get_current_informational_version(licensedAssembly); + Type licensedComponent = licensedAssembly.GetType(ApplicationParameters.LicensedComponentRegistry, throwOnError: true, 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}'. + The error message itself may be helpful as well:{1} {2}".format_with( + ApplicationParameters.LicensedAssemblyLocation, + Environment.NewLine, + ex.Message + )); + } + } var container = SimpleInjectorContainer.Container; + var config = container.GetInstance(); var fileSystem = container.GetInstance(); @@ -61,8 +86,8 @@ private static void Main(string[] args) ConfigurationBuilder.set_up_configuration( args, config, - fileSystem, - container.GetInstance(), + container, + license, warning => { warnings.Add(warning); } ); Config.initialize_with(config); @@ -75,18 +100,17 @@ private static void Main(string[] args) { "logfile".Log().Info(() => "".PadRight(60, '=')); #if DEBUG - "chocolatey".Log().Info(ChocolateyLoggers.Important, () => "{0} v{1} (DEBUG BUILD)".format_with(ApplicationParameters.Name, config.Information.ChocolateyProductVersion)); -#else + "chocolatey".Log().Info(ChocolateyLoggers.Important, () => "{0} v{1}{2} (DEBUG BUILD)".format_with(ApplicationParameters.Name, config.Information.ChocolateyProductVersion, license.is_licensed_version() ? " {0}".format_with(config.Information.LicenseType) : string.Empty)); +#else if (config.Information.ChocolateyVersion == config.Information.ChocolateyProductVersion && args.Any()) { - "logfile".Log().Info(() => "{0} v{1}".format_with(ApplicationParameters.Name, config.Information.ChocolateyProductVersion)); + "logfile".Log().Info(() => "{0} v{1}{2}".format_with(ApplicationParameters.Name, config.Information.ChocolateyProductVersion, license.is_licensed_version() ? " {0}".format_with(config.Information.LicenseType) : string.Empty)); } else { - "chocolatey".Log().Info(ChocolateyLoggers.Important, () => "{0} v{1}".format_with(ApplicationParameters.Name, config.Information.ChocolateyProductVersion)); + "chocolatey".Log().Info(ChocolateyLoggers.Important, () => "{0} v{1}{2}".format_with(ApplicationParameters.Name, config.Information.ChocolateyProductVersion, license.is_licensed_version() ? " {0}".format_with(config.Information.LicenseType) : string.Empty)); } #endif - } if (warnings.Count != 0 && config.RegularOutput) @@ -110,8 +134,6 @@ private static void Main(string[] args) remove_old_chocolatey_exe(fileSystem); - LicenseValidation.validate(fileSystem); - //refactor - thank goodness this is temporary, cuz manifest resource streams are dumb IList folders = new List { diff --git a/src/chocolatey.resources/helpers/chocolateyInstaller.psm1 b/src/chocolatey.resources/helpers/chocolateyInstaller.psm1 index 27dd72f314..1caa54f1ea 100644 --- a/src/chocolatey.resources/helpers/chocolateyInstaller.psm1 +++ b/src/chocolatey.resources/helpers/chocolateyInstaller.psm1 @@ -44,11 +44,23 @@ Get-Item $helpersPath\functions\*.ps1 | # load extensions if they exist $extensionsPath = Join-Path "$helpersPath" '..\extensions' -if(Test-Path($extensionsPath)) { +if (Test-Path($extensionsPath)) { Write-Debug 'Loading community extensions' #Resolve-Path $extensionsPath\**\*\*.psm1 | % { Write-Debug "Importing `'$_`'"; Import-Module $_.ProviderPath } Get-ChildItem $extensionsPath -recurse -filter "*.psm1" | Select -ExpandProperty FullName | % { Write-Debug "Importing `'$_`'"; Import-Module $_; } - Get-ChildItem $extensionsPath -recurse -filter "*.dll" | Select -ExpandProperty FullName | % { Write-Debug "Importing `'$_`'"; Import-Module $_; } + Get-ChildItem $extensionsPath -recurse -filter "*.dll" | Select -ExpandProperty FullName | % { + $path = $_; + try { + Write-Debug "Importing '$path'"; + Import-Module $path; + } catch { + if ($env:ChocolateyPowerShellHost -eq 'true') { + Write-Warning "Import failed for '$path'. Error: '$_'" + } else { + Write-Warning "Import failed for '$path'. If it depends on a newer version of the .NET framework, please make sure you are using the built-in PowerShell Host. Error: '$_'" + } + } + } } Export-ModuleMember -Function * -Alias * -Cmdlet * diff --git a/src/chocolatey.resources/helpers/functions/Get-ChocolateyWebFile.ps1 b/src/chocolatey.resources/helpers/functions/Get-ChocolateyWebFile.ps1 index e47a5b349c..011370d0e1 100644 --- a/src/chocolatey.resources/helpers/functions/Get-ChocolateyWebFile.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-ChocolateyWebFile.ps1 @@ -187,10 +187,13 @@ param( } Start-Sleep 2 #give it a sec or two to finish up copying - + $fi = new-object System.IO.FileInfo($fileFullPath) # validate file exists if (!($fi.Exists)) { throw "Chocolatey expected a file to be downloaded to `'$fileFullPath`' but nothing exists at that location." } + + Get-VirusCheckValid -location $url -file $fileFullPath + if ($headers.Count -ne 0) { # validate length is what we expected Write-Debug "Checking that `'$fileFullPath`' is the size we expect it to be." @@ -203,13 +206,8 @@ param( } } - Write-Debug "Verifying package provided checksum of `'$checksum`' for `'$fileFullPath`'." + Write-Debug "Verifying package provided checksum of '$checksum' for '$fileFullPath'." Get-CheckSumValid -file $fileFullPath -checkSum $checksum -checksumType $checksumType - # Virus check is not able to be performed, must note that. - # $url is already set properly to the used location. - #Write-Debug "Verifying downloaded file is not known to contain viruses. FilePath: `'$fileFullPath`'." - #Get-VirusCheckValid -location $url -file $fileFullPath - return $fileFullPath } diff --git a/src/chocolatey.resources/helpers/functions/Get-VirusCheckValid.ps1 b/src/chocolatey.resources/helpers/functions/Get-VirusCheckValid.ps1 index f6ddadd49c..4b4064bc51 100644 --- a/src/chocolatey.resources/helpers/functions/Get-VirusCheckValid.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-VirusCheckValid.ps1 @@ -14,15 +14,9 @@ function Get-VirusCheckValid { param( - [string] $location, + [string] $url, [string] $file = '' ) - Write-Debug "Running 'Get-VirusCheckValid' with location:`'$location`', file: `'$file`'"; - - Write-Debug "Right now there is no virus checking built in." - #if ($settings:virusCheck) { - - #} - - #if virus check is invalid, throw here + Write-Debug "No virus checking built into FOSS Chocolatey." + #Write-Debug "Running 'Get-VirusCheckValid' with url:`'$url`', file: `'$file`'"; } diff --git a/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 b/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 index 2cfbe0eb30..397bb8ad39 100644 --- a/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 +++ b/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 @@ -101,7 +101,7 @@ 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 = Join-Path $env:TEMP "chocolatey" + $chocTempDir = $env:TEMP $tempDir = Join-Path $chocTempDir "$packageName" if ($env:packageVersion -ne $null) {$tempDir = Join-Path $tempDir "$env:packageVersion"; } diff --git a/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 b/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 index 48ef8a6508..80c27ce04e 100644 --- a/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 +++ b/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 @@ -93,7 +93,7 @@ param( $fileType = 'zip' - $chocTempDir = Join-Path $env:TEMP "chocolatey" + $chocTempDir = $env:TEMP $tempDir = Join-Path $chocTempDir "$packageName" if ($env:packageVersion -ne $null) {$tempDir = Join-Path $tempDir "$env:packageVersion"; } diff --git a/src/chocolatey.tests.integration/NUnitSetup.cs b/src/chocolatey.tests.integration/NUnitSetup.cs index d2e187acc4..d150b16131 100644 --- a/src/chocolatey.tests.integration/NUnitSetup.cs +++ b/src/chocolatey.tests.integration/NUnitSetup.cs @@ -21,6 +21,7 @@ namespace chocolatey.tests.integration using System.Linq; using System.Reflection; using System.Threading; + using chocolatey.infrastructure.licensing; using NUnit.Framework; using SimpleInjector; using chocolatey.infrastructure.app; @@ -56,7 +57,7 @@ public override void BeforeEverything() unpack_self(Container, config); build_packages(Container, config); - ConfigurationBuilder.set_up_configuration(new List(), config, Container.GetInstance(), Container.GetInstance(), null); + ConfigurationBuilder.set_up_configuration(new List(), config, Container, new ChocolateyLicense(), null); MockLogger.reset(); } diff --git a/src/chocolatey.tests.integration/Scenario.cs b/src/chocolatey.tests.integration/Scenario.cs index 1b0f30b10f..3d43e5970a 100644 --- a/src/chocolatey.tests.integration/Scenario.cs +++ b/src/chocolatey.tests.integration/Scenario.cs @@ -162,7 +162,7 @@ public static ChocolateyConfiguration uninstall() public static ChocolateyConfiguration list() { var config = baseline_configuration(); - config.CommandName = CommandNameType.list.to_string(); + config.CommandName = "list"; return config; } @@ -170,7 +170,7 @@ public static ChocolateyConfiguration list() public static ChocolateyConfiguration pin() { var config = baseline_configuration(); - config.CommandName = CommandNameType.pin.to_string(); + config.CommandName = "pin"; return config; } diff --git a/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs b/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs index 8ef598d800..bc06141b95 100644 --- a/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs +++ b/src/chocolatey.tests.integration/scenarios/UpgradeScenarios.cs @@ -19,6 +19,7 @@ namespace chocolatey.tests.integration.scenarios using System.Collections.Concurrent; using System.IO; using System.Linq; + using System.Threading; using System.Xml.XPath; using NUnit.Framework; using NuGet; @@ -1848,7 +1849,15 @@ public override void Context() string dotChocolatey = Path.Combine(Scenario.get_top_level(), ".chocolatey"); if (Directory.Exists(dotChocolatey)) { - Directory.Delete(dotChocolatey, recursive: true); + try + { + Directory.Delete(dotChocolatey, recursive: true); + } + catch (Exception) + { + Thread.Sleep(2000); + Directory.Delete(dotChocolatey, recursive: true); + } } } diff --git a/src/chocolatey.tests/infrastructure.app/attributes/CommandForAttributeSpecs.cs b/src/chocolatey.tests/infrastructure.app/attributes/CommandForAttributeSpecs.cs index 39c8e976bf..27f8d5fc38 100644 --- a/src/chocolatey.tests/infrastructure.app/attributes/CommandForAttributeSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/attributes/CommandForAttributeSpecs.cs @@ -32,7 +32,7 @@ public class when_CommandForAttribute_is_set_with_string : CommandForAttributeSp public override void Context() { - attribute = new CommandForAttribute("bob"); + attribute = new CommandForAttribute("bob",""); } public override void Because() @@ -46,26 +46,5 @@ public void should_be_set_to_the_string() result.ShouldEqual("bob"); } } - - public class when_CommandForAttribute_is_set_with_CommandNameType : CommandForAttributeSpecsBase - { - private string result; - - public override void Context() - { - attribute = new CommandForAttribute(CommandNameType.@new); - } - - public override void Because() - { - result = attribute.CommandName; - } - - [Fact] - public void should_be_set_to_a_string_representation_of_the_CommandNameType() - { - result.ShouldEqual("new"); - } - } } } \ No newline at end of file diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyApiKeyCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyApiKeyCommandSpecs.cs index 73188189b0..df67389c0f 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyApiKeyCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyApiKeyCommandSpecs.cs @@ -54,13 +54,13 @@ public override void Because() [Fact] public void should_implement_apikey() { - results.ShouldContain(CommandNameType.apikey.to_string()); + results.ShouldContain("apikey"); } [Fact] public void should_implement_setapikey() { - results.ShouldContain(CommandNameType.setapikey.to_string()); + results.ShouldContain("setapikey"); } } diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyConfigCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyConfigCommandSpecs.cs index 95d4720d46..8ba1b0df08 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyConfigCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyConfigCommandSpecs.cs @@ -53,7 +53,7 @@ public override void Because() [Fact] public void should_implement_config() { - results.ShouldContain(CommandNameType.config.to_string()); + results.ShouldContain("config"); } } diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyFeatureCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyFeatureCommandSpecs.cs index 0c4943434c..4d404b18cd 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyFeatureCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyFeatureCommandSpecs.cs @@ -39,13 +39,13 @@ public override void Because() [Fact] public void should_implement_feature() { - results.ShouldContain(CommandNameType.feature.to_string()); + results.ShouldContain("feature"); } [Fact] public void should_implement_features() { - results.ShouldContain(CommandNameType.features.to_string()); + results.ShouldContain("features"); } } diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyListCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyListCommandSpecs.cs index c4b2499c7b..130663b863 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyListCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyListCommandSpecs.cs @@ -55,13 +55,13 @@ public override void Because() [Fact] public void should_implement_list() { - results.ShouldContain(CommandNameType.list.to_string()); + results.ShouldContain("list"); } [Fact] public void should_implement_search() { - results.ShouldContain(CommandNameType.search.to_string()); + results.ShouldContain("search"); } } diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyNewCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyNewCommandSpecs.cs index 846b513ad7..6710661be0 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyNewCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyNewCommandSpecs.cs @@ -54,7 +54,6 @@ public override void Because() [Fact] public void should_implement_new() { - results.ShouldContain(CommandNameType.@new.to_string()); results.ShouldContain("new"); } } diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyOutdatedCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyOutdatedCommandSpecs.cs index 4a67f2dad1..59dd99d5f4 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyOutdatedCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyOutdatedCommandSpecs.cs @@ -54,7 +54,7 @@ public override void Because() [Fact] public void should_implement_outdated() { - results.ShouldContain(CommandNameType.outdated.to_string()); + results.ShouldContain("outdated"); } } diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPackCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPackCommandSpecs.cs index 10f072578d..d6f280acaf 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPackCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPackCommandSpecs.cs @@ -52,7 +52,7 @@ public override void Because() [Fact] public void should_implement_pack() { - results.ShouldContain(CommandNameType.pack.to_string()); + results.ShouldContain("pack"); } } diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs index e9248924b2..1e40c0e4a1 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs @@ -80,7 +80,7 @@ public override void Because() [Fact] public void should_implement_source() { - results.ShouldContain(CommandNameType.pin.to_string()); + results.ShouldContain("pin"); } } diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPushCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPushCommandSpecs.cs index cf40295cfa..4cad545e65 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPushCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPushCommandSpecs.cs @@ -56,7 +56,7 @@ public override void Because() [Fact] public void should_implement_push() { - results.ShouldContain(CommandNameType.push.to_string()); + results.ShouldContain("push"); } } diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateySourceCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateySourceCommandSpecs.cs index 55e6654e34..7879183bad 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateySourceCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateySourceCommandSpecs.cs @@ -54,13 +54,13 @@ public override void Because() [Fact] public void should_implement_source() { - results.ShouldContain(CommandNameType.source.to_string()); + results.ShouldContain("source"); } [Fact] public void should_implement_sources() { - results.ShouldContain(CommandNameType.sources.to_string()); + results.ShouldContain("sources"); } } diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyUnpackSelfCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyUnpackSelfCommandSpecs.cs index f0364258bd..ab49cdaf5a 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyUnpackSelfCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyUnpackSelfCommandSpecs.cs @@ -55,7 +55,7 @@ public override void Because() [Fact] public void should_implement_unpackself() { - results.ShouldContain(CommandNameType.unpackself.to_string()); + results.ShouldContain("unpackself"); } } diff --git a/src/chocolatey/GetChocolatey.cs b/src/chocolatey/GetChocolatey.cs index d35529b113..de3e8f11a9 100644 --- a/src/chocolatey/GetChocolatey.cs +++ b/src/chocolatey/GetChocolatey.cs @@ -17,6 +17,7 @@ namespace chocolatey { using System; using System.Collections.Generic; + using infrastructure.licensing; using SimpleInjector; using infrastructure.adapters; using infrastructure.app; @@ -51,6 +52,7 @@ public class GetChocolatey { private readonly Container _container; private Action _propConfig; + private ChocolateyLicense _license; /// /// Initializes a new instance of the class. @@ -59,6 +61,7 @@ public GetChocolatey() { Log4NetAppenderConfiguration.configure(); Bootstrap.initialize(); + _license = LicenseValidation.validate(); _container = SimpleInjectorContainer.Container; } @@ -218,7 +221,7 @@ public int ListCount() private ChocolateyConfiguration create_configuration(IList args) { var configuration = new ChocolateyConfiguration(); - ConfigurationBuilder.set_up_configuration(args, configuration, _container.GetInstance(), _container.GetInstance(), 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 9cb61a21b2..764c16fda4 100644 --- a/src/chocolatey/chocolatey.csproj +++ b/src/chocolatey/chocolatey.csproj @@ -125,6 +125,8 @@ + + diff --git a/src/chocolatey/infrastructure.app/ApplicationParameters.cs b/src/chocolatey/infrastructure.app/ApplicationParameters.cs index cbff6518c2..3a10e90774 100644 --- a/src/chocolatey/infrastructure.app/ApplicationParameters.cs +++ b/src/chocolatey/infrastructure.app/ApplicationParameters.cs @@ -44,6 +44,8 @@ public static class ApplicationParameters public static readonly string ChocolateyConfigFileResource = @"chocolatey.infrastructure.app.configuration.chocolatey.config"; public static readonly string GlobalConfigFileLocation = _fileSystem.combine_paths(InstallLocation, "config", "chocolatey.config"); public static readonly string LicenseFileLocation = _fileSystem.combine_paths(InstallLocation, "license", "chocolatey.license.xml"); + public static readonly string LicensedAssemblyLocation = _fileSystem.combine_paths(InstallLocation, "extensions", "chocolatey", "chocolatey.licensed.dll"); + public static readonly string LicensedComponentRegistry = @"chocolatey.licensed.infrastructure.app.registration.ContainerBinding"; public static readonly string PackageNamesSeparator = ";"; public static readonly string OfficialChocolateyPublicKey = "79d02ea9cad655eb"; @@ -93,6 +95,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 VirusCheckMinimumPositives = "virusCheckMinimumPositives"; } public static class Features @@ -104,6 +107,7 @@ public static class Features public static readonly string FailOnStandardError = "failOnStandardError"; public static readonly string UsePowerShellHost = "powershellHost"; public static readonly string LogEnvironmentValues = "logEnvironmentValues"; + public static readonly string VirusCheck = "virusCheck"; } public static class Messages diff --git a/src/chocolatey/infrastructure.app/attributes/CommandForAttribute.cs b/src/chocolatey/infrastructure.app/attributes/CommandForAttribute.cs index 60984aa7f1..687ec99c23 100644 --- a/src/chocolatey/infrastructure.app/attributes/CommandForAttribute.cs +++ b/src/chocolatey/infrastructure.app/attributes/CommandForAttribute.cs @@ -22,15 +22,12 @@ namespace chocolatey.infrastructure.app.attributes public sealed class CommandForAttribute : Attribute { public string CommandName { get; private set; } + public string Description { get; private set; } - public CommandForAttribute(CommandNameType commandName) - { - CommandName = commandName.to_string(); - } - - public CommandForAttribute(string commandName) + public CommandForAttribute(string commandName, string description) { CommandName = commandName; + Description = description; } } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs b/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs index f279805b19..d5232b9e08 100644 --- a/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs +++ b/src/chocolatey/infrastructure.app/builders/ConfigurationBuilder.cs @@ -21,16 +21,19 @@ namespace chocolatey.infrastructure.app.builders using System.Linq; using System.Text; using adapters; + using attributes; using configuration; - using domain; using extractors; using filesystem; using information; + using infrastructure.commands; using infrastructure.services; + using licensing; using logging; using nuget; using platforms; using tolerance; + using Container = SimpleInjector.Container; using Environment = adapters.Environment; /// @@ -56,15 +59,18 @@ private static IEnvironment Environment /// /// The arguments. /// The configuration. - /// The file system. - /// The XML service. + /// The container. + /// The license. /// Notify warn logging action - public static void set_up_configuration(IList args, ChocolateyConfiguration config, IFileSystem fileSystem, IXmlService xmlService, Action notifyWarnLoggingAction) + public static void set_up_configuration(IList args, ChocolateyConfiguration config, Container container, ChocolateyLicense license, Action notifyWarnLoggingAction) { + var fileSystem = container.GetInstance(); + var xmlService = container.GetInstance(); set_file_configuration(config, fileSystem, xmlService, notifyWarnLoggingAction); ConfigurationOptions.reset_options(); - set_global_options(args, config); + set_global_options(args, config, container); set_environment_options(config); + set_license_options(config, license); set_environment_variables(config); } @@ -128,7 +134,7 @@ private static void set_machine_sources(ChocolateyConfiguration config, ConfigFi private static void set_config_items(ChocolateyConfiguration config, ConfigFileSettings configFileSettings, IFileSystem fileSystem) { var cacheLocation = set_config_item(ApplicationParameters.ConfigSettings.CacheLocation, configFileSettings, string.IsNullOrWhiteSpace(configFileSettings.CacheLocation) ? string.Empty : configFileSettings.CacheLocation, "Cache location if not TEMP folder."); - config.CacheLocation = !string.IsNullOrWhiteSpace(cacheLocation) ? cacheLocation : fileSystem.get_temp_path(); // System.Environment.GetEnvironmentVariable("TEMP"); + config.CacheLocation = !string.IsNullOrWhiteSpace(cacheLocation) ? cacheLocation : fileSystem.combine_paths(fileSystem.get_temp_path(), "chocolatey"); // System.Environment.GetEnvironmentVariable("TEMP"); if (string.IsNullOrWhiteSpace(config.CacheLocation)) { config.CacheLocation = fileSystem.combine_paths(ApplicationParameters.InstallLocation, "temp"); @@ -156,6 +162,10 @@ private static void set_config_items(ChocolateyConfiguration config, ConfigFileS 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."); config.Proxy.EncryptedPassword = set_config_item(ApplicationParameters.ConfigSettings.ProxyPassword, configFileSettings, string.Empty, "Optional proxy password. Encrypted."); + + int minPositives=0; + int.TryParse(set_config_item(ApplicationParameters.ConfigSettings.VirusCheckMinimumPositives, configFileSettings, "5", "Optional proxy password. Encrypted."), out minPositives); + config.VirusCheckMinimumPositives = minPositives == 0 ? 5 : minPositives; } private static string set_config_item(string configName, ConfigFileSettings configFileSettings, string defaultValue, string description, bool forceSettingValue = false) @@ -190,6 +200,7 @@ private static void set_feature_flags(ChocolateyConfiguration config, ConfigFile config.Features.FailOnStandardError = set_feature_flag(ApplicationParameters.Features.FailOnStandardError, configFileSettings, defaultEnabled: false, description: "Fail if install provider writes to stderr."); config.Features.UsePowerShellHost = set_feature_flag(ApplicationParameters.Features.UsePowerShellHost, configFileSettings, defaultEnabled: true, description: "Use Chocolatey's built-in PowerShell host."); config.Features.LogEnvironmentValues = set_feature_flag(ApplicationParameters.Features.LogEnvironmentValues, configFileSettings, defaultEnabled: false, description: "Log Environment Values - will log values of environment before and after install (could disclose sensitive data)."); + config.Features.VirusCheck = set_feature_flag(ApplicationParameters.Features.VirusCheck, configFileSettings, defaultEnabled: false, description: "Virus Check [licensed versions only] - perform virus checking on downloaded files."); config.PromptForConfirmation = !set_feature_flag(ApplicationParameters.Features.AllowGlobalConfirmation, configFileSettings, defaultEnabled: false, description: "Prompt for confirmation in scripts or bypass."); } @@ -221,7 +232,7 @@ private static bool set_feature_flag(string featureName, ConfigFileSettings conf return feature != null ? feature.Enabled : defaultEnabled; } - private static void set_global_options(IList args, ChocolateyConfiguration config) + private static void set_global_options(IList args, ChocolateyConfiguration config, Container container) { ConfigurationOptions.parse_arguments_and_update_configuration( args, @@ -283,9 +294,14 @@ private static void set_global_options(IList args, ChocolateyConfigurati () => { var commandsLog = new StringBuilder(); - foreach (var command in Enum.GetValues(typeof (CommandNameType)).Cast()) + IEnumerable commands = container.GetAllInstances(); + foreach (var command in commands.or_empty_list_if_null()) { - commandsLog.AppendFormat(" * {0}\n", command.get_description_or_value()); + var attributes = command.GetType().GetCustomAttributes(typeof(CommandForAttribute), false).Cast(); + foreach (var attribute in attributes.or_empty_list_if_null()) + { + commandsLog.AppendFormat(" * {0} - {1}\n", attribute.CommandName, attribute.Description); + } } "chocolatey".Log().Info(@"This is a listing of all of the different things you can pass to choco. @@ -341,6 +357,21 @@ private static void set_environment_options(ChocolateyConfiguration config) config.Information.IsProcessElevated = ProcessInformation.process_is_elevated(); } + private static void set_license_options(ChocolateyConfiguration config, ChocolateyLicense license) + { + config.Information.LicenseExpirationDate = license.ExpirationDate; + config.Information.LicenseIsValid = license.IsValid; + config.Information.LicenseVersion = license.Version ?? string.Empty; + config.Information.LicenseType = license.is_licensed_version() ? license.LicenseType.get_description_or_value() : string.Empty; + + var licenseName = license.Name.to_string(); + if (licenseName.Contains("@")) + { + licenseName = licenseName.Remove(licenseName.IndexOf("@", StringComparison.InvariantCulture)) + "[at REDACTED])"; + } + config.Information.LicenseUserName = licenseName; + } + public static void set_environment_variables(ChocolateyConfiguration config) { Environment.SetEnvironmentVariable(ApplicationParameters.ChocolateyInstallEnvironmentVariableName, ApplicationParameters.InstallLocation); @@ -353,20 +384,12 @@ public static void set_environment_variables(ChocolateyConfiguration config) Environment.SetEnvironmentVariable("OS_IS64BIT", config.Information.Is64Bit ? "true" : "false"); Environment.SetEnvironmentVariable("IS_ADMIN", config.Information.IsUserAdministrator ? "true" : "false"); Environment.SetEnvironmentVariable("IS_PROCESSELEVATED", config.Information.IsProcessElevated ? "true" : "false"); - Environment.SetEnvironmentVariable("TEMP", config.CacheLocation); - if (config.Debug) - { - Environment.SetEnvironmentVariable("ChocolateyEnvironmentDebug", "true"); - } - if (config.Verbose) - { - Environment.SetEnvironmentVariable("ChocolateyEnvironmentVerbose", "true"); - } - if (!config.Features.CheckSumFiles) - { - Environment.SetEnvironmentVariable("ChocolateyIgnoreChecksums", "true"); - } + + if (config.Debug) Environment.SetEnvironmentVariable("ChocolateyEnvironmentDebug", "true"); + if (config.Verbose) Environment.SetEnvironmentVariable("ChocolateyEnvironmentVerbose", "true"); + if (!config.Features.CheckSumFiles) Environment.SetEnvironmentVariable("ChocolateyIgnoreChecksums", "true"); + if (!string.IsNullOrWhiteSpace(config.Proxy.Location)) { var proxyCreds = string.Empty; @@ -384,6 +407,15 @@ public static void set_environment_variables(ChocolateyConfiguration config) Environment.SetEnvironmentVariable("https_proxy", "{0}{1}".format_with(proxyCreds, config.Proxy.Location)); Environment.SetEnvironmentVariable("chocolateyProxyLocation", config.Proxy.Location); } + + if (config.Features.UsePowerShellHost) Environment.SetEnvironmentVariable("ChocolateyPowerShellHost", "true"); + if (config.Information.LicenseIsValid) Environment.SetEnvironmentVariable("ChocolateyLicenseValid", "true"); + if (config.Force) Environment.SetEnvironmentVariable("ChocolateyForce", "true"); + if (config.Features.VirusCheck) + { + Environment.SetEnvironmentVariable("ChocolateyVirusCheckFiles", "true"); + Environment.SetEnvironmentVariable("ChocolateyVirusCheckMinimumPositives", config.VirusCheckMinimumPositives.to_string()); + } } } } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyApiKeyCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyApiKeyCommand.cs index cc8fa00867..05f4ca7f03 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyApiKeyCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyApiKeyCommand.cs @@ -25,9 +25,9 @@ namespace chocolatey.infrastructure.app.commands using logging; using services; - [CommandFor(CommandNameType.setapikey)] - [CommandFor(CommandNameType.apikey)] - public sealed class ChocolateyApiKeyCommand : ICommand + [CommandFor("apikey", "retrieves or saves an apikey for a particular source")] + [CommandFor("setapikey", "retrieves or saves an apikey for a particular source (alias for apikey)")] + public class ChocolateyApiKeyCommand : ICommand { private readonly IChocolateyConfigSettingsService _configSettingsService; @@ -36,7 +36,7 @@ public ChocolateyApiKeyCommand(IChocolateyConfigSettingsService configSettingsSe _configSettingsService = configSettingsService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { configuration.Sources = null; @@ -50,12 +50,12 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati ; } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { if (!string.IsNullOrWhiteSpace(configuration.ApiKeyCommand.Key) && string.IsNullOrWhiteSpace(configuration.Sources)) { @@ -63,7 +63,7 @@ public void handle_validation(ChocolateyConfiguration configuration) } } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "ApiKey Command"); this.Log().Info(@" @@ -101,12 +101,12 @@ choco apikey -k -s {0} "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { _configSettingsService.noop(configuration); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { if (string.IsNullOrWhiteSpace(configuration.ApiKeyCommand.Key)) { @@ -128,7 +128,7 @@ public void run(ChocolateyConfiguration configuration) } } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return true; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyConfigCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyConfigCommand.cs index 0df8bbb141..c86869979b 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyConfigCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyConfigCommand.cs @@ -26,8 +26,8 @@ namespace chocolatey.infrastructure.app.commands using logging; using services; - [CommandFor(CommandNameType.config)] - public sealed class ChocolateyConfigCommand : ICommand + [CommandFor("config", "Retrieve and configure config file settings")] + public class ChocolateyConfigCommand : ICommand { private readonly IChocolateyConfigSettingsService _configSettingsService; @@ -36,7 +36,7 @@ public ChocolateyConfigCommand(IChocolateyConfigSettingsService configSettingsSe _configSettingsService = configSettingsService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { configuration.Sources = string.Empty; @@ -52,7 +52,7 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati ; } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); var command = ConfigCommandType.unknown; @@ -81,13 +81,13 @@ public void handle_additional_argument_parsing(IList unparsedArguments, } } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { if (configuration.ConfigCommand.Command != ConfigCommandType.list && string.IsNullOrWhiteSpace(configuration.ConfigCommand.Name)) throw new ApplicationException("When specifying the subcommand '{0}', you must also specify --name by option or position.".format_with(configuration.ConfigCommand.Command.to_string())); if (configuration.ConfigCommand.Command == ConfigCommandType.set && string.IsNullOrWhiteSpace(configuration.ConfigCommand.ConfigValue)) throw new ApplicationException("When specifying the subcommand '{0}', you must also specify --value by option or position.".format_with(configuration.ConfigCommand.Command.to_string())); } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Config Command"); this.Log().Info(@" @@ -114,12 +114,12 @@ choco config unset --name proxy "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { _configSettingsService.noop(configuration); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { switch (configuration.ConfigCommand.Command) { @@ -138,7 +138,7 @@ public void run(ChocolateyConfiguration configuration) } } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return true; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyFeatureCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyFeatureCommand.cs index d192de8371..ca640283e6 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyFeatureCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyFeatureCommand.cs @@ -26,9 +26,9 @@ namespace chocolatey.infrastructure.app.commands using logging; using services; - [CommandFor(CommandNameType.feature)] - [CommandFor(CommandNameType.features)] - public sealed class ChocolateyFeatureCommand : ICommand + [CommandFor("feature", "view and configure choco features")] + [CommandFor("features", "view and configure choco features (alias for feature)")] + public class ChocolateyFeatureCommand : ICommand { private readonly IChocolateyConfigSettingsService _configSettingsService; @@ -37,7 +37,7 @@ public ChocolateyFeatureCommand(IChocolateyConfigSettingsService configSettingsS _configSettingsService = configSettingsService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { configuration.Sources = string.Empty; @@ -48,7 +48,7 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati ; } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); @@ -69,7 +69,7 @@ public void handle_additional_argument_parsing(IList unparsedArguments, configuration.FeatureCommand.Command = command; } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { if (configuration.FeatureCommand.Command != FeatureCommandType.list && string.IsNullOrWhiteSpace(configuration.FeatureCommand.Name)) { @@ -77,7 +77,7 @@ public void handle_validation(ChocolateyConfiguration configuration) } } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Feature Command"); this.Log().Info(@" @@ -100,12 +100,12 @@ choco feature list "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { _configSettingsService.noop(configuration); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { switch (configuration.FeatureCommand.Command) { @@ -121,7 +121,7 @@ public void run(ChocolateyConfiguration configuration) } } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return true; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyInstallCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyInstallCommand.cs index e63eead688..5c7084b27e 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyInstallCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyInstallCommand.cs @@ -20,13 +20,12 @@ namespace chocolatey.infrastructure.app.commands using attributes; using commandline; using configuration; - using domain; using infrastructure.commands; using logging; using services; - [CommandFor(CommandNameType.install)] - public sealed class ChocolateyInstallCommand : ICommand + [CommandFor("install", "installs packages from various sources")] + public class ChocolateyInstallCommand : ICommand { private readonly IChocolateyPackageService _packageService; @@ -35,7 +34,7 @@ public ChocolateyInstallCommand(IChocolateyPackageService packageService) _packageService = packageService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("s=|source=", @@ -94,13 +93,13 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati //todo: Checksum / ChecksumType defaults to md5 / package name can be a url / installertype } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); configuration.PackageNames = string.Join(ApplicationParameters.PackageNamesSeparator.to_string(), unparsedArguments); } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { if (string.IsNullOrWhiteSpace(configuration.PackageNames)) { @@ -119,7 +118,7 @@ public void handle_validation(ChocolateyConfiguration configuration) } } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Install Command"); this.Log().Info(@" @@ -180,18 +179,18 @@ pass specific options. "); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { _packageService.install_noop(configuration); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { _packageService.ensure_source_app_installed(configuration); _packageService.install_run(configuration); } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return true; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs index 32cce2b02b..c290930bd4 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyListCommand.cs @@ -27,9 +27,9 @@ namespace chocolatey.infrastructure.app.commands using results; using services; - [CommandFor(CommandNameType.list)] - [CommandFor(CommandNameType.search)] - public sealed class ChocolateyListCommand : IListCommand + [CommandFor("list", "lists remote or local packages")] + [CommandFor("search", "searches remote or local packages (alias for list)")] + public class ChocolateyListCommand : IListCommand { private readonly IChocolateyPackageService _packageService; @@ -38,7 +38,7 @@ public ChocolateyListCommand(IChocolateyPackageService packageService) _packageService = packageService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("s=|source=", @@ -82,16 +82,16 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati //todo exact name } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "List/Search Command"); this.Log().Info(@" @@ -121,32 +121,32 @@ choco search git "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { _packageService.list_noop(configuration); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { _packageService.ensure_source_app_installed(configuration); // note: you must leave the .ToList() here or else the method won't be evaluated! _packageService.list_run(configuration).ToList(); } - public IEnumerable list(ChocolateyConfiguration configuration) + public virtual IEnumerable list(ChocolateyConfiguration configuration) { configuration.QuietOutput = true; // here it's up to the caller to enumerate the results return _packageService.list_run(configuration); } - public int count(ChocolateyConfiguration config) + public virtual int count(ChocolateyConfiguration config) { config.QuietOutput = true; return _packageService.count_run(config); } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return false; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyNewCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyNewCommand.cs index ab2b6006e7..d732c61baf 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyNewCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyNewCommand.cs @@ -21,14 +21,13 @@ namespace chocolatey.infrastructure.app.commands using attributes; using commandline; using configuration; - using domain; using infrastructure.commands; using logging; using services; using templates; - [CommandFor(CommandNameType.@new)] - public sealed class ChocolateyNewCommand : ICommand + [CommandFor("new", "generates files necessary for a chocolatey package from a template")] + public class ChocolateyNewCommand : ICommand { private readonly ITemplateService _templateService; @@ -37,7 +36,7 @@ public ChocolateyNewCommand(ITemplateService templateService) _templateService = templateService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("a|auto|automaticpackage", @@ -63,7 +62,7 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati //todo: more built-in templates } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); @@ -97,7 +96,7 @@ public void handle_additional_argument_parsing(IList unparsedArguments, } } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { if (string.IsNullOrWhiteSpace(configuration.NewCommand.Name)) { @@ -105,7 +104,7 @@ public void handle_validation(ChocolateyConfiguration configuration) } } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "New Command"); this.Log().Info(@" @@ -137,17 +136,17 @@ public void help_message(ChocolateyConfiguration configuration) "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { _templateService.noop(configuration); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { _templateService.generate(configuration); } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return false; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyOutdatedCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyOutdatedCommand.cs index 7a608c6959..67eb6271b0 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyOutdatedCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyOutdatedCommand.cs @@ -19,13 +19,12 @@ namespace chocolatey.infrastructure.app.commands using attributes; using commandline; using configuration; - using domain; using infrastructure.commands; using logging; using services; - [CommandFor(CommandNameType.outdated)] - public sealed class ChocolateyOutdatedCommand : ICommand + [CommandFor("outdated", "retrieves packages that are outdated. Similar to upgrade all --noop")] + public class ChocolateyOutdatedCommand : ICommand { private readonly IChocolateyPackageService _packageService; @@ -34,7 +33,7 @@ public ChocolateyOutdatedCommand(IChocolateyPackageService packageService) _packageService = packageService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("s=|source=", @@ -49,17 +48,17 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati ; } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); configuration.PackageNames = string.Join(ApplicationParameters.PackageNamesSeparator.to_string(), unparsedArguments); } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Outdated Command"); this.Log().Info(@" @@ -84,17 +83,17 @@ choco outdated "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { _packageService.outdated_noop(configuration); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { _packageService.outdated_run(configuration); } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return false; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyPackCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyPackCommand.cs index 3a76134a76..aa74e1660a 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyPackCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyPackCommand.cs @@ -19,13 +19,12 @@ namespace chocolatey.infrastructure.app.commands using attributes; using commandline; using configuration; - using domain; using infrastructure.commands; using logging; using services; - [CommandFor(CommandNameType.pack)] - public sealed class ChocolateyPackCommand : ICommand + [CommandFor("pack", "packages up a nuspec to a compiled nupkg")] + public class ChocolateyPackCommand : ICommand { private readonly IChocolateyPackageService _packageService; @@ -34,7 +33,7 @@ public ChocolateyPackCommand(IChocolateyPackageService packageService) _packageService = packageService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("version=", @@ -43,16 +42,16 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati ; } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Pack Command"); this.Log().Info(@" @@ -81,17 +80,17 @@ choco pack path/to/nuspec "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { _packageService.pack_noop(configuration); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { _packageService.pack_run(configuration); } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return false; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyPinCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyPinCommand.cs index 5bdfa34bac..c84a44e997 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyPinCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyPinCommand.cs @@ -28,8 +28,8 @@ namespace chocolatey.infrastructure.app.commands using nuget; using services; - [CommandFor(CommandNameType.pin)] - public sealed class ChocolateyPinCommand : ICommand + [CommandFor("pin", "suppress upgrades for a package")] + public class ChocolateyPinCommand : ICommand { private readonly IChocolateyPackageInformationService _packageInfoService; private readonly ILogger _nugetLogger; @@ -43,7 +43,7 @@ public ChocolateyPinCommand(IChocolateyPackageInformationService packageInfoServ _nugetService = nugetService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("n=|name=", @@ -55,7 +55,7 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati ; } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { // don't set configuration.Input or it will be passed to list @@ -81,7 +81,7 @@ public void handle_additional_argument_parsing(IList unparsedArguments, configuration.Prerelease = true; } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { if (configuration.PinCommand.Command != PinCommandType.list && string.IsNullOrWhiteSpace(configuration.PinCommand.Name)) { @@ -89,7 +89,7 @@ public void handle_validation(ChocolateyConfiguration configuration) } } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Pin Command"); this.Log().Info(@" @@ -114,12 +114,12 @@ choco pin remove --name git "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { this.Log().Info("Pin would have called {0} with other options:{1} Name={2}{1} Version={3}".format_with(configuration.PinCommand.Command.to_string(), Environment.NewLine, configuration.PinCommand.Name.to_string(), configuration.Version.to_string())); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { var packageManager = NugetCommon.GetPackageManager(configuration, _nugetLogger, installSuccessAction: null, @@ -137,7 +137,7 @@ public void run(ChocolateyConfiguration configuration) } } - public void list_pins(IPackageManager packageManager, ChocolateyConfiguration config) + public virtual void list_pins(IPackageManager packageManager, ChocolateyConfiguration config) { var input = config.Input; config.Input = string.Empty; @@ -157,7 +157,7 @@ public void list_pins(IPackageManager packageManager, ChocolateyConfiguration co } } - public void set_pin(IPackageManager packageManager, ChocolateyConfiguration config) + public virtual void set_pin(IPackageManager packageManager, ChocolateyConfiguration config) { var addingAPin = config.PinCommand.Command == PinCommandType.add; this.Log().Info("Trying to {0} a pin for {1}".format_with(config.PinCommand.Command.to_string(), config.PinCommand.Name)); @@ -196,7 +196,7 @@ public void set_pin(IPackageManager packageManager, ChocolateyConfiguration conf } } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return true; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyPushCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyPushCommand.cs index 5de65894f2..6b0b3a5078 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyPushCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyPushCommand.cs @@ -20,13 +20,12 @@ namespace chocolatey.infrastructure.app.commands using attributes; using commandline; using configuration; - using domain; using infrastructure.commands; using logging; using services; - [CommandFor(CommandNameType.push)] - public sealed class ChocolateyPushCommand : ICommand + [CommandFor("push", "pushes a compiled nupkg")] + public class ChocolateyPushCommand : ICommand { private readonly IChocolateyPackageService _packageService; private readonly IChocolateyConfigSettingsService _configSettingsService; @@ -37,7 +36,7 @@ public ChocolateyPushCommand(IChocolateyPackageService packageService, IChocolat _configSettingsService = configSettingsService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { configuration.Sources = null; configuration.PushCommand.TimeoutInSeconds = 300; @@ -67,7 +66,7 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati //todo: push command - allow disable buffering? } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); // path to .nupkg - assume relative @@ -87,7 +86,7 @@ public void handle_additional_argument_parsing(IList unparsedArguments, } } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { if (string.IsNullOrWhiteSpace(configuration.Sources)) { @@ -121,7 +120,7 @@ accessing an internal feed. If you are however doing this against an } } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Push Command"); this.Log().Info(@" @@ -168,17 +167,17 @@ You can verify by going to {0}packages/packageName. "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { _packageService.push_noop(configuration); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { _packageService.push_run(configuration); } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return false; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateySourceCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateySourceCommand.cs index c13331b055..152224eaaa 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateySourceCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateySourceCommand.cs @@ -26,9 +26,9 @@ namespace chocolatey.infrastructure.app.commands using logging; using services; - [CommandFor(CommandNameType.sources)] - [CommandFor(CommandNameType.source)] - public sealed class ChocolateySourceCommand : IListCommand + [CommandFor("source", "view and configure default sources")] + [CommandFor("sources", "view and configure default sources (alias for source)")] + public class ChocolateySourceCommand : IListCommand { private readonly IChocolateyConfigSettingsService _configSettingsService; @@ -37,7 +37,7 @@ public ChocolateySourceCommand(IChocolateyConfigSettingsService configSettingsSe _configSettingsService = configSettingsService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { configuration.Sources = string.Empty; @@ -60,7 +60,7 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati ; } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); @@ -81,7 +81,7 @@ public void handle_additional_argument_parsing(IList unparsedArguments, configuration.SourceCommand.Command = command; } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { if (configuration.SourceCommand.Command != SourceCommandType.list && string.IsNullOrWhiteSpace(configuration.SourceCommand.Name)) { @@ -89,7 +89,7 @@ public void handle_validation(ChocolateyConfiguration configuration) } } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Source Command"); this.Log().Info(@" @@ -116,12 +116,12 @@ choco source list "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { _configSettingsService.noop(configuration); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { switch (configuration.SourceCommand.Command) { @@ -143,17 +143,17 @@ public void run(ChocolateyConfiguration configuration) } } - public IEnumerable list(ChocolateyConfiguration configuration) + public virtual IEnumerable list(ChocolateyConfiguration configuration) { return _configSettingsService.source_list(configuration); } - public int count(ChocolateyConfiguration config) + public virtual int count(ChocolateyConfiguration config) { return list(config).Count(); } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return true; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyUninstallCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyUninstallCommand.cs index a9d545efbd..925d4618bf 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyUninstallCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyUninstallCommand.cs @@ -20,13 +20,12 @@ namespace chocolatey.infrastructure.app.commands using attributes; using commandline; using configuration; - using domain; using infrastructure.commands; using logging; using services; - [CommandFor(CommandNameType.uninstall)] - public sealed class ChocolateyUninstallCommand : ICommand + [CommandFor("uninstall", "uninstalls a package")] + public class ChocolateyUninstallCommand : ICommand { private readonly IChocolateyPackageService _packageService; @@ -35,7 +34,7 @@ public ChocolateyUninstallCommand(IChocolateyPackageService packageService) _packageService = packageService; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { optionSet .Add("s=|source=", @@ -68,14 +67,13 @@ public void configure_argument_parser(OptionSet optionSet, ChocolateyConfigurati ; } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { configuration.Input = string.Join(" ", unparsedArguments); configuration.PackageNames = string.Join(ApplicationParameters.PackageNamesSeparator.to_string(), unparsedArguments); } - - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { if (string.IsNullOrWhiteSpace(configuration.PackageNames)) { @@ -83,7 +81,7 @@ public void handle_validation(ChocolateyConfiguration configuration) } } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "Uninstall Command"); this.Log().Info(@" @@ -124,18 +122,18 @@ pass specific options. "); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { _packageService.uninstall_noop(configuration); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { _packageService.ensure_source_app_installed(configuration); _packageService.uninstall_run(configuration); } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return true; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyUnpackSelfCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyUnpackSelfCommand.cs index 5b7b9e7a23..9a2ea296d0 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyUnpackSelfCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyUnpackSelfCommand.cs @@ -22,15 +22,14 @@ namespace chocolatey.infrastructure.app.commands using attributes; using commandline; using configuration; - using domain; using extractors; using filesystem; using infrastructure.commands; using logging; using resources; - [CommandFor(CommandNameType.unpackself)] - public sealed class ChocolateyUnpackSelfCommand : ICommand + [CommandFor("unpackself", "have chocolatey set it self up")] + public class ChocolateyUnpackSelfCommand : ICommand { private readonly IFileSystem _fileSystem; private Lazy _assemblyInitializer = new Lazy(() => Assembly.GetAssembly(typeof (ChocolateyResourcesAssembly))); @@ -51,19 +50,19 @@ public ChocolateyUnpackSelfCommand(IFileSystem fileSystem) _fileSystem = fileSystem; } - public void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) + public virtual void configure_argument_parser(OptionSet optionSet, ChocolateyConfiguration configuration) { } - public void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) + public virtual void handle_additional_argument_parsing(IList unparsedArguments, ChocolateyConfiguration configuration) { } - public void handle_validation(ChocolateyConfiguration configuration) + public virtual void handle_validation(ChocolateyConfiguration configuration) { } - public void help_message(ChocolateyConfiguration configuration) + public virtual void help_message(ChocolateyConfiguration configuration) { this.Log().Info(ChocolateyLoggers.Important, "UnpackSelf Command"); this.Log().Info(@" @@ -78,12 +77,12 @@ during normal operation. "chocolatey".Log().Info(ChocolateyLoggers.Important, "Options and Switches"); } - public void noop(ChocolateyConfiguration configuration) + public virtual void noop(ChocolateyConfiguration configuration) { this.Log().Info("This would have unpacked {0} for use relative where the executable is, based on resources embedded in {0}.".format_with(ApplicationParameters.Name)); } - public void run(ChocolateyConfiguration configuration) + public virtual void run(ChocolateyConfiguration configuration) { this.Log().Info("{0} is unpacking required files for use. Overwriting? {1}".format_with(ApplicationParameters.Name, configuration.Force)); //refactor - thank goodness this is temporary, cuz manifest resource streams are dumb @@ -105,7 +104,7 @@ public void run(ChocolateyConfiguration configuration) logOutput: true); } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return true; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyUpdateCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyUpdateCommand.cs index ad9de73b2c..76cf93b2d0 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyUpdateCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyUpdateCommand.cs @@ -18,12 +18,11 @@ namespace chocolatey.infrastructure.app.commands using attributes; using commandline; using configuration; - using domain; using logging; using services; - [CommandFor(CommandNameType.update)] - public sealed class ChocolateyUpdateCommand : ChocolateyUpgradeCommand + [CommandFor("update", "[DEPRECATED] RESERVED for future use (you are looking for upgrade, these are not the droids you are looking for)")] + public class ChocolateyUpdateCommand : ChocolateyUpgradeCommand { //todo: v1 Deprecation - update is removed or becomes package indexes public ChocolateyUpdateCommand(IChocolateyPackageService packageService) : base(packageService) diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs index c3b1657adc..c0f722d14b 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyUpgradeCommand.cs @@ -20,12 +20,11 @@ namespace chocolatey.infrastructure.app.commands using attributes; using commandline; using configuration; - using domain; using infrastructure.commands; using logging; using services; - [CommandFor(CommandNameType.upgrade)] + [CommandFor("upgrade", "upgrades packages from various sources")] public class ChocolateyUpgradeCommand : ICommand { //todo v1 Deprecation reseal this class and remove virtuals @@ -165,7 +164,7 @@ public virtual void run(ChocolateyConfiguration configuration) _packageService.upgrade_run(configuration); } - public bool may_require_admin_access() + public virtual bool may_require_admin_access() { return true; } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyVersionCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyVersionCommand.cs index 1f9e04224a..ea80a357ba 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyVersionCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyVersionCommand.cs @@ -20,12 +20,11 @@ namespace chocolatey.infrastructure.app.commands using attributes; using commandline; using configuration; - using domain; using logging; using services; - [CommandFor(CommandNameType.version)] - public sealed class ChocolateyVersionCommand : ChocolateyUpgradeCommand + [CommandFor("version", "[DEPRECATED] will be removed in v1 - use `choco outdated` or `cup -whatif` instead")] + public class ChocolateyVersionCommand : ChocolateyUpgradeCommand { private readonly IChocolateyPackageService _packageService; diff --git a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs index c5ca158ba2..ecf773667f 100644 --- a/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs +++ b/src/chocolatey/infrastructure.app/configuration/ChocolateyConfiguration.cs @@ -20,6 +20,7 @@ namespace chocolatey.infrastructure.app.configuration using System.Reflection; using System.Text; using domain; + using licensing; using logging; using platforms; @@ -206,6 +207,9 @@ private void append_output(StringBuilder propertyValues, string append) public bool AllowDowngrade { get; set; } public bool ForceDependencies { get; set; } + //licensed versions only + public int VirusCheckMinimumPositives { get; set; } + /// /// Configuration values provided by choco. /// @@ -326,6 +330,11 @@ public sealed class InformationCommandConfiguration public bool IsInteractive { get; set; } public bool IsUserAdministrator { get; set; } public bool IsProcessElevated { get; set; } + public string LicenseType { get; set; } + public bool LicenseIsValid { get; set; } + public string LicenseVersion { get; set; } + public string LicenseUserName { get; set; } + public DateTime? LicenseExpirationDate { get; set; } } @@ -338,6 +347,7 @@ public sealed class FeaturesConfiguration public bool FailOnStandardError { get; set; } public bool UsePowerShellHost { get; set; } public bool LogEnvironmentValues { get; set; } + public bool VirusCheck { get; set; } } //todo: retrofit other command configs this way diff --git a/src/chocolatey/infrastructure.app/domain/CommandNameType.cs b/src/chocolatey/infrastructure.app/domain/CommandNameType.cs index 03fc056d07..439488ea85 100644 --- a/src/chocolatey/infrastructure.app/domain/CommandNameType.cs +++ b/src/chocolatey/infrastructure.app/domain/CommandNameType.cs @@ -15,35 +15,12 @@ namespace chocolatey.infrastructure.app.domain { - using System.ComponentModel; public enum CommandNameType { - [Description("list - lists remote or local packages")] list, - [Description("search - searches remote or local packages (alias for list)")] search, - [Description("install - installs packages from various sources")] install, - [Description("version - [DEPRECATED] will be removed in v1 - use `cup -whatif` instead")] version, - [Description("pin - suppress upgrades to a package")] pin, - //[Description("update - updates package index")] update, - [Description("update - [DEPRECATED] RESERVED for future use (you are looking for upgrade, these are not the droids you are looking for)")] update, - [Description("upgrade - upgrades packages from various sources")] upgrade, - [Description("outdated - retrieves packages that are outdated. Similar to upgrade all --noop")] outdated, - [Description("uninstall - uninstalls a package")] uninstall, - [Description("source - view and configure default sources")] source, - [Description("sources - view and configure default sources (alias for source)")] - sources, - [Description("feature - view and configure choco features")] feature, - [Description("features - view and configure choco features (alias for feature)")] - features, - // [Description("config - view and change configuration")] config, - [Description("unpackself - have chocolatey set it self up")] unpackself, - [Description("pack - packages up a nuspec to a compiled nupkg")] pack, - [Description("push - pushes a compiled nupkg")] push, - [Description("new - generates files necessary for a chocolatey package")] @new, - [Description("apikey - retrieves or saves an apikey for a particular source")] apikey, - [Description("setapikey - retrieves or saves an apikey for a particular source (alias for apikey)")] - setapikey, - [Description("config - Retrieve and configure config file settings")] - config, + list, + install, + upgrade, + uninstall, } } \ No newline at end of file diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs index b69cba6590..19ed1d4b23 100644 --- a/src/chocolatey/infrastructure.app/services/NugetService.cs +++ b/src/chocolatey/infrastructure.app/services/NugetService.cs @@ -321,6 +321,7 @@ public ConcurrentDictionary install_run(ChocolateyConfigu //todo: handle all SemanticVersion version = config.Version != null ? new SemanticVersion(config.Version) : null; + if (config.Force) config.AllowDowngrade = true; IList packageNames = config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).or_empty_list_if_null().ToList(); if (packageNames.Count == 1) @@ -398,7 +399,7 @@ public ConcurrentDictionary install_run(ChocolateyConfigu if (installedPackage != null && version != null && version < installedPackage.Version && !config.AllowMultipleVersions && !config.AllowDowngrade) { - string logMessage = "A newer version of {0} (v{1}) is already installed.{2} Use --allow-downgrade to attempt to install older versions, or use side by side to allow multiple versions.".format_with(installedPackage.Id, installedPackage.Version, Environment.NewLine); + string logMessage = "A newer version of {0} (v{1}) is already installed.{2} Use --allow-downgrade or --force to attempt to install older versions, or use side by side to allow multiple versions.".format_with(installedPackage.Id, installedPackage.Version, Environment.NewLine); var nullResult = packageInstalls.GetOrAdd(packageName, new PackageResult(installedPackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id))); nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); @@ -417,7 +418,7 @@ public ConcurrentDictionary install_run(ChocolateyConfigu if (installedPackage != null && (installedPackage.Version == availablePackage.Version) && config.Force) { - var forcedResult = packageInstalls.GetOrAdd(packageName, new PackageResult(installedPackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id))); + var forcedResult = packageInstalls.GetOrAdd(packageName, new PackageResult(availablePackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, availablePackage.Id))); forcedResult.Messages.Add(new ResultMessage(ResultType.Note, "Backing up and removing old version")); backup_existing_version(config, installedPackage, _packageInfoService.get_package_information(installedPackage)); @@ -429,6 +430,7 @@ public ConcurrentDictionary install_run(ChocolateyConfigu { _fileSystem.delete_directory_if_exists(forcedResult.InstallLocation, recursive: true); } + remove_cache_for_package(config, installedPackage); } catch (Exception ex) { @@ -447,6 +449,7 @@ public ConcurrentDictionary install_run(ChocolateyConfigu { packageManager.InstallPackage(availablePackage, ignoreDependencies: config.IgnoreDependencies, allowPrereleaseVersions: config.Prerelease); //packageManager.InstallPackage(packageName, version, configuration.IgnoreDependencies, configuration.Prerelease); + remove_nuget_cache_for_package(availablePackage); } } catch (Exception ex) @@ -503,6 +506,8 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu var packageInstalls = new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase); SemanticVersion version = config.Version != null ? new SemanticVersion(config.Version) : null; + if (config.Force) config.AllowDowngrade = true; + var packageManager = NugetCommon.GetPackageManager( config, _nugetLogger, @@ -565,7 +570,7 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu if (version != null && version < installedPackage.Version && !config.AllowMultipleVersions && !config.AllowDowngrade) { - string logMessage = "A newer version of {0} (v{1}) is already installed.{2} Use --allow-downgrade to attempt to upgrade to older versions, or use side by side to allow multiple versions.".format_with(installedPackage.Id, installedPackage.Version, Environment.NewLine); + string logMessage = "A newer version of {0} (v{1}) is already installed.{2} Use --allow-downgrade or --force to attempt to upgrade to older versions, or use side by side to allow multiple versions.".format_with(installedPackage.Id, installedPackage.Version, Environment.NewLine); var nullResult = packageInstalls.GetOrAdd(packageName, new PackageResult(installedPackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id))); nullResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage)); this.Log().Error(ChocolateyLoggers.Important, logMessage); @@ -705,7 +710,11 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu if (config.Force && (installedPackage.Version == availablePackage.Version)) { FaultTolerance.try_catch_with_logging_exception( - () => _fileSystem.delete_directory_if_exists(_fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id), recursive: true), + () => + { + _fileSystem.delete_directory_if_exists(_fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id), recursive: true); + remove_cache_for_package(config, installedPackage); + }, "Error during force upgrade"); packageManager.InstallPackage(availablePackage, config.IgnoreDependencies, config.Prerelease); } @@ -713,6 +722,7 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu { packageManager.UpdatePackage(availablePackage, updateDependencies: !config.IgnoreDependencies, allowPrereleaseVersions: config.Prerelease); } + remove_nuget_cache_for_package(availablePackage); } } catch (Exception ex) @@ -894,6 +904,34 @@ private void remove_shim_directors(ChocolateyConfiguration config, IPackage inst } } + private void remove_cache_for_package( ChocolateyConfiguration config, IPackage installedPackage) + { + var cacheDirectory = _fileSystem.combine_paths(config.CacheLocation, installedPackage.Id, installedPackage.Version.to_string()); + + FaultTolerance.try_catch_with_logging_exception( + () => _fileSystem.delete_directory_if_exists(cacheDirectory, recursive: true), + "Unable to removed cached files"); + } + + /// + /// Remove NuGet cache of the package. + /// Whether we use the cached file or not, NuGet always caches the package. + /// This is annoying with choco, but if you use both choco and NuGet, it can + /// cause hard to detect issues in NuGet when there is a NuGet package of the + /// same name with different contents. + /// + /// The installed package. + private void remove_nuget_cache_for_package(IPackage installedPackage) + { + var nugetCachedFile = _fileSystem.combine_paths(Environment.GetEnvironmentVariable("LocalAppData"), "NuGet", "Cache", "{0}.{1}.nupkg".format_with(installedPackage.Id, installedPackage.Version.to_string())); + if (_fileSystem.file_exists(nugetCachedFile)) + { + FaultTolerance.try_catch_with_logging_exception( + () => _fileSystem.delete_file(nugetCachedFile), + "Unable to removed cached NuGet package file"); + } + } + public void uninstall_noop(ChocolateyConfiguration config, Action continueAction) { var results = uninstall_run(config, continueAction, performAction: false); @@ -1063,6 +1101,7 @@ public ConcurrentDictionary uninstall_run(ChocolateyConfi packageManager.UninstallPackage(packageVersion, forceRemove: config.Force, removeDependencies: config.ForceDependencies); ensure_nupkg_is_removed(packageVersion, pkgInfo); remove_installation_files(packageVersion, pkgInfo); + remove_cache_for_package(config, packageVersion); } } catch (Exception ex) diff --git a/src/chocolatey/infrastructure.app/templates/NuspecTemplate.cs b/src/chocolatey/infrastructure.app/templates/NuspecTemplate.cs index 9dea87cf24..01364e078e 100644 --- a/src/chocolatey/infrastructure.app/templates/NuspecTemplate.cs +++ b/src/chocolatey/infrastructure.app/templates/NuspecTemplate.cs @@ -67,8 +67,8 @@ public class NuspecTemplate - __REPLACE__ [[PackageNameLower]] admin SPACE_SEPARATED + __REPLACE__ __REPLACE__MarkDown_Okay [[AutomaticPackageNotesNuspec]] diff --git a/src/chocolatey/infrastructure/adapters/Assembly.cs b/src/chocolatey/infrastructure/adapters/Assembly.cs index e69d3ea4fb..8f91a70f17 100644 --- a/src/chocolatey/infrastructure/adapters/Assembly.cs +++ b/src/chocolatey/infrastructure/adapters/Assembly.cs @@ -67,15 +67,36 @@ public Stream GetManifestResourceStream(Type type, string name) return _assembly.GetManifestResourceStream(type, name); } + public AssemblyName GetName() + { + return _assembly.GetName(); + } + + public Type GetType(String name) + { + return _assembly.GetType(name); + } + + public Type GetType(String name, bool throwOnError) + { + return _assembly.GetType(name,throwOnError); + } + + public Type GetType(String name, bool throwOnError, bool ignoreCase) + { + return _assembly.GetType(name,throwOnError, ignoreCase); + } + + public static IAssembly LoadFile(string path) + { + return new Assembly(System.Reflection.Assembly.LoadFile(path)); + } + public static IAssembly GetAssembly(Type type) { return new Assembly(System.Reflection.Assembly.GetAssembly(type)); //return System.Reflection.Assembly.GetAssembly(type); } - public AssemblyName GetName() - { - return _assembly.GetName(); - } public static IAssembly GetExecutingAssembly() { diff --git a/src/chocolatey/infrastructure/adapters/IAssembly.cs b/src/chocolatey/infrastructure/adapters/IAssembly.cs index 35a857726f..fb91bc25f7 100644 --- a/src/chocolatey/infrastructure/adapters/IAssembly.cs +++ b/src/chocolatey/infrastructure/adapters/IAssembly.cs @@ -79,6 +79,12 @@ public interface IAssembly AssemblyName GetName(); + Type GetType(String name); + + Type GetType(String name, bool throwOnError); + + Type GetType(String name, bool throwOnError, bool ignoreCase); + /// /// Loads the specified manifest resource from this assembly. /// diff --git a/src/chocolatey/infrastructure/information/VersionInformation.cs b/src/chocolatey/infrastructure/information/VersionInformation.cs index b846713390..81f5e78686 100644 --- a/src/chocolatey/infrastructure/information/VersionInformation.cs +++ b/src/chocolatey/infrastructure/information/VersionInformation.cs @@ -20,11 +20,11 @@ namespace chocolatey.infrastructure.information public sealed class VersionInformation { - public static string get_current_assembly_version() + public static string get_current_assembly_version(IAssembly assembly = null) { string version = null; - var executingAssembly = Assembly.GetExecutingAssembly(); - string location = executingAssembly != null ? executingAssembly.Location : string.Empty; + if (assembly == null) assembly = Assembly.GetExecutingAssembly(); + string location = assembly != null ? assembly.Location : string.Empty; if (!string.IsNullOrEmpty(location)) { @@ -34,11 +34,11 @@ public static string get_current_assembly_version() return version; } - public static string get_current_informational_version() + public static string get_current_informational_version(IAssembly assembly = null) { string version = null; - var executingAssembly = Assembly.GetExecutingAssembly(); - string location = executingAssembly != null ? executingAssembly.Location : string.Empty; + if (assembly == null) assembly = Assembly.GetExecutingAssembly(); + string location = assembly != null ? assembly.Location : string.Empty; if (!string.IsNullOrEmpty(location)) { diff --git a/src/chocolatey/infrastructure/licensing/ChocolateyLicense.cs b/src/chocolatey/infrastructure/licensing/ChocolateyLicense.cs new file mode 100644 index 0000000000..97b82c50c1 --- /dev/null +++ b/src/chocolatey/infrastructure/licensing/ChocolateyLicense.cs @@ -0,0 +1,39 @@ +// 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; + + public sealed class ChocolateyLicense + { + public string Name { get; set; } + public ChocolateyLicenseType LicenseType { get; set; } + public bool IsValid { get; set; } + public bool AssemblyLoaded { get; set; } + //todo: get version + public string Version { get; set; } + public string InvalidReason { get; set; } + public DateTime? ExpirationDate { get; set; } + + public bool is_licensed_version() + { + return IsValid + && LicenseType != ChocolateyLicenseType.Unknown + && LicenseType != ChocolateyLicenseType.Foss + ; + } + } +} diff --git a/src/chocolatey/infrastructure/licensing/ChocolateyLicenseType.cs b/src/chocolatey/infrastructure/licensing/ChocolateyLicenseType.cs new file mode 100644 index 0000000000..442736de6d --- /dev/null +++ b/src/chocolatey/infrastructure/licensing/ChocolateyLicenseType.cs @@ -0,0 +1,26 @@ +// 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 +{ + public enum ChocolateyLicenseType + { + Unknown, + Foss, + Professional, + Business, + Enterprise, + } +} diff --git a/src/chocolatey/infrastructure/licensing/LicenseValidation.cs b/src/chocolatey/infrastructure/licensing/LicenseValidation.cs index c03e3a960a..0a012b9485 100644 --- a/src/chocolatey/infrastructure/licensing/LicenseValidation.cs +++ b/src/chocolatey/infrastructure/licensing/LicenseValidation.cs @@ -15,26 +15,68 @@ namespace chocolatey.infrastructure.licensing { - using Rhino.Licensing; + using System; + using System.IO; using app; - using filesystem; + using Rhino.Licensing; public sealed class LicenseValidation { - private const string PUBLIC_KEY = @""; + private const string PUBLIC_KEY = + @"rznyhs3OslLqL7A7qav9bSHYGQmgWVsP/L47dWU7yF3EHsiYZuJNLlq8tQkPql/LB1FfLihiGsOKKUF1tmxihcRUrDaYkK1IYY3A+uJWkBglDUOUjnoDboI1FgF3wmXSb07JC8JCVYWjchq+h6MV9aDZaigA5MqMKNj9FE14f68=AQAB"; - public static void validate(IFileSystem fileSystem) + public static ChocolateyLicense validate() { - string licenseFile = ApplicationParameters.LicenseFileLocation; + var chocolateyLicense = new ChocolateyLicense + { + LicenseType = ChocolateyLicenseType.Unknown + }; - if (fileSystem.file_exists(licenseFile)) + string licenseFile = ApplicationParameters.LicenseFileLocation; + //no file system at this point + if (File.Exists(licenseFile)) { - new LicenseValidator(PUBLIC_KEY, licenseFile).AssertValidLicense(); + var license = new LicenseValidator(PUBLIC_KEY, licenseFile); + + try + { + license.AssertValidLicense(); + chocolateyLicense.IsValid = true; + } + catch (Exception e) + { + //license may be invalid + chocolateyLicense.IsValid = false; + chocolateyLicense.InvalidReason = e.Message; + "chocolatey".Log().Error("A license was found for a licensed version of Chocolatey, but is invalid:{0} {1}".format_with(Environment.NewLine, e.Message)); + } + + switch (license.LicenseType) + { + case LicenseType.Professional : + chocolateyLicense.LicenseType = ChocolateyLicenseType.Professional; + break; + case LicenseType.Business : + chocolateyLicense.LicenseType = ChocolateyLicenseType.Business; + break; + case LicenseType.Enterprise : + chocolateyLicense.LicenseType = ChocolateyLicenseType.Enterprise; + break; + } + + chocolateyLicense.ExpirationDate = license.ExpirationDate; + chocolateyLicense.Name = license.Name; + + //todo: if it is expired, provide a warning. + // one month after it should stop working } else { //free version + chocolateyLicense.LicenseType = ChocolateyLicenseType.Foss; } + + return chocolateyLicense; } } -} \ No newline at end of file +} diff --git a/src/chocolatey/infrastructure/registration/SimpleInjectorContainer.cs b/src/chocolatey/infrastructure/registration/SimpleInjectorContainer.cs index 8e8955117b..08cc805a85 100644 --- a/src/chocolatey/infrastructure/registration/SimpleInjectorContainer.cs +++ b/src/chocolatey/infrastructure/registration/SimpleInjectorContainer.cs @@ -16,8 +16,11 @@ namespace chocolatey.infrastructure.registration { using System; - using SimpleInjector; + using System.Collections.Generic; + using System.Reflection; using app.registration; + using logging; + using SimpleInjector; /// /// The inversion container @@ -25,15 +28,25 @@ namespace chocolatey.infrastructure.registration public static class SimpleInjectorContainer { private static readonly Lazy _container = new Lazy(initialize); + private static readonly IList _componentRegistries = new List(); + private const string REGISTER_COMPONENTS_METHOD = "RegisterComponents"; /// - /// Gets the container. + /// Add a component registry class to the container. + /// Must have `public void RegisterComponents(Container container)` + /// and a parameterless constructor. /// - public static Container Container + /// Type of the component. + public static void add_component_registry_class(Type componentType) { - get { return _container.Value; } + _componentRegistries.Add(componentType); } + /// + /// Gets the container. + /// + public static Container Container { get { return _container.Value; } } + /// /// Initializes the container /// @@ -47,11 +60,54 @@ private static Container initialize() var binding = new ContainerBinding(); binding.RegisterComponents(container); + foreach (var componentRegistry in _componentRegistries) + { + load_component_registry(componentRegistry, container); + } + #if DEBUG container.Verify(); #endif return container; } + + /// + /// Loads a component registry for simple injector. + /// + /// The component registry. + /// The container. + private static void load_component_registry(Type componentRegistry, Container container) + { + if (componentRegistry == null) + { + "chocolatey".Log().Error( + @"Type expected for registering components was null. Unable to provide + name due to it being null."); + return; + } + try + { + object componentClass = Activator.CreateInstance(componentRegistry); + + componentRegistry.InvokeMember( + REGISTER_COMPONENTS_METHOD, + BindingFlags.InvokeMethod, + null, + componentClass, + new Object[] { container } + ); + } + catch (Exception ex) + { + "chocolatey".Log().Error( + ChocolateyLoggers.Important, + @"Error when registering components for '{0}':{1} {2}".format_with( + componentRegistry.FullName, + Environment.NewLine, + ex.Message + )); + } + } } -} \ No newline at end of file +}