├── .github └── workflows │ └── CI.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE.txt ├── README.md ├── build.ps1 ├── src ├── Foil.ps1 └── Foil.psd1 └── test ├── Foil.chocoV1.tests.ps1 └── Foil.chocoV2.tests.ps1 /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | on: 6 | push: 7 | branches: [ master ] 8 | pull_request: 9 | branches: [ master ] 10 | release: 11 | types: [ published ] 12 | 13 | jobs: 14 | Build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout Repository 18 | uses: actions/checkout@v3 19 | - name: Setup PowerShell module cache 20 | uses: actions/cache@v3 21 | id: cacher 22 | with: 23 | path: "~/.local/share/powershell/Modules" 24 | key: crescendo-1.1-preview-cache 25 | - name: Install Crescendo 26 | if: steps.cacher.outputs.cache-hit != 'true' 27 | shell: pwsh 28 | run: Install-Module Microsoft.PowerShell.Crescendo -AllowPrerelease -RequiredVersion 1.1.0-Preview01 -Force 29 | - name: Build the module with Crescendo 30 | shell: pwsh 31 | run: ./build.ps1 32 | - name: Bundle up module 33 | uses: actions/upload-artifact@v3 34 | with: 35 | name: module 36 | path: ./src/ 37 | Test: 38 | needs: Build 39 | runs-on: windows-latest 40 | steps: 41 | - name: Checkout Repository 42 | uses: actions/checkout@v3 43 | - name: Download module 44 | uses: actions/download-artifact@v3 45 | with: 46 | name: module 47 | path: C:\Users\runneradmin\Documents\PowerShell\Modules\Foil\ 48 | - name: Test with Pester 49 | run: | 50 | Invoke-Pester -Configuration (New-PesterConfiguration -Hashtable @{ 51 | Run = @{ 52 | Exit = $true 53 | } 54 | Output = @{ 55 | Verbosity = 'Detailed' 56 | } 57 | }) 58 | - name: Upload Chocolatey logs 59 | if: always() 60 | uses: actions/upload-artifact@v3 61 | with: 62 | name: choco-logs 63 | path: C:\ProgramData\chocolatey\logs\ 64 | Publish: 65 | needs: Test 66 | if: github.event_name == 'release' && github.event.action == 'published' 67 | runs-on: ubuntu-latest 68 | steps: 69 | - name: Download module 70 | uses: actions/download-artifact@v3 71 | with: 72 | name: module 73 | path: '~/.local/share/powershell/Modules/Foil' 74 | - name: Publish Module 75 | env: 76 | NUGET_KEY: ${{ secrets.NUGET_KEY }} 77 | shell: pwsh 78 | run: Write-Output "Publishing..."; Publish-Module -Name Foil -NuGetApiKey $env:NUGET_KEY -Exclude @('foil.ps1') -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | src/Foil.psm1 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [0.3.1] - 2023-11-17 8 | #### Added 9 | * Optional `-User` and `-Password` parameters to `Register-ChocoSource` 10 | 11 | ## [0.3.0] - 2023-01-21 12 | #### Added 13 | * Futureproofing support for Chocolatey v2.0.0 and higher 14 | * Ability to search remote packages with `Find-ChocoPackage` via `choco search` 15 | #### Changed 16 | * Migrated `Get-ChocoPackage` from using `choco search` to `choco list` to distinguish their changed meaning in Chocolatey v2.0.0 and higher 17 | * Upgraded to PowerShell Crescendo 1.1 Preview 1 for compiling the module 18 | * No functional changes are expected with this upgrade 19 | #### Deprecated 20 | * The `-LocalOnly` switch for `Get-ChocoPackage` becomes deprecated when used with Chocolatey v2.0.0, due to it becoming redundant with a change to `choco list` (see chocolatey/choco#158) 21 | * The use of `Get-ChocoPackage` for package search operations (and it's `-Source` parameter) becomes **immediately** deprecated, as `Get-ChocoPackage` only looks at installed packages beginning with Chocolatey v2.0.0 and higher 22 | * **Package search operations must be migrated to `Find-ChocoPackage` prior to the release of Chocolatey v2.0.0** 23 | 24 | ## [0.2.1] - 2023-01-21 25 | #### Fixed 26 | * No longer emits 'Environment' packages of version 'var' when installing a package that updates environment variables 27 | 28 | ## [0.2.0] - 2022-09-28 29 | #### Added 30 | * Support for finding and installing prelease packages 31 | 32 | ## [0.1.0] - 2021-09-24 33 | #### Changed 34 | * Including dependent packages during package uninstalling must now be explicitly requested 35 | 36 | ## [0.0.8] - 2021-09-24 37 | #### Added 38 | * Support for empty package parameters and install arguments 39 | 40 | ## [0.0.7] - 2021-07-11 41 | #### Added 42 | * Specific Cmdlet descriptions in Get-Help documentation 43 | 44 | ## [0.0.6] - 2021-07-04 45 | #### Fixed 46 | * Package failure regex that only captured install failures now captures uninstalls failures as well 47 | 48 | ## [0.0.5] - 2021-06-16 49 | #### Changed 50 | * Switched CI/CD from AppVeyor to GitHub Actions 51 | 52 | ## [0.0.4] - 2021-06-16 53 | #### Fixed 54 | * False positives in error handling during package installation for packages that emitted output including the string 'fail' 55 | 56 | ## [0.0.3] - 2021-03-28 57 | #### Changed 58 | * To mirror broader PowerShell Crescendo support, restrict module to run at a minimum of PowerShell 5.1 59 | * https://devblogs.microsoft.com/powershell/native-commands-in-powershell-a-new-approach/ 60 | 61 | ## [0.0.2] - 2021-03-27 62 | #### Fixed 63 | * Cmdlets can now properly chain in a pipeline 64 | 65 | ## [0.0.1] - 2021-03-27 66 | Initial release 67 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021-2023 Ethan Bergstrom 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CI](https://github.com/ethanbergstrom/Foil/actions/workflows/CI.yml/badge.svg)](https://github.com/ethanbergstrom/Foil/actions/workflows/CI.yml) 2 | 3 | # Foil 4 | Foil is a PowerShell Crescendo wrapper for Chocolatey 5 | 6 | ## Install Foil 7 | ```PowerShell 8 | Install-Module Foil -Force 9 | ``` 10 | 11 | ## Sample usages 12 | ### Search for a package 13 | ```PowerShell 14 | Find-ChocoPackage -Name nodejs 15 | 16 | Find-ChocoPackage -Name firefox -Exact 17 | ``` 18 | 19 | ### Install a package 20 | ```PowerShell 21 | Find-ChocoPackage nodejs -Exact -Verbose | Install-ChocoPackage 22 | 23 | Install-ChocoPackage -Name 7zip -Verbose 24 | ``` 25 | ### Get list of installed packages 26 | ```PowerShell 27 | Get-ChocoPackage nodejs -LocalOnly -Verbose 28 | ``` 29 | ### Uninstall a package 30 | ```PowerShell 31 | Get-ChocoPackage keepass-plugin-winhello -LocalOnly -Verbose | Uninstall-ChocoPackage -Verbose -RemoveDependencies 32 | ``` 33 | 34 | ### Manage package sources 35 | ```PowerShell 36 | Register-ChocoSource privateRepo -Location 'https://somewhere/out/there/api/v2/' 37 | Get-ChocoPackage nodejs -Verbose -Source privateRepo -Exact | Install-ChocoPackage 38 | Unregister-ChocoSource privateRepo 39 | ``` 40 | 41 | Foil integrates with Choco.exe to manage and store source information 42 | 43 | ## Pass in package parameters 44 | The Install-ChocoPackage cmdlet allows passing package parameters. 45 | 46 | ```powershell 47 | Install-ChocoPackage sysinternals -AcceptLicense -ParamsGlobal -Params '/InstallDir:c:\windows\temp\sysinternals /QuickLaunchShortcut:false' -Verbose 48 | ``` 49 | 50 | ## Known Issues 51 | ### Compatibility 52 | Foil works with PowerShell for both FullCLR/'Desktop' (ex 5.1) and CoreCLR (ex: 7.0.1), though Chocolatey itself still requires FullCLR. 53 | 54 | The `-LocalOnly` switch for `Get-ChocoPackage` becomes deprecated when used with Chocolatey v2.0.0, due to it becoming redundant with a change to `choco list` (see chocolatey/choco#158). 55 | 56 | The use of `Get-ChocoPackage` for package search operations (and it's `-Source` parameter) is deprecated, as `Get-ChocoPackage` only looks at installed packages beginning with Chocolatey v2.0.0 and higher. **Users must upgrade to Foil v0.3.0 or higher and migrate package search operations to `Find-ChocoPackage` prior to the release of Chocolatey v2.0.0 to ensure continued compatibility.** 57 | 58 | ## Legal and Licensing 59 | Foil is licensed under the [MIT license](./LICENSE.txt). 60 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | . (Join-Path -Path src -ChildPath Foil.ps1 -Resolve) 2 | 3 | $commandArray = @() 4 | 5 | $commands | ForEach-Object { 6 | $Noun = $_.Noun 7 | # Inherit noun-level attributes (if they exist) for all commands 8 | # If no noun-level original command elements or parameters exist, return an empty array for easy merging later 9 | $NounOriginalCommandElements = $_.OriginalCommandElements ?? @() 10 | $NounParameters = $_.Parameters ?? @() 11 | # Output handlers work differently - they will supercede each other, instead of being merged. 12 | $NounOutputHandlers = $_.OutputHandlers 13 | $_.Verbs | ForEach-Object { 14 | # Same logic as nouns - prepare verb-level original command elements and parameters for merging, but not output handlers 15 | $VerbOriginalCommandElements = $_.OriginalCommandElements ?? @() 16 | $VerbParameters = $_.Parameters ?? @() 17 | $VerbOutputHandlers = $_.OutputHandlers 18 | $Description = $_.Description 19 | $tempJson = New-TemporaryFile 20 | $commandArray += $(New-CrescendoCommand -Verb $_.Verb -Noun $Noun -OriginalName $BaseOriginalName | ForEach-Object { 21 | # Marge command elements in order of noun-level first, then verb-level, then generic 22 | $_.OriginalCommandElements = ($NounOriginalCommandElements + $VerbOriginalCommandElements + $BaseOriginalCommandElements) 23 | $_.Description = $Description 24 | # Merge parameters in order of noun-level, then verb-level, then generic 25 | $_.Parameters = ($NounParameters + $VerbParameters + $BaseParameters) 26 | # Prefer verb-level handlers first, then noun-level, then generic 27 | $_.OutputHandlers = ($VerbOutputHandlers ?? $NounOutputHandlers) ?? $BaseOutputHandlers 28 | $_ 29 | }) 30 | } 31 | } 32 | 33 | $tempJson = (New-TemporaryFile).FullName 34 | Export-CrescendoCommand -command $commandArray -fileName $tempJson -Force 35 | Export-CrescendoModule -NoClobberManifest -ConfigurationFile $tempJson -ModuleName (Join-Path -Path src -ChildPath Foil.psm1) -Force 36 | -------------------------------------------------------------------------------- /src/Foil.ps1: -------------------------------------------------------------------------------- 1 | $BaseOriginalName = 'choco' 2 | 3 | $BaseOriginalCommandElements = @( 4 | '--limit-output', 5 | '--yes' 6 | ) 7 | 8 | $BaseParameters = @() 9 | 10 | $BaseOutputHandlers = @{ 11 | ParameterSetName = 'Default' 12 | Handler = { 13 | param ( $output ) 14 | } 15 | } 16 | # The general structure of this hashtable is to define noun-level attributes, which are -probably- common across all commands for the same noun, but still allow for customization at more specific verb-level defition for that noun. 17 | # The following three command attributes have the following order of precedence: 18 | # OriginalCommandElements will be MERGED in the order of Noun + Verb + Base 19 | # Example: Noun ChocoSource's element 'source', Verb Register's element 'add', and Base elements are merged to become 'choco source add --limit-output --yes' 20 | # Parameters will be MERGED in the order of Noun + Verb + Base 21 | # Example: Noun ChocoPackage's parameters for package name and version and Verb Install's parameter specifying source information are merged to become ' --version= --source='. 22 | # These are then appended to the merged original command elements, to create 'choco install --version= --source= --limit-output --yes' 23 | # OutputHandler sets will SUPERCEDE each other in the order of: Verb -beats-> Noun -beats-> Base. This allows reusability of PowerShell parsing code. 24 | # Example: Noun ChocoPackage has inline output handler PowerShell code with complex regex that works for both Install-ChocoPackage and Uninstall-ChocoPackage, but Get-ChocoPackage's native output uses simple vertical bar delimiters. 25 | # Example 2: The native commands for Register-ChocoSource and Unregister-ChocoSource don't return any output, and until Crescendo supports error handling by exit codes, a base required default output handler that doesn't do anything can be defined and reused in multiple places. 26 | $Commands = @( 27 | @{ 28 | Noun = 'ChocoSource' 29 | OriginalCommandElements = @('source') 30 | Verbs = @( 31 | @{ 32 | Verb = 'Get' 33 | Description = 'Return Chocolatey package sources' 34 | OutputHandlers = @{ 35 | ParameterSetName = 'Default' 36 | Handler = { 37 | param ($output) 38 | if ($output) { 39 | $output | ForEach-Object { 40 | $sourceData = $_ -split '\|' 41 | [pscustomobject]@{ 42 | Name = $sourceData[0] 43 | Location = $sourceData[1] 44 | Disabled = $sourceData[2] 45 | UserName = $sourceData[3] 46 | Certificate = $sourceData[4] 47 | Priority = $sourceData[5] 48 | 'Bypass Proxy' = $sourceData[6] 49 | 'Allow Self Service' = $sourceData[7] 50 | 'Visibile to Admins Only' = $sourceData[8] 51 | } 52 | } 53 | } 54 | } 55 | } 56 | }, 57 | @{ 58 | Verb = 'Register' 59 | Description = 'Register a new Chocolatey package source' 60 | OriginalCommandElements = @('add') 61 | Parameters = @( 62 | @{ 63 | Name = 'Name' 64 | ParameterType = 'string' 65 | Description = 'Source Name' 66 | OriginalName = '--name=' 67 | NoGap = $true 68 | Mandatory = $true 69 | }, 70 | @{ 71 | Name = 'Location' 72 | OriginalName = '--source=' 73 | NoGap = $true 74 | ParameterType = 'string' 75 | Description = 'Source Location' 76 | Mandatory = $true 77 | }, 78 | @{ 79 | Name = 'User' 80 | OriginalName = '--user=' 81 | NoGap = $true 82 | ParameterType = 'string' 83 | Description = 'User Name' 84 | Mandatory = $false 85 | }, 86 | @{ 87 | Name = 'Password' 88 | OriginalName = '--password=' 89 | NoGap = $true 90 | ParameterType = 'string' 91 | Description = 'User Password' 92 | Mandatory = $false 93 | } 94 | ) 95 | }, 96 | @{ 97 | Verb = 'Unregister' 98 | Description = 'Unregister an existing Chocolatey package source' 99 | OriginalCommandElements = @('remove') 100 | Parameters = @( 101 | @{ 102 | Name = 'Name' 103 | ParameterType = 'string' 104 | Description = 'Source Name' 105 | OriginalName = '--name=' 106 | NoGap = $true 107 | Mandatory = $true 108 | ValueFromPipelineByPropertyName = $true 109 | } 110 | ) 111 | } 112 | ) 113 | }, 114 | @{ 115 | Noun = 'ChocoPackage' 116 | Parameters = @( 117 | @{ 118 | Name = 'Name' 119 | ParameterType = 'string' 120 | Description = 'Package Name' 121 | ValueFromPipelineByPropertyName = $true 122 | }, 123 | @{ 124 | Name = 'Version' 125 | OriginalName = '--version=' 126 | ParameterType = 'string' 127 | Description = 'Package version' 128 | NoGap = $true 129 | ValueFromPipelineByPropertyName = $true 130 | } 131 | ) 132 | OutputHandlers = @{ 133 | ParameterSetName = 'Default' 134 | Handler = { 135 | param ($output) 136 | if ($output) { 137 | $failures = ($output -match 'Chocolatey .+ packages failed\.') 138 | if ($failures) { 139 | Write-Error ($output -join "`r`n") 140 | } else { 141 | $packageRegex = "^(?[\S]+)[\|\s]v(?[\S]+)" 142 | $packageReportRegex="^[0-9]*(\s*)(packages installed)" 143 | $output | ForEach-Object { 144 | if (($_ -cmatch $packageRegex) -and ($_ -notmatch $packageReportRegex) -and ($_ -notmatch 'already installed') -and $Matches.name -and $Matches.version) { 145 | [pscustomobject]@{ 146 | Name = $Matches.name 147 | Version = $Matches.version 148 | } 149 | } 150 | } 151 | } 152 | } 153 | } 154 | } 155 | Verbs = @( 156 | @{ 157 | Verb = 'Install' 158 | Description = 'Install a new package with Chocolatey' 159 | OriginalCommandElements = @('install','--no-progress') 160 | Parameters = @( 161 | @{ 162 | Name = 'ParamsGlobal' 163 | OriginalName = '--params-global' 164 | ParameterType = 'switch' 165 | Description = 'Apply package parameters to dependencies' 166 | }, 167 | @{ 168 | Name = 'Parameters' 169 | OriginalName = '--parameters=' 170 | ParameterType = 'string' 171 | Description = 'Parameters to pass to the package' 172 | NoGap = $true 173 | }, 174 | @{ 175 | Name = 'ArgsGlobal' 176 | OriginalName = '--args-global' 177 | ParameterType = 'switch' 178 | Description = 'Apply package arguments to dependencies' 179 | }, 180 | @{ 181 | Name = 'InstallArguments' 182 | OriginalName = '--install-arguments=' 183 | ParameterType = 'string' 184 | Description = 'Parameters to pass to the package' 185 | NoGap = $true 186 | }, 187 | @{ 188 | Name = 'Source' 189 | OriginalName = '--source=' 190 | ParameterType = 'string' 191 | Description = 'Package Source' 192 | NoGap = $true 193 | ValueFromPipelineByPropertyName = $true 194 | }, 195 | @{ 196 | Name = 'Force' 197 | OriginalName = '--force' 198 | ParameterType = 'switch' 199 | Description = 'Force the operation' 200 | }, 201 | @{ 202 | Name = 'PreRelease' 203 | OriginalName = '--pre' 204 | ParameterType = 'switch' 205 | Description = 'Include prerelease packages' 206 | } 207 | ) 208 | }, 209 | @{ 210 | Verb = 'Get' 211 | Description = 'Get a list of installed or available Chocolatey packages' 212 | OriginalCommandElements = @('list') 213 | Parameters = @( 214 | @{ 215 | Name = 'AllVersions' 216 | OriginalName = '--all-versions' 217 | ParameterType = 'switch' 218 | Description = 'All Versions' 219 | }, 220 | @{ 221 | Name = 'LocalOnly' 222 | OriginalName = '--local-only' 223 | ParameterType = 'switch' 224 | Description = 'Local Packages Only' 225 | }, 226 | @{ 227 | Name = 'Exact' 228 | OriginalName = '--exact' 229 | ParameterType = 'switch' 230 | Description = 'Search by exact package name' 231 | }, 232 | @{ 233 | Name = 'Source' 234 | OriginalName = '--source=' 235 | ParameterType = 'string' 236 | Description = 'Package Source' 237 | NoGap = $true 238 | }, 239 | @{ 240 | Name = 'PreRelease' 241 | OriginalName = '--pre' 242 | ParameterType = 'switch' 243 | Description = 'Include prerelease packages' 244 | } 245 | ) 246 | OutputHandlers = @{ 247 | ParameterSetName = 'Default' 248 | Handler = { 249 | param ( $output ) 250 | $output | ForEach-Object { 251 | $Name,$version = $_ -split '\|' 252 | if ( -not [string]::IsNullOrEmpty($name)) { 253 | [pscustomobject]@{ 254 | Name = $Name 255 | Version = $version 256 | } 257 | } 258 | } 259 | } 260 | } 261 | }, 262 | @{ 263 | Verb = 'Find' 264 | Description = 'Finds a list of available Chocolatey packages' 265 | OriginalCommandElements = @('search') 266 | Parameters = @( 267 | @{ 268 | Name = 'AllVersions' 269 | OriginalName = '--all-versions' 270 | ParameterType = 'switch' 271 | Description = 'All Versions' 272 | }, 273 | @{ 274 | Name = 'Exact' 275 | OriginalName = '--exact' 276 | ParameterType = 'switch' 277 | Description = 'Search by exact package name' 278 | }, 279 | @{ 280 | Name = 'Source' 281 | OriginalName = '--source=' 282 | ParameterType = 'string' 283 | Description = 'Package Source' 284 | NoGap = $true 285 | }, 286 | @{ 287 | Name = 'PreRelease' 288 | OriginalName = '--pre' 289 | ParameterType = 'switch' 290 | Description = 'Include prerelease packages' 291 | } 292 | ) 293 | OutputHandlers = @{ 294 | ParameterSetName = 'Default' 295 | Handler = { 296 | param ( $output ) 297 | $output | ForEach-Object { 298 | $Name,$version = $_ -split '\|' 299 | if ( -not [string]::IsNullOrEmpty($name)) { 300 | [pscustomobject]@{ 301 | Name = $Name 302 | Version = $version 303 | } 304 | } 305 | } 306 | } 307 | } 308 | }, 309 | @{ 310 | Verb = 'Uninstall' 311 | Description = 'Uninstall an existing package with Chocolatey' 312 | OriginalCommandElements = @('uninstall') 313 | Parameters = @( 314 | @{ 315 | Name = 'Force' 316 | OriginalName = '--force' 317 | ParameterType = 'switch' 318 | Description = 'Force the operation' 319 | } 320 | @{ 321 | Name = 'RemoveDependencies' 322 | OriginalName = '--remove-dependencies' 323 | ParameterType = 'switch' 324 | Description = 'Remove all dependant packages not depended on by another installed package' 325 | } 326 | ) 327 | } 328 | ) 329 | } 330 | ) 331 | -------------------------------------------------------------------------------- /src/Foil.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | RootModule = 'Foil.psm1' 3 | ModuleVersion = '0.3.1' 4 | GUID = '38430603-9954-45fd-949a-5f79492ffaf7' 5 | Author = 'Ethan Bergstrom' 6 | Copyright = '2021-2023' 7 | Description = 'A PowerShell Crescendo wrapper for Chocolatey' 8 | # Crescendo modules aren't supported below PowerShell 5.1 9 | # https://devblogs.microsoft.com/powershell/announcing-powershell-crescendo-preview-1/ 10 | PowerShellVersion = '5.1' 11 | PrivateData = @{ 12 | PSData = @{ 13 | # Tags applied to this module to indicate this is a PackageManagement Provider. 14 | Tags = @('Crescendo','Chocolatey','PSEdition_Desktop','PSEdition_Core','Windows','CrescendoBuilt') 15 | 16 | # A URL to the license for this module. 17 | LicenseUri = 'https://github.com/ethanbergstrom/foil/blob/master/LICENSE.txt' 18 | 19 | # A URL to the main website for this project. 20 | ProjectUri = 'https://github.com/ethanbergstrom/Foil' 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/Foil.chocoV1.tests.ps1: -------------------------------------------------------------------------------- 1 | Import-Module Foil 2 | 3 | Describe "Chocolatey V1 test validity" { 4 | BeforeAll { 5 | $package = 'chocolatey' 6 | $version = '1.4.0' 7 | # Ensure an older verison of Chocolatey is present to provide for test coverage 8 | choco upgrade $package --version $version --allow-downgrade 9 | } 10 | It 'confirms version of Chocolatey is below v2' { 11 | Get-ChocoPackage -LocalOnly | Where-Object {$_.Name -eq $package -And $_.Version -lt '2.0.0'} | Should -Not -BeNullOrEmpty 12 | } 13 | } 14 | 15 | Describe "Chocolatey V1 basic package search operations" { 16 | Context 'without additional arguments' { 17 | BeforeAll { 18 | $package = 'cpu-z' 19 | } 20 | 21 | It 'gets a list of latest installed packages' { 22 | Get-ChocoPackage -LocalOnly | Where-Object {$_.Name -contains 'chocolatey'} | Should -Not -BeNullOrEmpty 23 | } 24 | It 'searches for the latest version of a package' { 25 | Get-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 26 | } 27 | It 'searches for all versions of a package' { 28 | Get-ChocoPackage -Name $package -AllVersions | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 29 | } 30 | It 'searches for the latest version of a package with a wildcard pattern' { 31 | Get-ChocoPackage -Name "$package*" | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 32 | } 33 | } 34 | } 35 | 36 | Describe "Chocolatey V1 DSC-compliant package installation and uninstallation" { 37 | Context 'without additional arguments' { 38 | BeforeAll { 39 | $package = 'cpu-z' 40 | } 41 | 42 | It 'searches for the latest version of a package' { 43 | Get-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 44 | } 45 | It 'silently installs the latest version of a package' { 46 | Install-ChocoPackage -Name $package -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 47 | } 48 | It 'detects the locally installed package just installed' { 49 | Get-ChocoPackage -Name $package -LocalOnly | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 50 | } 51 | It 'silently uninstalls the locally installed package just installed' { 52 | Uninstall-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 53 | } 54 | } 55 | Context 'with additional parameters' { 56 | BeforeAll { 57 | $package = 'sysinternals' 58 | } 59 | 60 | It 'searches for the latest version of a package' { 61 | Get-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 62 | } 63 | It 'silently installs the latest version of a package' { 64 | Install-ChocoPackage -Name $package -Force -ParamsGlobal -Parameters "/InstallDir:$env:ProgramFiles\$package /QuickLaunchShortcut:false" | Should -HaveCount 1 65 | } 66 | It 'correctly passed parameters to the package' { 67 | Get-ChildItem -Path (Join-Path -Path $env:ProgramFiles -ChildPath $package) -ErrorAction SilentlyContinue | Should -Not -BeNullOrEmpty 68 | } 69 | It 'detects the locally installed package just installed' { 70 | Get-ChocoPackage -Name $package -LocalOnly | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 71 | } 72 | It 'silently uninstalls the locally installed package just installed' { 73 | Uninstall-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 74 | } 75 | } 76 | Context 'with prerelease parameter' { 77 | BeforeAll { 78 | $package = 'firefox-dev' 79 | } 80 | 81 | It 'searches for the latest version of a package' { 82 | Get-ChocoPackage -Name $package -PreRelease | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 83 | } 84 | It 'silently installs the latest version of a package' { 85 | Install-ChocoPackage -Name $package -PreRelease -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 86 | } 87 | It 'detects the locally installed package just installed' { 88 | Get-ChocoPackage -Name $package -LocalOnly | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 89 | } 90 | It 'silently uninstalls the locally installed package just installed' { 91 | Uninstall-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 92 | } 93 | } 94 | } 95 | 96 | Describe "Chocolatey V1 pipline-based package installation and uninstallation" { 97 | Context 'without additional arguments' { 98 | BeforeAll { 99 | $package = 'cpu-z' 100 | } 101 | 102 | It 'searches for and silently installs the latest version of a package' { 103 | Get-ChocoPackage -Name $package | Install-ChocoPackage -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 104 | } 105 | It 'detects and silently uninstalls the locally installed package just installed' { 106 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 107 | } 108 | } 109 | Context 'with dependencies' { 110 | BeforeAll { 111 | $package = 'keepass-plugin-winhello' 112 | } 113 | 114 | It 'searches for and silently installs the latest version of a package' { 115 | Get-ChocoPackage -Name $package -Exact | Install-ChocoPackage -Force | Should -HaveCount 3 116 | } 117 | It 'detects and silently uninstalls the locally installed package just installed, along with its dependencies' { 118 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage -RemoveDependencies | Should -HaveCount 3 119 | } 120 | } 121 | Context 'with empty arguments' { 122 | BeforeAll { 123 | $package = 'cpu-z' 124 | } 125 | 126 | It 'searches for and silently installs the latest version of a package' { 127 | Get-ChocoPackage -Name $package | Install-ChocoPackage -Force -Parameters '' | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 128 | } 129 | It 'detects and silently uninstalls the locally installed package just installed' { 130 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 131 | } 132 | } 133 | Context 'with additional parameters' { 134 | BeforeAll { 135 | $package = 'sysinternals' 136 | } 137 | 138 | It 'searches for and silently installs the latest version of a package' { 139 | Get-ChocoPackage -Name $package -Exact | Install-ChocoPackage -Force -ParamsGlobal -Parameters "/InstallDir:$env:ProgramFiles\$package /QuickLaunchShortcut:false" | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 140 | } 141 | It 'correctly passed parameters to the package' { 142 | Get-ChildItem -Path (Join-Path -Path $env:ProgramFiles -ChildPath $package) -ErrorAction SilentlyContinue | Should -Not -BeNullOrEmpty 143 | } 144 | It 'detects and silently uninstalls the locally installed package just installed' { 145 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 146 | } 147 | } 148 | Context 'with prerelease parameter' { 149 | BeforeAll { 150 | $package = 'firefox-dev' 151 | } 152 | 153 | It 'searches for and silently installs the latest version of a package' { 154 | Get-ChocoPackage -Name $package -PreRelease | Install-ChocoPackage -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 155 | } 156 | It 'detects and silently uninstalls the locally installed package just installed' { 157 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 158 | } 159 | } 160 | } 161 | 162 | Describe "Chocolatey V1 multi-source support" { 163 | BeforeAll { 164 | $altSource = 'LocalChocoSource' 165 | $altLocation = $PSScriptRoot 166 | $package = 'cpu-z' 167 | 168 | Save-Package $package -Source 'http://chocolatey.org/api/v2' -Path $altLocation 169 | Unregister-ChocoSource -Name $altSource -ErrorAction SilentlyContinue 170 | } 171 | AfterAll { 172 | Remove-Item "$altLocation\*.nupkg" -Force -ErrorAction SilentlyContinue 173 | Unregister-ChocoSource -Name $altSource -ErrorAction SilentlyContinue 174 | } 175 | 176 | It 'registers an alternative package source' { 177 | { Register-ChocoSource -Name $altSource -Location $altLocation | Where-Object {$_.Name -eq $altSource} } | Should -Not -Throw 178 | } 179 | It 'searches for and installs the latest version of a package from an alternate source' { 180 | Get-ChocoPackage -Name $package -Source $altSource | Install-ChocoPackage -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 181 | } 182 | It 'detects and uninstalls a package installed from an alternate source' { 183 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 184 | } 185 | It 'unregisters an alternative package source' { 186 | Unregister-ChocoSource -Name $altSource 187 | Get-ChocoSource | Where-Object {$_.Name -eq $altSource} | Should -BeNullOrEmpty 188 | } 189 | } 190 | 191 | Describe "Chocolatey V1 version filters" { 192 | BeforeAll { 193 | $package = 'ninja' 194 | # Keep at least one version back, to test the 'latest' feature 195 | $version = '1.10.1' 196 | } 197 | AfterAll { 198 | Uninstall-ChocoPackage -Name $package -ErrorAction SilentlyContinue 199 | } 200 | 201 | Context 'required version' { 202 | It 'searches for and silently installs a specific package version' { 203 | Get-ChocoPackage -Name $package -Version $version -Exact | Install-ChocoPackage -Force | Where-Object {$_.Name -contains $package -and $_.Version -eq $version} | Should -Not -BeNullOrEmpty 204 | } 205 | It 'detects and silently uninstalls a specific package version' { 206 | Get-ChocoPackage -Name $package -Version $version -LocalOnly | UnInstall-ChocoPackage -Force | Where-Object {$_.Name -contains $package -and $_.Version -eq $version} | Should -Not -BeNullOrEmpty 207 | } 208 | } 209 | } 210 | 211 | Describe "Chocolatey V1 error handling on Chocolatey failures" { 212 | Context 'package installation' { 213 | BeforeAll { 214 | $package = 'googlechrome' 215 | # This version is known to be broken, per https://github.com/chocolatey-community/chocolatey-coreteampackages/issues/1608 216 | $version = '87.0.4280.141' 217 | } 218 | AfterAll { 219 | Uninstall-ChocoPackage -Name $package -ErrorAction SilentlyContinue 220 | } 221 | 222 | It 'searches for and fails to silently install a broken package version' { 223 | {Get-ChocoPackage -Name $package -Version $version -Exact | Install-ChocoPackage -Force} | Should -Throw 224 | } 225 | } 226 | Context 'package uninstallation' { 227 | BeforeAll { 228 | $package = 'chromium' 229 | # This version is known to be broken, per https://github.com/chocolatey-community/chocolatey-coreteampackages/issues/341 230 | $version = '56.0.2897.0' 231 | } 232 | 233 | It 'searches for, installs, and fails to silently uninstall a broken package version' { 234 | {Get-ChocoPackage -Name $package -Version $version -Exact | Install-ChocoPackage -Force | Uninstall-ChocoPackage} | Should -Throw 235 | } 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /test/Foil.chocoV2.tests.ps1: -------------------------------------------------------------------------------- 1 | Import-Module Foil 2 | 3 | Describe "Chocolatey V2 test validity" { 4 | BeforeAll { 5 | $package = 'chocolatey' 6 | $version = '2.0.0' 7 | # Upgrade to Chocolatey v2 alpha to test the API changes 8 | choco upgrade $package 9 | } 10 | It 'confirms version of Chocolatey is at least 2.0.0' { 11 | Get-ChocoPackage -LocalOnly | Where-Object {$_.Name -eq $package -And $_.Version -ge $version} | Should -Not -BeNullOrEmpty 12 | } 13 | } 14 | 15 | Describe "Chocolatey V2 basic package search operations" { 16 | Context 'without additional arguments' { 17 | BeforeAll { 18 | $package = 'cpu-z' 19 | } 20 | 21 | It 'gets a list of latest installed packages' { 22 | Get-ChocoPackage -LocalOnly | Where-Object {$_.Name -contains 'chocolatey'} | Should -Not -BeNullOrEmpty 23 | } 24 | It 'searches for the latest version of a package' { 25 | Find-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 26 | } 27 | It 'searches for all versions of a package' { 28 | Find-ChocoPackage -Name $package -AllVersions | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 29 | } 30 | It 'searches for the latest version of a package with a wildcard pattern' { 31 | Find-ChocoPackage -Name "$package*" | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 32 | } 33 | } 34 | } 35 | 36 | Describe "Chocolatey V2 DSC-compliant package installation and uninstallation" { 37 | Context 'without additional arguments' { 38 | BeforeAll { 39 | $package = 'cpu-z' 40 | } 41 | 42 | It 'searches for the latest version of a package' { 43 | Find-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 44 | } 45 | It 'silently installs the latest version of a package' { 46 | Install-ChocoPackage -Name $package -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 47 | } 48 | It 'detects the locally installed package just installed' { 49 | Get-ChocoPackage -Name $package -LocalOnly | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 50 | } 51 | It 'silently uninstalls the locally installed package just installed' { 52 | Uninstall-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 53 | } 54 | } 55 | Context 'with additional parameters' { 56 | BeforeAll { 57 | $package = 'sysinternals' 58 | } 59 | 60 | It 'searches for the latest version of a package' { 61 | Find-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 62 | } 63 | It 'silently installs the latest version of a package' { 64 | Install-ChocoPackage -Name $package -Force -ParamsGlobal -Parameters "/InstallDir:$env:ProgramFiles\$package /QuickLaunchShortcut:false" | Should -HaveCount 1 65 | } 66 | It 'correctly passed parameters to the package' { 67 | Get-ChildItem -Path (Join-Path -Path $env:ProgramFiles -ChildPath $package) -ErrorAction SilentlyContinue | Should -Not -BeNullOrEmpty 68 | } 69 | It 'detects the locally installed package just installed' { 70 | Get-ChocoPackage -Name $package -LocalOnly | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 71 | } 72 | It 'silently uninstalls the locally installed package just installed' { 73 | Uninstall-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 74 | } 75 | } 76 | Context 'with prerelease parameter' { 77 | BeforeAll { 78 | $package = 'firefox-dev' 79 | } 80 | 81 | It 'searches for the latest version of a package' { 82 | Find-ChocoPackage -Name $package -PreRelease | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 83 | } 84 | It 'silently installs the latest version of a package' { 85 | Install-ChocoPackage -Name $package -PreRelease -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 86 | } 87 | It 'detects the locally installed package just installed' { 88 | Get-ChocoPackage -Name $package -LocalOnly | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 89 | } 90 | It 'silently uninstalls the locally installed package just installed' { 91 | Uninstall-ChocoPackage -Name $package | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 92 | } 93 | } 94 | } 95 | 96 | Describe "Chocolatey V2 pipline-based package installation and uninstallation" { 97 | Context 'without additional arguments' { 98 | BeforeAll { 99 | $package = 'cpu-z' 100 | } 101 | 102 | It 'searches for and silently installs the latest version of a package' { 103 | Find-ChocoPackage -Name $package | Install-ChocoPackage -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 104 | } 105 | It 'detects and silently uninstalls the locally installed package just installed' { 106 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 107 | } 108 | } 109 | Context 'with dependencies' { 110 | BeforeAll { 111 | $package = 'keepass-plugin-winhello' 112 | } 113 | 114 | It 'searches for and silently installs the latest version of a package' { 115 | Find-ChocoPackage -Name $package -Exact | Install-ChocoPackage -Force | Should -HaveCount 3 116 | } 117 | It 'detects and silently uninstalls the locally installed package just installed, along with its dependencies' { 118 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage -RemoveDependencies | Should -HaveCount 3 119 | } 120 | } 121 | Context 'with empty arguments' { 122 | BeforeAll { 123 | $package = 'cpu-z' 124 | } 125 | 126 | It 'searches for and silently installs the latest version of a package' { 127 | Find-ChocoPackage -Name $package | Install-ChocoPackage -Force -Parameters '' | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 128 | } 129 | It 'detects and silently uninstalls the locally installed package just installed' { 130 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 131 | } 132 | } 133 | Context 'with additional parameters' { 134 | BeforeAll { 135 | $package = 'sysinternals' 136 | } 137 | 138 | It 'searches for and silently installs the latest version of a package' { 139 | Find-ChocoPackage -Name $package -Exact | Install-ChocoPackage -Force -ParamsGlobal -Parameters "/InstallDir:$env:ProgramFiles\$package /QuickLaunchShortcut:false" | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 140 | } 141 | It 'correctly passed parameters to the package' { 142 | Get-ChildItem -Path (Join-Path -Path $env:ProgramFiles -ChildPath $package) -ErrorAction SilentlyContinue | Should -Not -BeNullOrEmpty 143 | } 144 | It 'detects and silently uninstalls the locally installed package just installed' { 145 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 146 | } 147 | } 148 | Context 'with prerelease parameter' { 149 | BeforeAll { 150 | $package = 'firefox-dev' 151 | } 152 | 153 | It 'searches for and silently installs the latest version of a package' { 154 | Find-ChocoPackage -Name $package -PreRelease | Install-ChocoPackage -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 155 | } 156 | It 'detects and silently uninstalls the locally installed package just installed' { 157 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 158 | } 159 | } 160 | } 161 | 162 | Describe "Chocolatey V2 multi-source support" { 163 | BeforeAll { 164 | $altSource = 'LocalChocoSource' 165 | $altLocation = $PSScriptRoot 166 | $package = 'cpu-z' 167 | 168 | Save-Package $package -Source 'http://chocolatey.org/api/v2' -Path $altLocation 169 | Unregister-ChocoSource -Name $altSource -ErrorAction SilentlyContinue 170 | } 171 | AfterAll { 172 | Remove-Item "$altLocation\*.nupkg" -Force -ErrorAction SilentlyContinue 173 | Unregister-ChocoSource -Name $altSource -ErrorAction SilentlyContinue 174 | } 175 | 176 | It 'registers an alternative package source' { 177 | { Register-ChocoSource -Name $altSource -Location $altLocation | Where-Object {$_.Name -eq $altSource} } | Should -Not -Throw 178 | } 179 | It 'searches for and installs the latest version of a package from an alternate source' { 180 | Find-ChocoPackage -Name $package -Source $altSource | Install-ChocoPackage -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 181 | } 182 | It 'detects and uninstalls a package installed from an alternate source' { 183 | Get-ChocoPackage -Name $package -LocalOnly -Exact | Uninstall-ChocoPackage | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty 184 | } 185 | It 'unregisters an alternative package source' { 186 | Unregister-ChocoSource -Name $altSource 187 | Get-ChocoSource | Where-Object {$_.Name -eq $altSource} | Should -BeNullOrEmpty 188 | } 189 | } 190 | 191 | Describe "Chocolatey V2 version filters" { 192 | BeforeAll { 193 | $package = 'ninja' 194 | # Keep at least one version back, to test the 'latest' feature 195 | $version = '1.10.1' 196 | } 197 | AfterAll { 198 | Uninstall-ChocoPackage -Name $package -ErrorAction SilentlyContinue 199 | } 200 | 201 | Context 'required version' { 202 | It 'searches for and silently installs a specific package version' { 203 | Find-ChocoPackage -Name $package -Version $version -Exact | Install-ChocoPackage -Force | Where-Object {$_.Name -contains $package -and $_.Version -eq $version} | Should -Not -BeNullOrEmpty 204 | } 205 | It 'detects and silently uninstalls a specific package version' { 206 | Get-ChocoPackage -Name $package -Version $version -LocalOnly | UnInstall-ChocoPackage -Force | Where-Object {$_.Name -contains $package -and $_.Version -eq $version} | Should -Not -BeNullOrEmpty 207 | } 208 | } 209 | } 210 | 211 | Describe "Chocolatey V2 error handling on Chocolatey failures" { 212 | Context 'package installation' { 213 | BeforeAll { 214 | $package = 'googlechrome' 215 | # This version is known to be broken, per https://github.com/chocolatey-community/chocolatey-coreteampackages/issues/1608 216 | $version = '87.0.4280.141' 217 | } 218 | AfterAll { 219 | Uninstall-ChocoPackage -Name $package -ErrorAction SilentlyContinue 220 | } 221 | 222 | It 'searches for and fails to silently install a broken package version' { 223 | {Find-ChocoPackage -Name $package -Version $version -Exact | Install-ChocoPackage -Force} | Should -Throw 224 | } 225 | } 226 | Context 'package uninstallation' { 227 | BeforeAll { 228 | $package = 'chromium' 229 | # This version is known to be broken, per https://github.com/chocolatey-community/chocolatey-coreteampackages/issues/341 230 | $version = '56.0.2897.0' 231 | } 232 | 233 | It 'searches for, installs, and fails to silently uninstall a broken package version' { 234 | {Find-ChocoPackage -Name $package -Version $version -Exact | Install-ChocoPackage -Force | Uninstall-ChocoPackage} | Should -Throw 235 | } 236 | } 237 | } 238 | --------------------------------------------------------------------------------