[
  {
    "path": "CHANGELOG.md",
    "content": "### Version 1.3.0\n* BUGFIX: update url to API endpoint\n* BUGFIX: support for symlink handling in Win10\n* IMPROVE: use 7zip for archive extraction if available on path\n* BUGFIX: walkaround for rare ACCESS_DENIED error on SDK installation\n* BUGFIX: always show correct download file sizes\n\n### Version 1.2.2\n* BUGFIX: explicitly handle a missing version definition for uninstall\n* BUGFIX: added -Force for Remove-Item in the uninstall process\n\n### Version 1.2.1\n* BUGFIX: fixed wrong url construction for broadcast api\n\n### Version 1.2.0\n* IMPROVE: update to the new broadcast api for GVM\n\n### Version 1.1.4\n* IMPROVE: version check requests where executed on module import and took some time, these checks will now be executed on first gvm-call\n\n### Version 1.1.3\n* IMPROVE: the new version messaging\n\n### Version 1.1.2\n* BUGFIX: installation routine in GetPoshGvm.ps1 broken\n\n### Version 1.1.1\n* BUGFIX: default of $Global:PGVM_AUTO_SELFUPDATE was $true but should have been $false\n\n### Version 1.1.0\n* FEATURE: use unzip.exe if available on path for better install performance\n* FEATURE: self-update\n* FEATURE: automatic check for new posh-gvm versions\n\n### Version 1.0.0\n* posh-gvm before it has self-update functionality\n"
  },
  {
    "path": "Commands.Tests.ps1",
    "content": ". .\\Commands.ps1\n. .\\Utils.ps1\n. .\\Init.ps1\n. .\\TestUtils.ps1\n\nDescribe 'gvm' {\n    Context 'No posh-gvm dir available'{\n        $Script:GVM_FORCE_OFFLINE = $true\n        Mock-PGVM-Dir\n        Remove-Item $global:PGVM_DIR -Recurse\n        Mock Init-Posh-Gvm -verifiable\n        Mock Init-Candidate-Cache -verifiable\n        Mock Show-Help\n        gvm\n\n        It 'initalize posh-gvm' {\n            Assert-VerifiableMocks\n        }\n\n        It 'prints help' {\n            Assert-MockCalled Show-Help 1\n        }\n\n        Reset-PGVM-Dir\n    }\n\n    Context 'Posh-gvm dir available'{\n        $Script:GVM_FORCE_OFFLINE = $true\n        Mock-PGVM-Dir\n        Mock Init-Posh-Gvm\n        Mock Init-Candidate-Cache -verifiable\n        Mock Show-Help\n        gvm\n\n        It 'initalize posh-gvm' {\n            Assert-VerifiableMocks\n        }\n\n        It 'does not init again' {\n            Assert-MockCalled Init-Posh-Gvm 0\n        }\n\n        It 'prints help' {\n            Assert-MockCalled Show-Help 1\n        }\n\n    }\n\n    Context 'posh-gvm is forced offline' {\n        Mock-PGVM-DIR\n        Mock Init-Candidate-Cache -verifiable\n        Mock Check-Available-Broadcast\n        Mock Show-Help -verifiable\n        $Script:GVM_FORCE_OFFLINE = $true\n\n        gvm\n\n        It 'does not load broadcast message from api' {\n            Assert-MockCalled Check-Available-Broadcast 0\n        }\n\n        It 'performs default command actions' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-PGVM-DIR\n    }\n\n    Context 'posh-gvm offline command called' {\n        Mock-PGVM-DIR\n        Mock Init-Candidate-Cache -verifiable\n        Mock Check-Available-Broadcast\n        Mock Set-Offline-Mode -verifiable\n        $Script:GVM_FORCE_OFFLINE = $false\n\n        gvm offline\n\n        It 'does not load broadcast message from api' {\n            Assert-MockCalled Check-Available-Broadcast 0\n        }\n\n        It 'performs offline command actions' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-PGVM-DIR\n    }\n\n    Context 'posh-gvm online and command i called' {\n        Mock-Dispatcher-Test\n        Mock Install-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.2' -and $InstallPath -eq '\\bla' }\n\n        gvm i grails 2.2.2 \\bla\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls install-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command install called' {\n        Mock-Dispatcher-Test\n        Mock Install-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.2' -and $InstallPath -eq '' }\n\n        gvm install grails 2.2.2\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls install-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command uninstall called' {\n        Mock-Dispatcher-Test\n        Mock Uninstall-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.2' }\n\n        gvm uninstall grails 2.2.2\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls uninstall-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command rm called' {\n        Mock-Dispatcher-Test\n        Mock Uninstall-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' }\n\n        gvm rm grails 2.2.1\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls uninstall-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command ls called' {\n        Mock-Dispatcher-Test\n        Mock List-Candidate-Versions -verifiable -parameterFilter { $Candidate -eq 'grails'  }\n\n        gvm ls grails\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls list-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command list called' {\n        Mock-Dispatcher-Test\n        Mock List-Candidate-Versions -verifiable -parameterFilter { $Candidate -eq 'grails'  }\n\n        gvm list grails\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls list-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command u called' {\n        Mock-Dispatcher-Test\n        Mock Use-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' }\n\n        gvm u grails 2.2.1\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls use-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command use called' {\n        Mock-Dispatcher-Test\n        Mock Use-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' }\n\n        gvm use grails 2.2.1\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls use-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command d called' {\n        Mock-Dispatcher-Test\n        Mock Set-Default-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' }\n\n        gvm d grails 2.2.1\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls default-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command default called' {\n        Mock-Dispatcher-Test\n        Mock Set-Default-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' }\n\n        gvm default grails 2.2.1\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls default-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command c called' {\n        Mock-Dispatcher-Test\n        Mock Show-Current-Version -verifiable -parameterFilter { $Candidate -eq 'grails'  }\n\n        gvm c grails\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls current-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command current called' {\n        Mock-Dispatcher-Test\n        Mock Show-Current-Version -verifiable -parameterFilter { $Candidate -eq 'grails'  }\n\n        gvm current grails\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls current-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command v called' {\n        Mock-Dispatcher-Test\n        Mock Show-Posh-Gvm-Version -verifiable\n\n        gvm v\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls version-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command version called' {\n        Mock-Dispatcher-Test\n        Mock Show-Posh-Gvm-Version -verifiable\n\n        gvm version\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls version-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command b called' {\n        Mock-Dispatcher-Test\n        Mock Show-Broadcast-Message -verifiable\n\n        gvm b\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls broadcast-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command broadcast called' {\n        Mock-Dispatcher-Test\n        Mock Show-Broadcast-Message -verifiable\n\n        gvm broadcast\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls broadcast-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command h called' {\n        Mock-Dispatcher-Test\n        Mock Show-Help -verifiable\n\n        gvm h\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls help-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command help called' {\n        Mock-Dispatcher-Test\n        Mock Show-Help -verifiable\n\n        gvm help\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls help-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command offline called' {\n        Mock-Dispatcher-Test -Offline\n        Mock Set-Offline-Mode -verifiable -parameterFilter { $Flag -eq 'enable' }\n\n        gvm offline enable\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls offline-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command selfupdate called' {\n        Mock-Dispatcher-Test\n        Mock Invoke-Self-Update -verifiable\n\n        gvm selfupdate\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls selfupdate-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n\n    Context 'posh-gvm online and command flush called' {\n        Mock-Dispatcher-Test\n        Mock Flush-Cache -verifiable -parameterFilter { $DataType -eq 'version'  }\n\n        gvm flush version\n\n        It 'checks for new broadcast, inits the Candidate-Cache and calls flush-command' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-Dispatcher-Test\n    }\n}\n\nDescribe 'Install-Candidate-Version' {\n    Context 'Remote Version already installed' {\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Check-Candidate-Version-Available { '1.1.1' } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Is-Candidate-Version-Locally-Available { $true } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n\n        It 'throw an error' {\n            { Install-Candidate-Version grails 1.1.1 } | Should Throw\n        }\n\n        It 'process precondition checks' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Local Version already installed' {\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Check-Candidate-Version-Available { throw 'error' } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Is-Candidate-Version-Locally-Available { $true } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n\n        It 'throw an error' {\n            { Install-Candidate-Version grails 1.1.1 \\bla } | Should Throw\n        }\n\n        It 'process precondition checks' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Local path but version is remote available already installed' {\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Check-Candidate-Version-Available { 1.1.1 } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n\n        It 'throw an error' {\n            { Install-Candidate-Version grails 1.1.1 \\bla } | Should Throw\n        }\n\n        It 'process precondition checks' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Local version installation without defaulting' {\n        $backupAutoAnswer = $Global:PGVM_AUTO_ANSWER\n        $Global:PGVM_AUTO_ANSWER = $false\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Check-Candidate-Version-Available { throw 'error' } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Is-Candidate-Version-Locally-Available { $false } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Install-Local-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' -and $LocalPath -eq '\\bla' }\n        Mock Read-Host { 'n' }\n        Mock Set-Linked-Candidate-Version\n\n        Install-Candidate-Version grails 1.1.1 \\bla\n\n        It 'installs the local version' {\n            Assert-VerifiableMocks\n        }\n\n        It \"does not set default\" {\n            Assert-MockCalled Set-Linked-Candidate-Version 0\n        }\n\n        $Global:PGVM_AUTO_ANSWER = $backupAutoAnswer\n    }\n\n    Context 'Local version installation with auto defaulting' {\n        $backupAutoAnswer = $Global:PGVM_AUTO_ANSWER\n        $Global:PGVM_AUTO_ANSWER = $true\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Check-Candidate-Version-Available { throw 'error' } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Is-Candidate-Version-Locally-Available { $false } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Install-Local-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' -and $LocalPath -eq '\\bla' }\n        Mock Set-Linked-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Write-Output -verifiable\n\n        Install-Candidate-Version grails 1.1.1 \\bla\n\n        It 'installs the local version' {\n            Assert-VerifiableMocks\n        }\n\n        $Global:PGVM_AUTO_ANSWER = $backupAutoAnswer\n    }\n\n    Context 'Remote version installation with prompt defaulting' {\n        $backupAutoAnswer = $Global:PGVM_AUTO_ANSWER\n        $Global:PGVM_AUTO_ANSWER = $false\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Check-Candidate-Version-Available { '1.1.1' } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Is-Candidate-Version-Locally-Available { $false } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Install-Remote-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Read-Host { 'y' }\n        Mock Set-Linked-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Write-Output -verifiable\n\n        Install-Candidate-Version grails 1.1.1\n\n        It 'installs the local version' {\n            Assert-VerifiableMocks\n        }\n\n        $Global:PGVM_AUTO_ANSWER = $backupAutoAnswer\n    }\n}\n\nDescribe 'Uninstall-Candidate-Version' {\n    Context 'No version is provided' {\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        It 'throws an error' {\n            { Uninstall-Candidate-Version grails } | Should Throw\n        }\n    }\n\n    Context 'To be uninstalled version is not installed' {\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Is-Candidate-Version-Locally-Available { $false } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '24.3' }\n\n        It 'throws an error' {\n            { Uninstall-Candidate-Version grails 24.3 } | Should Throw\n        }\n\n        It 'checks candidate' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'To be uninstalled Version is current version' {\n        Mock-PGVM-Dir\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\24.3\" | Out-Null\n        Set-Linked-Candidate-Version grails 24.3\n\n        It 'finds current-junction defined' {\n            Test-Path \"$Global:PGVM_DIR\\grails\\current\" | Should Be $true\n        }\n\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Is-Candidate-Version-Locally-Available { $true } -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '24.3' }\n        Mock Get-Current-Candidate-Version { '24.3' } -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Write-Output -verifiable\n\n        Uninstall-Candidate-Version grails 24.3\n\n        It 'delete the current-junction' {\n            Test-Path \"$Global:PGVM_DIR\\grails\\current\" | Should Be $false\n        }\n\n        It 'delete the version' {\n            Test-Path \"$Global:PGVM_DIR\\grails\\24.3\" | Should Be $false\n        }\n\n        It \"checks different preconditions correctly\" {\n            Assert-VerifiableMocks\n        }\n\n        Reset-PGVM-Dir\n    }\n\n    Context 'To be uninstalled version is installed' {\n        Mock-PGVM-Dir\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\24.3\" | Out-Null\n\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Is-Candidate-Version-Locally-Available { $true } -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '24.3'}\n        Mock Get-Current-Candidate-Version { $null } -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Write-Output -verifiable\n\n        Uninstall-Candidate-Version grails 24.3\n\n        It 'delete the version' {\n            Test-Path \"$Global:PGVM_DIR\\grails\\24.3\" | Should Be $false\n        }\n\n        It \"checks different preconditions correctly\" {\n            Assert-VerifiableMocks\n        }\n\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'List-Candidate-Versions' {\n    Context 'if in online mode' {\n        Mock-Online\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Write-Version-List -verifiable -parameterFilter { $Candidate -eq 'grails' }\n\n        List-Candidate-Versions grails\n\n        It 'write the version list retrieved from api' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'If in offline mode' {\n        Mock-Offline\n        Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n        Mock Write-Offline-Version-List -verifiable -parameterFilter { $Candidate -eq 'grails' }\n\n        List-Candidate-Versions grails\n\n        It 'write the version list based on local file structure' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Use-Candidate-Version' {\n    Context 'If new use version is already used' {\n        Mock Check-Candidate-Version-Available { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Get-Env-Candidate-Version { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' }\n        Mock Write-Output -verifiable\n        Mock Check-Candidate-Version-Locally-Available\n\n        Use-Candidate-Version grails 1.1.1\n\n        It 'changes nothing' {\n            Assert-VerifiableMocks\n        }\n\n        It 'does not test candidate version' {\n            Assert-MockCalled Check-Candidate-Version-Locally-Available 0\n        }\n    }\n\n    Context 'If setting a different version as the current version to use' {\n        Mock Check-Candidate-Version-Available { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Get-Env-Candidate-Version { '1.1.0' } -parameterFilter { $Candidate -eq 'grails' }\n        Mock Write-Output -verifiable\n        Mock Check-Candidate-Version-Locally-Available -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n\n        Use-Candidate-Version grails 1.1.1\n\n        It 'perform the changes' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Set-Default-Version' {\n    Context 'If new default is already default' {\n        Mock Check-Candidate-Version-Available { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Get-Current-Candidate-Version { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' }\n        Mock Write-Output -verifiable\n        Mock Check-Candidate-Version-Locally-Available\n\n        Set-Default-Version grails 1.1.1\n\n        It 'changes nothing' {\n            Assert-VerifiableMocks\n        }\n\n        It 'does not test candidate version' {\n            Assert-MockCalled Check-Candidate-Version-Locally-Available 0\n        }\n    }\n\n    Context 'If setting a new default' {\n        Mock Check-Candidate-Version-Available { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Get-Current-Candidate-Version { '1.1.0' } -parameterFilter { $Candidate -eq 'grails' }\n        Mock Write-Output -verifiable\n        Mock Check-Candidate-Version-Locally-Available -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n        Mock Set-Linked-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n\n        Set-Default-Version grails 1.1.1\n\n        It 'perform the changes' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Show-Current-Version' {\n    Context 'If called without candidate' {\n        $Script:GVM_CANDIDATES = @('grails','groovy','bla')\n        Mock Get-Env-Candidate-Version { '1.1.0' } -parameterFilter { $Candidate -eq 'grails' }\n        Mock Get-Env-Candidate-Version { '2.1.0' } -parameterFilter { $Candidate -eq 'groovy' }\n        Mock Get-Env-Candidate-Version { '0.1.0' } -parameterFilter { $Candidate -eq 'bla' }\n        Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'Using:' }\n        Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'grails: 1.1.0' }\n        Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'groovy: 2.1.0' }\n        Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'bla: 0.1.0' }\n\n        Show-Current-Version\n\n        It 'write the version for all currently used candidates' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'If called with specifiv candidate and version available' {\n        Mock Check-Candidate-Present -verifiable\n        Mock Get-Env-Candidate-Version { '1.1.0' } -parameterFilter { $Candidate -eq 'grails' }\n        Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'Using grails version 1.1.0' }\n\n        Show-Current-Version grails\n\n        It 'write version info' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'If called with specifiv candidate and no version available' {\n        Mock Check-Candidate-Present -verifiable\n        Mock Get-Env-Candidate-Version { $null } -parameterFilter { $Candidate -eq 'grails' }\n        Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'Not using any version of grails' }\n\n        Show-Current-Version grails\n\n        It 'write no version is available' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Show-Posh-Gvm-Version' {\n    Context 'When called' {\n        Mock Get-GVM-API-Version -verifiable\n        Mock Get-Posh-Gvm-Version -verifiable\n        Mock Write-Output -verifiable\n\n        Show-Posh-Gvm-Version\n\n        It 'write the version message to output' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Show-Broadcast-Message' {\n    Context 'When called' {\n        $Script:PGVM_BROADCAST_PATH = 'broadcast'\n        Mock Get-Content { 'broadcast' } -verifiable -parameterFilter { $Path -eq 'broadcast' }\n        Mock Write-Output -verifiable\n\n        Show-Broadcast-Message\n\n        It 'Write broadcast message to output' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Set-Offline-Mode' {\n    Context 'If called with invalid flag' {\n        It 'throws an error' {\n            { Set-Offline-Mode invalid } | Should Throw\n        }\n    }\n\n    Context 'If called with enable flag' {\n        $Script:GVM_FORCE_OFFLINE = $false\n        Mock Write-Output -verifiable\n\n        Set-Offline-Mode enable\n\n        It \"set offline mode\" {\n            $Script:GVM_FORCE_OFFLINE | Should Be $true\n        }\n\n        It \"writes info to output\" {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'if called with disable flag' {\n        $Script:GVM_ONLINE = $false\n        $Script:GVM_FORCE_OFFLINE = $true\n        Mock Write-Output -verifiable\n\n        Set-Offline-Mode disable\n\n        It \"deactivate offline mode\" {\n            $Script:GVM_FORCE_OFFLINE | Should Be $false\n        }\n\n        It \"set gvm to online\" {\n            $Script:GVM_ONLINE | Should Be $true\n        }\n\n        It \"writes info to output\" {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Flush-Cache' {\n    Context 'Try to delete existing candidates cache' {\n        $Script:PGVM_CANDIDATES_PATH = 'test'\n        Mock Test-Path { $true } -parameterFilter { $Path -eq 'test' }\n        Mock Remove-Item -verifiable -parameterFilter { $Path -eq 'test' }\n        Mock Write-Output -verifiable\n\n        Flush-Cache candidates\n\n        It 'deletes the file and writes flush message' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Try to delete non-existing candidates cache' {\n        $Script:PGVM_CANDIDATES_PATH = 'test2'\n        Mock Test-Path { $false } -parameterFilter { $Path -eq 'test2' }\n        Mock Write-Warning -verifiable\n\n        Flush-Cache candidates\n\n        It 'writes warning about non existing file' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Try to delete existing broadcast cache' {\n        $Script:PGVM_BROADCAST_PATH = 'test'\n        Mock Test-Path { $true } -parameterFilter { $Path -eq 'test' }\n        Mock Remove-Item -verifiable -parameterFilter { $Path -eq 'test' }\n        Mock Write-Output -verifiable\n\n        Flush-Cache broadcast\n\n        It 'deletes the file and writes flush message' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Try to delete non-existing broadcast cache' {\n        $Script:PGVM_BROADCAST_PATH = 'test2'\n        Mock Test-Path { $false } -parameterFilter { $Path -eq 'test2' }\n        Mock Write-Warning -verifiable\n\n        Flush-Cache broadcast\n\n        It 'writes warning about non existing file' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Try to delete existing version cache' {\n        $Script:GVM_API_VERSION_PATH = 'test'\n        Mock Test-Path { $true } -parameterFilter { $Path -eq 'test' }\n        Mock Remove-Item -verifiable -parameterFilter { $Path -eq 'test' }\n        Mock Write-Output -verifiable\n\n        Flush-Cache version\n\n        It 'deletes the file and writes flush message' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Try to delete non-existing version cache' {\n        $Script:GVM_API_VERSION_PATH = 'test2'\n        Mock Test-Path { $false } -parameterFilter { $Path -eq 'test2' }\n        Mock Write-Warning -verifiable\n\n        Flush-Cache version\n\n        It 'writes warning about non existing file' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Cleanup archives directory' {\n        $Script:PGVM_ARCHIVES_PATH = 'archives'\n        Mock Cleanup-Directory -verifiable -parameterFilter { $Path -eq  'archives' }\n\n        Flush-Cache archives\n\n        It 'cleanup archives directory' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Cleanup temp directory' {\n        $Script:PGVM_TEMP_PATH = 'temp'\n        Mock Cleanup-Directory -verifiable -parameterFilter { $Path -eq  'temp' }\n\n        Flush-Cache temp\n\n        It 'cleanup temp directory' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Cleanup tmp directory' {\n        $Script:PGVM_TEMP_PATH = 'temp'\n        Mock Cleanup-Directory -verifiable -parameterFilter { $Path -eq  'temp' }\n\n        Flush-Cache tmp\n\n        It 'cleanup temp directory' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'flush invalid parameter' {\n        It 'throws an error' {\n            { Flush-Cache invalid } | Should Throw\n        }\n    }\n}\n\nDescribe 'Show-Help' {\n    Context 'If Show-Help is called' {\n        Mock Write-Output -verifiable\n\n        Show-Help\n\n        It 'write the help to the output' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n"
  },
  {
    "path": "Commands.ps1",
    "content": "﻿function gvm([string]$Command, [string]$Candidate, [string]$Version, [string]$InstallPath, [switch]$Verbose, [switch]$Force) {\n    $ErrorActionPreference = 'Stop'\n\t$ProgressPreference = 'SilentlyContinue'\n\tif ($Verbose) { $VerbosePreference = 'Continue' }\n\n    if ( !( Test-Path $Global:PGVM_DIR ) ) {\n        Write-Warning \"$Global:PGVM_DIR does not exists. Reinitialize posh-gvm\"\n        Init-Posh-Gvm\n    }\n\n    $Script:GVM_AVAILABLE = $true\n    if ( !($Script:GVM_FORCE_OFFLINE) -and $Command -ne 'offline' ) {\n        Check-Available-Broadcast $Command\n\n        if ( $Script:GVM_AVAILABLE ) {\n            if ( $Script:FIRST_RUN ) {\n                Check-GVM-API-Version\n                Check-Posh-Gvm-Version\n                $Script:FIRST_RUN = $false\n            }\n            Write-New-Version-Broadcast\n        }\n    }\n\n    Init-Candidate-Cache\n\n    Write-Verbose \"Command: $Command\"\n\n    if ($Command -eq '') {\n        $Command = 'help'\n    }\n\n    try {\n        switch -regex ($Command) {\n            '^i(nstall)?$'    { Install-Candidate-Version $Candidate $Version $InstallPath }\n            '^(uninstall|rm)$'{ Uninstall-Candidate-Version $Candidate $Version }\n            '^(ls|list)$'     { List-Candidate-Versions $Candidate }\n            '^u(se)?$'        { Use-Candidate-Version $Candidate $Version }\n            '^d(efault)?$'    { Set-Default-Version $Candidate $Version }\n            '^c(urrent)?$'    { Show-Current-Version $Candidate }\n            '^v(ersion)?$'    { Show-Posh-Gvm-Version }\n            '^b(roadcast)?$'  { Show-Broadcast-Message }\n            '^h(elp)?$'       { Show-Help }\n            '^offline$'       { Set-Offline-Mode $Candidate }\n            '^selfupdate$'    { Invoke-Self-Update($Force) }\n            '^flush$'         { Flush-Cache $Candidate }\n            default           { Write-Warning \"Invalid command: $Command. Check gvm help!\" }\n        }\n    } catch {\n        if ( $_.CategoryInfo.Category -eq 'OperationStopped') {\n            Write-Warning $_.CategoryInfo.TargetName\n        } else {\n            throw\n        }\n    }\n}\n\nfunction Install-Candidate-Version($Candidate, $Version, $InstallPath) {\n    Write-Verbose 'Perform Install-Candidate-Version'\n    Check-Candidate-Present $Candidate\n\n    $localInstallation = $false\n    if ($Version -and $InstallPath) {\n        #local installation\n        try {\n            $Version = Check-Candidate-Version-Available $Candidate $Version\n        } catch {\n            $localInstallation = $true\n        }\n\t\tif ( !($localInstallation) ) {\n\t\t\tthrow 'Stop! Local installation for $Candidate $Version not possible. It exists remote already.'\n\t\t}\n    } else {\n        $Version = Check-Candidate-Version-Available $Candidate $Version\n    }\n\n    if ( Is-Candidate-Version-Locally-Available $Candidate $Version ) {\n        throw \"Stop! $Candidate $Version is already installed.\"\n    }\n\n    if ( $localInstallation ) {\n        Install-Local-Version $Candidate $Version $InstallPath\n    } else {\n        Install-Remote-Version $Candidate $Version\n    }\n\n    $default = $false\n    if ( !$Global:PGVM_AUTO_ANSWER ) {\n        $default = (Read-Host -Prompt \"Do you want $Candidate $Version to be set as default? (Y/n)\") -match '(y|\\A\\z)'\n    } else {\n        $default = $true\n    }\n\n    if ( $default ) {\n        Write-Output \"Setting $Candidate $Version as default.\"\n        Set-Linked-Candidate-Version $Candidate $Version\n    }\n}\n\nfunction Uninstall-Candidate-Version($Candidate, $Version) {\n    Write-Verbose 'Perform Uninstall-Candidate-Version'\n    Check-Candidate-Present $Candidate\n    Check-Version-Present $Version\n\n    if ( !(Is-Candidate-Version-Locally-Available $Candidate $Version) ) {\n        throw \"$Candidate $Version is not installed.\"\n    }\n\n    $current = Get-Current-Candidate-Version $Candidate\n\n    if ( $current -eq $Version ) {\n        Write-Output \"Unselecting $Candidate $Version...\"\n        (Get-Item \"$Global:PGVM_DIR\\$Candidate\\current\").Delete()\n    }\n\n    Write-Output \"Uninstalling $Candidate $Version...\"\n    Remove-Item -Recurse -Force \"$Global:PGVM_DIR\\$Candidate\\$Version\"\n}\n\nfunction List-Candidate-Versions($Candidate) {\n    Write-Verbose 'Perform List-Candidate-Version'\n    Check-Candidate-Present $Candidate\n    if ( Get-Online-Mode ) {\n        Write-Version-List $Candidate\n    } else {\n        Write-Offline-Version-List $Candidate\n    }\n}\n\nfunction Use-Candidate-Version($Candidate, $Version) {\n    Write-Verbose 'Perform Use-Candidate-Version'\n    $Version = Check-Candidate-Version-Available $Candidate $Version\n\n    if ( $Version -eq (Get-Env-Candidate-Version $Candidate) ) {\n        Write-Output \"$Candidate $Version is used. Nothing changed.\"\n    } else {\n        Check-Candidate-Version-Locally-Available $Candidate $Version\n        Set-Env-Candidate-Version $Candidate $Version\n\t\tWrite-Output \"Using $CANDIDATE version $Version in this shell.\"\n    }\n}\n\nfunction Set-Default-Version($Candidate, $Version) {\n    Write-Verbose 'Perform Set-Default-Version'\n    $Version = Check-Candidate-Version-Available $Candidate $Version\n\n    if ( $Version -eq (Get-Current-Candidate-Version $Candidate) ) {\n        Write-Output \"$Candidate $Version is already default. Nothing changed.\"\n    } else {\n        Check-Candidate-Version-Locally-Available $Candidate $Version\n        Set-Linked-Candidate-Version $Candidate $Version\n        Write-Output \"Default $Candidate version set to $Version\"\n    }\n}\n\nfunction Show-Current-Version($Candidate) {\n    Write-Verbose 'Perform Set-Current-Version'\n\n    if ( !($Candidate) ) {\n        Write-Output 'Using:'\n        foreach ( $c in $Script:GVM_CANDIDATES ) {\n            $v = Get-Env-Candidate-Version $c\n            if ($v) {\n                Write-Output \"$c`: $v\"\n            }\n        }\n        return\n    }\n\n    Check-Candidate-Present $Candidate\n    $Version = Get-Env-Candidate-Version $Candidate\n    if ( $Version ) {\n        Write-Output \"Using $Candidate version $Version\"\n    } else {\n        Write-Output \"Not using any version of $Candidate\"\n    }\n}\n\nfunction Show-Posh-Gvm-Version() {\n    $poshGvmVersion = Get-Posh-Gvm-Version\n    $apiVersion = Get-GVM-API-Version\n    Write-Output \"posh-gvm (POwer SHell Groovy enVironment Manager) $poshGvmVersion base on GVM $GVM_BASE_VERSION and GVM API $apiVersion\"\n}\n\nfunction Show-Broadcast-Message() {\n    Write-Verbose 'Perform Show-Broadcast-Message'\n    Get-Content $Script:PGVM_BROADCAST_PATH | Write-Output\n}\n\nfunction Set-Offline-Mode($Flag) {\n    Write-Verbose 'Perform Set-Offline-Mode'\n    switch ($Flag) {\n        'enable'  { $Script:GVM_FORCE_OFFLINE = $true; Write-Output 'Forced offline mode enabled.' }\n        'disable' { $Script:GVM_FORCE_OFFLINE = $false; $Script:GVM_ONLINE = $true; Write-Output 'Online mode re-enabled!' }\n        default   { throw \"Stop! $Flag is not a valid offline offline mode.\" }\n    }\n}\n\nfunction Flush-Cache($DataType) {\n    Write-Verbose 'Perform Flush-Cache'\n    switch ($DataType) {\n        'candidates' {\n                        if ( Test-Path $Script:PGVM_CANDIDATES_PATH ) {\n                            Remove-Item $Script:PGVM_CANDIDATES_PATH\n                            Write-Output 'Candidates have been flushed.'\n                        } else {\n                            Write-Warning 'No candidate list found so not flushed.'\n                        }\n                     }\n        'broadcast'  {\n                        if ( Test-Path $Script:PGVM_BROADCAST_PATH ) {\n                            Remove-Item $Script:PGVM_BROADCAST_PATH\n                            Write-Output 'Broadcast have been flushed.'\n                        } else {\n                            Write-Warning 'No prior broadcast found so not flushed.'\n                        }\n                     }\n        'version'    {\n                        if ( Test-Path $Script:GVM_API_VERSION_PATH ) {\n                            Remove-Item $Script:GVM_API_VERSION_PATH\n                            Write-Output 'Version Token have been flushed.'\n                        } else {\n                            Write-Warning 'No prior Remote Version found so not flushed.'\n                        }\n                     }\n        'archives'   { Cleanup-Directory $Script:PGVM_ARCHIVES_PATH }\n        'temp'       { Cleanup-Directory $Script:PGVM_TEMP_PATH }\n        'tmp'        { Cleanup-Directory $Script:PGVM_TEMP_PATH }\n        default      { throw 'Stop! Please specify what you want to flush.' }\n    }\n}\n\nfunction Show-Help() {\n    Write-Output @\"\nUsage: gvm <command> <candidate> [version]\n    gvm offline <enable|disable>\n\n    commands:\n        install   or i    <candidate> [version]\n        uninstall or rm   <candidate> <version>\n        list      or ls   <candidate>\n        use       or u    <candidate> [version]\n        default   or d    <candidate> [version]\n        current   or c    [candidate]\n        version   or v\n        broadcast or b\n        help      or h\n        offline           <enable|disable>\n        selfupdate        [-Force]\n        flush             <candidates|broadcast|archives|temp>\n    candidate  :  $($Script:GVM_CANDIDATES -join ', ')\n\n    version    :  where optional, defaults to latest stable if not provided\n\neg: gvm install groovy\n\"@\n}\n"
  },
  {
    "path": "GetPoshGvm.ps1",
    "content": "<#\n\tParagon for the installation script is PsGet\n#>\n\nfunction Install-Posh-Gvm() {\n    $poshGvmZipUrl = 'https://github.com/flofreud/posh-gvm/archive/master.zip'\n\n    $poshGvmPath = Find-Module-Location\n\n    try {\n        # create temp dir\n        $tempDir = [guid]::NewGuid().ToString()\n        $tempDir = Join-Path -Path $env:TEMP -ChildPath $tempDir\n        New-Item -ItemType Directory $tempDir | Out-Null\n\n        # download current version\n        $poshGvmZip = \"$tempDir\\posh-gvm-master.zip\"\n        Write-Output \"Downloading posh-gvm from $poshGvmZipUrl\"\n\n        $client = (New-Object Net.WebClient)\n        $client.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials\n\t[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n        $client.DownloadFile($poshGvmZipUrl, $poshGvmZip)\n\n        # unzip archive\n        $shell = New-Object -com shell.application\n        $shell.namespace($tempDir).copyhere($shell.namespace($poshGvmZip).items(), 0x14)\n\n        # check if unzip successfully\n        if ( Test-Path \"$tempDir\\posh-gvm-master\" ) {\n            if ( !(Test-Path $poshGvmPath) ) {\n               New-Item -ItemType Directory $poshGvmPath | Out-Null\n            }\n\n            Copy-Item \"$tempDir\\posh-gvm-master\\*\" $poshGvmPath -Force -Recurse\n            Write-Output \"posh-gvm installed!\"\n            Write-Output \"Please see https://github.com/flofreud/posh-gvm#usage for details to get started.\"\n            Write-Warning \"Execute 'Import-Module posh-gvm -Force' so changes take effect!\"\n        } else {\n            Write-Warning 'Could not unzip archive containing posh-gvm. Most likely the archive is currupt. Please try to install again.'\n        }\n    } finally {\n        # clear temp dir\n        Remove-Item -Recurse -Force $tempDir\n    }\n}\n\nfunction Find-Module-Location {\n    $moduleDescriptor = Get-Module posh-gvm\n\n    if ( $moduleDescriptor ) {\n        return (Get-Item ($moduleDescriptor).Path).Directory.FullName\n    } else {\n        $modulePaths = @($Env:PSModulePath -split ';')\n        # set module path to posh default\n        $targetModulePath = Join-Path -Path ([Environment]::GetFolderPath('MyDocuments')) -ChildPath WindowsPowerShell\\Modules\n        # if its not use select the first defined\n        if ( $modulePaths -inotcontains $targetModulePath  ) {\n            $targetModulePath = $modulePaths | Select-Object -Index 0\n        }\n\n        return \"$targetModulePath\\posh-gvm\"\n    }\n}\n\nInstall-Posh-Gvm\n"
  },
  {
    "path": "Init.Tests.ps1",
    "content": ". .\\Utils.ps1\n. .\\Init.ps1\n. .\\TestUtils.ps1\n\nDescribe 'Init-Posh-Gvm' {\n    Context 'PGVM-Dir with only a grails folder' {\n        Mock-PGVM-Dir\n        Mock Check-JAVA-HOME -verifiable\n        Mock Update-Candidates-Cache -verifiable\n        Mock Init-Candidate-Cache -verifiable\n        Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq 'current' }\n        Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'groovy' -and $Version -eq 'current' }\n        Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'bla' -and $Version -eq 'current' }\n        $Script:PGVM_CANDIDATES_PATH = \"$Global:PGVM_DIR\\.meta\\candidates.txt\"\n        $Script:GVM_CANDIDATES = 'grails','groovy','bla'\n\n        Init-Posh-Gvm\n\n        It \"creates .meta\" {\n            Test-Path \"$Global:PGVM_DIR\\.meta\" | Should Be $true\n        }\n\n        It \"creates grails\" {\n            Test-Path \"$Global:PGVM_DIR\\grails\" | Should Be $true\n        }\n\n        It \"creates groovy\" {\n            Test-Path \"$Global:PGVM_DIR\\groovy\" | Should Be $true\n        }\n\n        It \"creates bla\" {\n            Test-Path \"$Global:PGVM_DIR\\bla\" | Should Be $true\n        }\n\n        It \"calls methods to test JAVA_HOME, API version, loads candidate cache and setup env variables\" {\n            Assert-VerifiableMocks\n        }\n\n        Reset-PGVM-Dir\n    }\n\n    Context 'PGVM-Dir with only a grails folder and a candidates list' {\n        Mock-PGVM-Dir\n        Mock Check-JAVA-HOME -verifiable\n        Mock Update-Candidates-Cache\n        Mock Init-Candidate-Cache -verifiable\n        Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq 'current' }\n        Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'groovy' -and $Version -eq 'current' }\n        Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'bla' -and $Version -eq 'current' }\n        $Script:PGVM_CANDIDATES_PATH = \"$Global:PGVM_DIR\\.meta\\candidates.txt\"\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\.meta\" | Out-Null\n        New-Item -ItemType File $Script:PGVM_CANDIDATES_PATH | Out-Null\n        $Script:GVM_CANDIDATES = 'grails','groovy','bla'\n\n        Init-Posh-Gvm\n\n        It \"creates .meta\" {\n            Test-Path \"$Global:PGVM_DIR\\.meta\" | Should Be $true\n        }\n\n        It \"creates grails\" {\n            Test-Path \"$Global:PGVM_DIR\\grails\" | Should Be $true\n        }\n\n        It \"creates groovy\" {\n            Test-Path \"$Global:PGVM_DIR\\groovy\" | Should Be $true\n        }\n\n        It \"creates bla\" {\n            Test-Path \"$Global:PGVM_DIR\\bla\" | Should Be $true\n        }\n\n        It \"calls methods to test JAVA_HOME, API version, loads candidate cache and setup env variables\" {\n            Assert-VerifiableMocks\n        }\n\n        It \"does not call update-candidates-cache\" {\n            Assert-MockCalled Update-Candidates-Cache 0\n        }\n\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Check-JAVA-HOME' {\n    Context 'JAVA_HOME is set' {\n        Mock Get-Command\n        Mock Test-Path { $true } -parameterFilter { $Path -eq 'env:Java_HOME' }\n\n        Check-JAVA-HOME\n\n        It \"changes nothing\" {\n            Assert-MockCalled Get-Command 0\n        }\n    }\n\n    Context 'JAVA_HOME is not set but javac is on path' {\n        $backupJAVAHOME = [Environment]::GetEnvironmentVariable('JAVA_HOME')\n        Mock Test-Path { $false } -parameterFilter { $Path -eq 'env:Java_HOME' }\n        Mock Get-Command { New-Object PSObject -Property @{ Path = (Get-Item 'C:\\Windows\\explorer.exe') } } -parameterFilter { $Name -eq 'javac' }\n        $expectedNewJAVAHOME = 'C:\\'\n\n        Check-JAVA-HOME\n\n        It \"sets JAVA_HOME to javac parent\" {\n            [Environment]::GetEnvironmentVariable('JAVA_HOME') | Should Be $expectedNewJAVAHOME\n        }\n\n        [Environment]::SetEnvironmentVariable('JAVA_HOME', $backupJAVAHOME)\n    }\n\n    Context 'JAVA_HOME is not set and javax is not on path' {\n        Mock Test-Path { $false } -parameterFilter { $Path -eq 'env:Java_HOME' }\n        Mock Get-Command { throw 'error' } -parameterFilter { $Name -eq 'javac' }\n\n        It \"throws an error\" {\n            { Check-JAVA-HOME } | Should Throw\n        }\n    }\n}"
  },
  {
    "path": "Init.ps1",
    "content": "#region Initialization\nfunction Init-Posh-Gvm() {\n    Write-Verbose 'Init posh-gvm'\n\n    $ErrorActionPreference = 'Stop'\n    $ProgressPreference = 'SilentlyContinue'\n\n    Check-JAVA-HOME\n\n    # Check if $Global:PGVM_DIR is available, if not create it\n    if ( !( Test-Path \"$Global:PGVM_DIR\\.meta\" ) ) {\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\.meta\" | Out-Null\n    }\n\n    # Load candidates cache\n    if ( ! (Test-Path $Script:PGVM_CANDIDATES_PATH) ) {\n        Update-Candidates-Cache\n    }\n\n    Init-Candidate-Cache\n\n    #Setup default paths\n    Foreach ( $candidate in $Script:GVM_CANDIDATES ) {\n\t\tif ( !( Test-Path \"$Global:PGVM_DIR\\$candidate\" ) ) {\n\t\t\tNew-Item -ItemType Directory \"$Global:PGVM_DIR\\$candidate\" | Out-Null\n\t\t}\n\n        Set-Env-Candidate-Version $candidate 'current'\n    }\n\n    # Check if we can use unzip (which is much faster)\n    Check-Unzip-On-Path\n}\n\nfunction Check-JAVA-HOME() {\n\t# Check for JAVA_HOME, If not set, try to interfere it\n    if ( ! (Test-Path env:JAVA_HOME) ) {\n        try {\n            [Environment]::SetEnvironmentVariable('JAVA_HOME', (Get-Item (Get-Command 'javac').Path).Directory.Parent.FullName)\n        } catch {\n            throw \"Could not find java, please set JAVA_HOME\"\n        }\n    }\n}\n\nfunction Check-Unzip-On-Path() {\n    try {\n        Get-Command 'unzip.exe' | Out-Null\n        $Script:UNZIP_ON_PATH = $true\n    } catch {\n        $Script:UNZIP_ON_PATH = $false\n    }\n\n    try {\n        Get-Command '7z.exe' | Out-Null\n        $Script:SEVENZ_ON_PATH = $true\n    } catch {\n        $Script:SEVENZ_ON_PATH = $false\n    }\n}\n#endregion\n"
  },
  {
    "path": "LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n"
  },
  {
    "path": "README.md",
    "content": "The code inside of this repository is broken. If you need the functionality of SDKMAN on Windows consider using Docker or WSL.\n"
  },
  {
    "path": "TabExpansion.ps1",
    "content": "﻿# Check if function TabExpansion already exists and backup existing version to\n# prevent breaking other TabExpansion implementations.\n# Taken from posh-git https://github.com/dahlbyk/posh-git/blob/master/GitTabExpansion.ps1#L297\n$tabExpansionBackup = 'PoshGVM_DefaultTabExpansion'\nif (Test-Path Function:\\TabExpansion) {\n    Rename-Item Function:\\TabExpansion $tabExpansionBackup -ErrorAction SilentlyContinue\n}\n\nfunction TabExpansion($line, $lastWord) {\n    $lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart()\n\n    switch -regex ($lastBlock) {\n        # Execute gvm tab expansion for gvm command\n        '^gvm (.*)' { gvmTabExpansion($lastBlock) }\n        # Fall back on existing tab expansion\n        default { if (Test-Path Function:\\$tabExpansionBackup) { & $tabExpansionBackup $line $lastWord } }\n    }\n}\n\n$Script:PGVM_TAB_COMMANDS = @('install','uninstall','rm','list','use','default','current','version','broadcast','help','offline','selfupdate','flush')\nfunction gvmTabExpansion($lastBlock) {\n    if ( !($lastBlock -match '^gvm\\s+(?<cmd>\\S+)?(?<args> .*)?$') ) {\n        return\n    }\n    $command = $Matches['cmd']\n    $arguments = $Matches['args']\n\n    if ( !($arguments) ) {\n        # Try to complete the command\n        return $Script:PGVM_TAB_COMMANDS | Where-Object { $_.StartsWith($command) }\n    }\n\n    $arguments = $arguments.TrimStart()\n    # Help add correct parameters\n    switch -regex ($command) {\n        '^i(nstall)?'    { gvmTabExpandion-Need-Candidate $command $arguments }\n        '^(uninstall|rm)'{ gvmTabExpandion-Need-Candidate $command $arguments }\n        '^(ls|list)'     { gvmTabExpandion-Need-Candidate $command $arguments }\n        '^u(se)?'        { gvmTabExpandion-Need-Candidate $command $arguments }\n        '^d(efault)?'    { gvmTabExpandion-Need-Candidate $command $arguments }\n        '^c(urrent)?'    { gvmTabExpandion-Need-Candidate $command $arguments }\n        '^offline'       { gvmTabExpansion-Offline $arguments }\n        '^flush'         { gvmTabExpansion-Flush $arguments }\n        default          {}\n    }\n}\n\nfunction gvmTabExpandion-Need-Candidate($Command, $LastBlock) {\n    if ( !($LastBlock -match \"^(?<candidate>\\S+)?(?<args> .*)?$\") ) {\n        return\n    }\n    $candidate = $Matches['candidate']\n    $arguments = $Matches['args']\n\n    Init-Candidate-Cache\n\n    if ( !($arguments) ) {\n        # Try to complete the command\n        return $Script:GVM_CANDIDATES | Where-Object { $_.StartsWith($candidate) }\n    }\n\n    if ( !($Script:GVM_CANDIDATES -contains $candidate) ) {\n        return\n    }\n\n    $arguments = $arguments.TrimStart()\n    # Help add correct parameters\n    switch -regex ($command) {\n        #'^i(nstall)?'    { gvmTabExpandion-Need-Version $candidate $arguments }\n        '^(uninstall|rm)'{ gvmTabExpandion-Need-Version $candidate $arguments }\n        '^u(se)?'        { gvmTabExpandion-Need-Version $candidate $arguments }\n        '^d(efault)?'    { gvmTabExpandion-Need-Version $candidate $arguments }\n        default          {}\n    }\n}\n\nfunction gvmTabExpandion-Need-Version($Candidate, $LastBlock) {\n    Get-Installed-Candidate-Version-List $Candidate | Where-Object { $_.StartsWith($LastBlock) }\n}\n\nfunction gvmTabExpansion-Offline($Arguments) {\n    @('enable','disable') | Where-Object { ([string]$_).StartsWith($Arguments) }\n}\n\nfunction gvmTabExpansion-Flush($Arguments) {\n    @('candidates','broadcast','archives','temp') | Where-Object { ([string]$_).StartsWith($Arguments) }\n}\n\nExport-ModuleMember TabExpansion\nExport-ModuleMember gvmTabExpansion"
  },
  {
    "path": "TestUtils.ps1",
    "content": "﻿. .\\Utils.ps1\n\nfunction Mock-Check-Candidate-Grails {\n    Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' }\n}\n\nfunction Mock-Online {\n    Mock Get-Online-Mode { return $true }\n}\n\nfunction Mock-Offline {\n    Mock Get-Online-Mode { return $false }\n}\n\nfunction Mock-Grails-1.1.1-Locally-Available($Available) {\n    if ( $Available ) {\n        Mock Is-Candidate-Version-Locally-Available { return $true }  -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n    } else {\n        Mock Is-Candidate-Version-Locally-Available { return $false }  -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' }\n    }\n}\n\nfunction Mock-Current-Grails-1.2 {\n    Mock Get-Current-Candidate-Version { return 1.2 } -parameterFilter { $Candidate -eq 'grails' }\n}\n\nfunction Mock-No-Current-Grails {\n    Mock Get-Current-Candidate-Version { return $null } -parameterFilter { $Candidate -eq 'grails' }\n}\n\nfunction Mock-Api-Call-Default-Grails-2.2 {\n    Mock Invoke-API-Call { return 2.2 } -parameterFilter { $Path -eq 'candidates/grails/default' }\n}\n\nfunction Mock-Api-Call-Grails-1.1.1-Available($Available) {\n    if ( $Available ) {\n        Mock Invoke-API-Call { return $true } -parameterFilter { $Path -eq 'candidates/grails/1.1.1' }\n    } else {\n        Mock Invoke-API-Call { return $false } -parameterFilter { $Path -eq 'candidates/grails/1.1.1' }\n    }\n}\n\nfunction Mock-PGVM-Dir {\n    $Script:backup_PGVM_DIR = $Global:PGVM_DIR\n    New-Item -ItemType Directory \"TestDrive:.posh-gvm\" | Out-Null\n    $Global:PGVM_DIR = (Get-Item \"TestDrive:.posh-gvm\").FullName\n    New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\" | Out-Null\n}\n\nfunction Reset-PGVM-Dir {\n    $link = \"$Global:PGVM_DIR\\grails\\current\"\n    if ( Test-Path $link ) {\n        (Get-Item $link).Delete()\n    }\n\n    $Global:PGVM_DIR = $Script:backup_PGVM_DIR\n}\n\nfunction Mock-Grails-Home($Version) {\n    $Script:backup_GRAILS_HOME = [System.Environment]::GetEnvironmentVariable('GRAILS_HOME')\n    [System.Environment]::SetEnvironmentVariable('GRAILS_HOME', \"$Global:PGVM_DIR\\grails\\$Version\")\n}\n\nfunction Reset-Grails-Home {\n    [System.Environment]::SetEnvironmentVariable('GRAILS_HOME', $Script:backup_GRAILS_HOME)\n}\n\nfunction Mock-Dispatcher-Test([switch]$Offline) {\n    Mock-PGVM-Dir\n    $Script:GVM_FORCE_OFFLINE = $false\n    $Script:FIRST_RUN = $false\n    if ( !($Offline) ) {\n        Mock Check-Available-Broadcast -verifiable\n        Write-New-Version-Broadcast -verifiable\n    }\n    Mock Init-Candidate-Cache -verifiable\n}\n\nfunction Reset-Dispatcher-Test {\n    Reset-PGVM-Dir\n}"
  },
  {
    "path": "Utils.Tests.ps1",
    "content": "﻿. .\\Utils.ps1\n. .\\TestUtils.ps1\n\nDescribe 'Check-GVM-API-Version' {\n    Context 'API offline' {\n        $Script:GVM_AVAILABLE = $true\n        $Script:GVM_API_NEW_VERSION = $false\n        Mock Get-GVM-API-Version\n        Mock Invoke-API-Call { throw 'error' }  -parameterFilter { $Path -eq 'app/Version' }\n\n        Check-GVM-API-Version\n\n        It 'the error handling set the app in offline mode' {\n            $Script:GVM_AVAILABLE | Should be $false\n        }\n\n        It 'does not informs about new version' {\n            $Script:GVM_API_NEW_VERSION | Should Be $false\n        }\n    }\n\n    Context 'No new version' {\n        $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE\n        $Global:PGVM_AUTO_SELFUPDATE = $true\n        $Script:GVM_API_NEW_VERSION = $false\n\n        Mock Get-GVM-API-Version { 1.2.2 }\n        Mock Invoke-API-Call { 1.2.2 } -parameterFilter { $Path -eq 'app/Version' }\n        Mock Invoke-Self-Update\n\n        Check-GVM-API-Version\n\n        It 'do nothing' {\n            Assert-MockCalled Invoke-Self-Update 0\n        }\n\n        It 'does not informs about new version' {\n            $Script:GVM_API_NEW_VERSION | Should Be $false\n        }\n\n        $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE\n    }\n\n    Context 'New version and no auto selfupdate' {\n        $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE\n        $Global:PGVM_AUTO_SELFUPDATE = $false\n        $Script:GVM_API_NEW_VERSION = $false\n\n        Mock Get-GVM-API-Version { '1.2.2' }\n        Mock Invoke-API-Call { '1.2.3' } -parameterFilter { $Path -eq 'app/Version' }\n\n        Check-GVM-API-Version\n\n        It 'informs about new version' {\n            $Script:GVM_API_NEW_VERSION | Should Be $true\n        }\n\n        It 'write a warning about needed update' {\n            Assert-VerifiableMocks\n        }\n\n        $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE\n    }\n\n    Context 'New version and auto selfupdate' {\n        $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE\n        $Global:PGVM_AUTO_SELFUPDATE = $true\n        $Script:GVM_API_NEW_VERSION = $false\n\n        Mock Get-GVM-API-Version { '1.2.2' }\n        Mock Invoke-API-Call { '1.2.3' } -parameterFilter { $Path -eq 'app/Version' }\n        Mock Invoke-Self-Update -verifiable\n\n        Check-GVM-API-Version\n\n        It 'updates self' {\n            Assert-VerifiableMocks\n        }\n\n        It 'does not informs about new version' {\n            $Script:GVM_API_NEW_VERSION | Should Be $false\n        }\n\n        $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE\n    }\n}\n\nDescribe 'Check-Posh-Gvm-Version' {\n    Context 'No new Version' {\n        $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE\n        $Global:PGVM_AUTO_SELFUPDATE = $false\n        $Script:PGVM_NEW_VERSION = $false\n\n        Mock Is-New-Posh-GVM-Version-Available { $false }\n        Mock Invoke-Self-Update\n\n        Check-Posh-Gvm-Version\n\n        It 'does not update itself' {\n            Assert-MockCalled Invoke-Self-Update -Times 0\n        }\n\n        It 'does not informs about new version' {\n            $Script:PGVM_NEW_VERSION | Should Be $false\n        }\n\n        $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE\n    }\n\n    Context 'New version and no auto selfupdate' {\n        $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE\n        $Global:PGVM_AUTO_SELFUPDATE = $false\n        $Script:PGVM_NEW_VERSION = $false\n\n        Mock Is-New-Posh-GVM-Version-Available { $true }\n        Mock Invoke-Self-Update\n\n        Check-Posh-Gvm-Version\n\n        It 'informs about new version' {\n            $Script:PGVM_NEW_VERSION | Should Be $true\n        }\n\n        It 'does not update itself' {\n            Assert-MockCalled Invoke-Self-Update -Times 0\n        }\n\n        $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE\n    }\n\n    Context 'New version and auto selfupdate' {\n        $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE\n        $Global:PGVM_AUTO_SELFUPDATE = $true\n        $Script:PGVM_NEW_VERSION = $false\n\n        Mock Is-New-Posh-GVM-Version-Available { $true }\n        Mock Invoke-Self-Update -verifiable\n\n        Check-Posh-Gvm-Version\n\n        It 'updates self' {\n            Assert-VerifiableMocks\n        }\n\n        It 'does not informs about new version' {\n            $Script:PGVM_NEW_VERSION | Should Be $false\n        }\n\n        $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE\n    }\n}\n\nDescribe 'Is-New-Posh-GVM-Version-Available' {\n    Context 'New version available' {\n        $Script:PGVM_VERSION_SERVICE = 'blub'\n        $Script:PGVM_VERSION_PATH = 'TestDrive:VERSION.txt'\n        Set-Content $Script:PGVM_VERSION_PATH '1.1.1'\n\n        Mock Invoke-RestMethod { '1.2.1' } -parameterFilter { $Uri -eq 'blub' }\n\n        $result = Is-New-Posh-GVM-Version-Available\n\n        It 'returns $true' {\n            $result | Should Be $true\n        }\n    }\n\n    Context 'No new version available' {\n        $Script:PGVM_VERSION_SERVICE = 'blub'\n        $Script:PGVM_VERSION_PATH = 'TestDrive:VERSION.txt'\n        Set-Content $Script:PGVM_VERSION_PATH '1.1.1'\n\n        Mock Invoke-RestMethod { '1.1.1' } -parameterFilter { $Uri -eq 'blub' }\n\n        $result = Is-New-Posh-GVM-Version-Available\n\n        It 'returns $false' {\n            $result | Should Be $false\n        }\n    }\n\n    Context 'Version service error' {\n        $Script:PGVM_VERSION_SERVICE = 'blub'\n        $Script:PGVM_VERSION_PATH = 'TestDrive:VERSION.txt'\n        Set-Content $Script:PGVM_VERSION_PATH '1.1.1'\n\n        Mock Invoke-RestMethod { throw 'error' } -parameterFilter { $Uri -eq 'blub' }\n\n        $result = Is-New-Posh-GVM-Version-Available\n\n        It 'returns $false' {\n            $result | Should Be $false\n        }\n    }\n}\n\nDescribe 'Get-GVM-API-Version' {\n    Context 'No cached version' {\n        $Script:GVM_API_VERSION_PATH = 'TestDrive:version.txt'\n\n        It 'returns `$null' {\n            Get-GVM-API-Version | Should Be $null\n        }\n    }\n\n    Context 'No cached version' {\n        $Script:GVM_API_VERSION_PATH = 'TestDrive:version.txt'\n        Set-Content $Script:GVM_API_VERSION_PATH '1.1.1'\n\n        It 'returns $null' {\n            Get-GVM-API-Version | Should Be 1.1.1\n        }\n    }\n}\n\nDescribe 'Check-Available-Broadcast' {\n    Context 'Last execution was online, still online' {\n        $Script:GVM_ONLINE = $true\n        $Script:GVM_AVAILABLE = $true\n        Mock Get-GVM-API-Version { '1.2.3' }\n        Mock Invoke-Broadcast-API-Call { 'Broadcast message' }\n        Mock Handle-Broadcast -verifiable -parameterFilter { $Command -eq $null -and $Broadcast -eq 'Broadcast message' }\n        Mock Write-Offline-Broadcast\n        Mock Write-Online-Broadcast\n\n        Check-Available-Broadcast\n\n        It 'does not announce any mode changes' {\n            Assert-MockCalled Write-Offline-Broadcast 0\n            Assert-MockCalled Write-Online-Broadcast 0\n        }\n\n        It 'calls Handle-Broadcast' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Last execution was online, now offline' {\n        $Script:GVM_ONLINE = $true\n        $Script:GVM_AVAILABLE = $false\n        Mock Get-GVM-API-Version { '1.2.4' }\n        Mock Invoke-Broadcast-API-Call { $null }\n        Mock Handle-Broadcast\n        Mock Write-Offline-Broadcast\n        Mock Write-Online-Broadcast\n\n        Check-Available-Broadcast\n\n        It 'does announce offline mode' {\n            Assert-MockCalled Write-Offline-Broadcast 1\n            Assert-MockCalled Write-Online-Broadcast 0\n        }\n\n        It 'does not call Handle-Broadcast' {\n            Assert-MockCalled Handle-Broadcast 0\n        }\n    }\n\n    Context 'Last execution was offline, still offline' {\n        $Script:GVM_ONLINE = $false\n        $Script:GVM_AVAILABLE = $false\n        Mock Get-GVM-API-Version { '1.2.4' }\n        Mock Invoke-Broadcast-API-Call { $null }\n        Mock Handle-Broadcast\n        Mock Write-Offline-Broadcast\n        Mock Write-Online-Broadcast\n\n        Check-Available-Broadcast\n\n        It 'does not announce any mode changes' {\n            Assert-MockCalled Write-Offline-Broadcast 0\n            Assert-MockCalled Write-Online-Broadcast 0\n        }\n\n        It 'does not call Handle-Broadcast' {\n            Assert-MockCalled Handle-Broadcast 0\n        }\n    }\n\n    Context 'Last execution was offline, now online' {\n        $Script:GVM_ONLINE = $false\n        $Script:GVM_AVAILABLE = $true\n        Mock Get-GVM-API-Version { '1.2.5' }\n        Mock Invoke-Broadcast-API-Call { 'Broadcast message' }\n        Mock Handle-Broadcast -verifiable -parameterFilter { $Command -eq $null -and $Broadcast -eq 'Broadcast message' }\n        Mock Write-Offline-Broadcast\n        Mock Write-Online-Broadcast\n\n        Check-Available-Broadcast\n\n        It 'does announce online mode' {\n            Assert-MockCalled Write-Offline-Broadcast 0\n            Assert-MockCalled Write-Online-Broadcast 1\n        }\n\n        It 'calls Handle-Broadcast' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Invoke-Self-Update' {\n    Context 'Selfupdate will be triggered, no force, no new version' {\n        Mock Update-Candidates-Cache -verifiable\n        Mock Write-Output -verifiable\n        Mock Is-New-Posh-GVM-Version-Available { $false }\n        Mock Invoke-Posh-Gvm-Update\n\n        Invoke-Self-Update\n\n        It 'updates the candidate cache' {\n            Assert-VerifiableMocks\n        }\n\n        It 'does not updates itself' {\n            Assert-MockCalled Invoke-Posh-Gvm-Update -Times 0\n        }\n    }\n\n    Context 'Selfupdate will be triggered, no force, new version' {\n        Mock Update-Candidates-Cache -verifiable\n        Mock Write-Output -verifiable\n        Mock Is-New-Posh-GVM-Version-Available { $true }\n        Mock Invoke-Posh-Gvm-Update -verifiable\n\n        Invoke-Self-Update\n\n        It 'updates the candidate cache and version' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Selfupdate will be triggered, force, no new version' {\n        Mock Update-Candidates-Cache -verifiable\n        Mock Write-Output -verifiable\n        Mock Is-New-Posh-GVM-Version-Available { $false }\n        Mock Invoke-Posh-Gvm-Update -verifiable\n\n        Invoke-Self-Update -Force $true\n\n        It 'updates the candidate cache and version' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Check-Candidate-Present checks if candidate parameter is valid' {\n\tIt 'throws an error if no candidate is provided' {\n\t\t{ Check-Candidate-Present } | Should Throw\n\t}\n\n    $Script:GVM_CANDIDATES = @('grails','groovy')\n    It 'throws error if candidate unknown' {\n        { Check-Candidate-Present java } | Should Throw\n    }\n\n    It 'throws no error if candidate known' {\n        { Check-Candidate-Present groovy } | Should Not Throw\n    }\n}\n\nDescribe 'Check-Version-Present checks if version parameter is defined' {\n    It 'throws an error if no candidate is provided' {\n        { Check-Version-Present } | Should Throw\n    }\n\n    It 'throws no error if version provided' {\n        { Check-Version-Present 2.1.3 } | Should Not Throw\n    }\n}\n\nDescribe 'Check-Candidate-Version-Available select or vadidates a version for a candidate' {\n    Context 'When grails version 1.1.1 is locally available' {\n        Mock-Check-Candidate-Grails\n        Mock-Grails-1.1.1-Locally-Available $true\n\n        $result = Check-Candidate-Version-Available grails 1.1.1\n\n        It 'check candidate parameter' {\n            Assert-VerifiableMocks\n        }\n\n        It 'returns the 1.1.1' {\n            $result | Should Be 1.1.1\n        }\n    }\n\n    Context 'When gvm is offline and the provided version is not locally available' {\n        Mock-Check-Candidate-Grails\n        Mock-Offline\n        Mock-Grails-1.1.1-Locally-Available $false\n\n        It 'throws an error' {\n            { Check-Candidate-Version-Available grails 1.1.1 } | Should Throw\n        }\n\n        It 'check candidate parameter' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'When gvm is offline and no version is provided but there is a current version' {\n        Mock-Check-Candidate-Grails\n        Mock-Offline\n        Mock-Current-Grails-1.2\n\n        $result = Check-Candidate-Version-Available grails\n\n        It 'check candidate parameter' {\n            Assert-VerifiableMocks\n        }\n\n        It 'returns the current version' {\n            $result | Should Be 1.2\n        }\n    }\n\n    Context 'When gvm is offline and no version is provided and no current version is defined' {\n        Mock-Check-Candidate-Grails\n        Mock-Offline\n        Mock-No-Current-Grails\n\n        It 'throws an error' {\n            { Check-Candidate-Version-Available grails } | Should Throw\n        }\n\n        It 'check candidate parameter' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'When gvm is online and no version is provided' {\n        Mock-Check-Candidate-Grails\n        Mock-Online\n        Mock-Api-Call-Default-Grails-2.2\n\n        $result = Check-Candidate-Version-Available grails\n\n        It 'the API default is returned' {\n            $result | Should Be 2.2\n        }\n\n        It 'check candidate parameter' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'When gvm is online and the provided version is valid' {\n        Mock-Check-Candidate-Grails\n        Mock-Online\n        Mock-Api-Call-Grails-1.1.1-Available $true\n\n        $result = Check-Candidate-Version-Available grails 1.1.1\n\n        It 'returns the version' {\n            $result | Should Be 1.1.1\n        }\n\n        It 'check candidate parameter' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'When gvm is online and the provided version is invalid' {\n        Mock-Check-Candidate-Grails\n        Mock-Online\n        Mock-Api-Call-Grails-1.1.1-Available $false\n\n        It 'throws an error' {\n            { Check-Candidate-Version-Available grails 1.1.1 } | Should Throw\n        }\n\n        It 'check candidate parameter' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Get-Current-Candidate-Version reads the currently linked version' {\n    Context 'When current is not defined' {\n        Mock-PGVM-Dir\n\n        It 'returns $null if current not defined' {\n            Get-Current-Candidate-Version grails | Should Be $null\n        }\n\n        Reset-PGVM-DIR\n    }\n\n    Context 'When current is defined' {\n        Mock-PGVM-Dir\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\2.2.2\" | Out-Null\n        Set-Junction-Via-Mklink \"$Global:PGVM_DIR\\grails\\current\" \"$Global:PGVM_DIR\\grails\\2.2.2\"\n\n        It 'returns the liked version' {\n            Get-Current-Candidate-Version grails | Should Be 2.2.2\n        }\n\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Get-Env-Candidate-Version reads the version set in $Candidate-Home' {\n    Context 'When GRAILS_HOME is set to a specific version' {\n        Mock-PGVM-Dir\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\2.2.1\" | Out-Null\n        Mock-Grails-Home 2.2.1\n\n        It 'returns the set version' {\n            Get-Env-Candidate-Version grails | Should Be 2.2.1\n        }\n\n        Reset-Grails-Home\n        Reset-PGVM-Dir\n    }\n\n    Context 'When GRAILS_HOME is set to current' {\n        Mock-PGVM-Dir\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\2.2.1\" | Out-Null\n        Set-Junction-Via-Mklink \"$Global:PGVM_DIR\\grails\\current\" \"$Global:PGVM_DIR\\grails\\2.2.1\"\n\n        Mock-Grails-Home current\n\n        It 'returns the version linked to current' {\n            Get-Env-Candidate-Version grails | Should Be 2.2.1\n        }\n\n        Reset-Grails-Home\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Check-Candidate-Version-Locally-Available throws error message if not available' {\n    Context 'Version not available' {\n        Mock-Grails-1.1.1-Locally-Available $false\n        It 'throws an error' {\n            { Check-Candidate-Version-Locally-Available grails 1.1.1 } | Should Throw\n        }\n    }\n\n    Context 'Version is available' {\n        Mock-Grails-1.1.1-Locally-Available $true\n\n        It 'not throws any error' {\n            { Check-Candidate-Version-Locally-Available grails 1.1.1 } | Should Not Throw\n        }\n    }\n}\n\nDescribe 'Is-Candidate-Version-Locally-Available check the path exists' {\n    Context 'No version provided' {\n        it 'returns $false' {\n            Is-Candidate-Version-Locally-Available grails | Should Be $false\n        }\n    }\n\n    Context 'COC path for grails 1.1.1 is missing' {\n        Mock-PGVM-Dir\n\n        it 'returns $false' {\n            Is-Candidate-Version-Locally-Available grails 1.1.1 | Should Be $false\n        }\n\n        Reset-PGVM-Dir\n    }\n\n    Context 'COC path for grails 1.1.1 exists' {\n        Mock-PGVM-Dir\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\1.1.1\" | Out-Null\n\n        it 'returns $true' {\n            Is-Candidate-Version-Locally-Available grails 1.1.1 | Should Be $true\n        }\n\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Get-Installed-Candidate-Version-List' {\n    Context 'Version 1.1, 1.3.7 and 2.2.1 of grails installed' {\n        Mock-PGVM-Dir\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\1.1\" | Out-Null\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\1.3.7\" | Out-Null\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\2.2.1\" | Out-Null\n        Set-Junction-Via-Mklink \"$Global:PGVM_DIR\\grails\\current\" \"$Global:PGVM_DIR\\grails\\2.2.1\"\n\n        It 'returns list of installed versions' {\n            Get-Installed-Candidate-Version-List grails | Should Be 1.1,1.3.7,2.2.1\n        }\n\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Set-Env-Candidate-Version' {\n    Context 'Env-Version of grails is current' {\n        Mock-PGVM-Dir\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\1.3.7\" | Out-Null\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\2.2.1\" | Out-Null\n        Set-Junction-Via-Mklink \"$Global:PGVM_DIR\\grails\\current\" \"$Global:PGVM_DIR\\grails\\2.2.1\"\n        Mock-Grails-Home current\n        $backupPATH = $env:Path\n\n        Set-Env-Candidate-Version grails 1.3.7\n\n        It 'sets GRAILS_HOME' {\n            $env:GRAILS_HOME -eq \"$Global:PGVM_DIR\\grails\\1.3.7\"\n        }\n\n        It 'extends the Path' {\n            $env:Path -eq \"$Global:PGVM_DIR\\grails\\1.3.7\\bin\"\n        }\n\n        $env:Path = $backupPATH\n        Reset-Grails-Home\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Set-Linked-Candidate-Version' {\n    Context 'In a initialized PGVM-Dir' {\n        Mock-PGVM-Dir\n        Mock Set-Junction-Via-Mklink -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' }\n\n        Set-Linked-Candidate-Version grails 2.2.1\n\n        It 'calls Set-Junction-Via-Mklink with the correct paths' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Set-Junction-Via-Mklink' {\n    Context 'No junction for the link-path exists' {\n        Mock-PGVM-Dir\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\1.3.7\" | Out-Null\n\n        Set-Junction-Via-Mklink \"$Global:PGVM_DIR\\grails\\bla\" \"$Global:PGVM_DIR\\grails\\1.3.7\"\n\n        It 'creates a junction to the target location' {\n            (Get-Junction-Target \"$Global:PGVM_DIR\\grails\\bla\").FullName -eq \"$Global:PGVM_DIR\\grails\\1.3.7\" \n        }\n\n        (Get-Item \"$Global:PGVM_DIR\\grails\\bla\").Delete()\n        Reset-PGVM-Dir\n    }\n\n    Context 'A Junction for the link-path exists' {\n        Mock-PGVM-Dir\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\1.3.7\" | Out-Null\n        New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\1.3.8\" | Out-Null\n        Set-Junction-Via-Mklink \"$Global:PGVM_DIR\\grails\\bla\" \"$Global:PGVM_DIR\\grails\\1.3.8\"\n        Set-Junction-Via-Mklink \"$Global:PGVM_DIR\\grails\\bla\" \"$Global:PGVM_DIR\\grails\\1.3.7\"\n\n        It 'creates a junction to the target location without errors' {\n            (Get-Junction-Target \"$Global:PGVM_DIR\\grails\\bla\").FullName -eq \"$Global:PGVM_DIR\\grails\\1.3.7\"\n        }\n\n        (Get-Item \"$Global:PGVM_DIR\\grails\\bla\").Delete()\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Get-Junction-Target' {\n    Context 'Provided path is a junction' {\n      Mock-PGVM-Dir\n      New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\1.3.7\" | Out-Null\n\n      Set-Junction-Via-Mklink \"$Global:PGVM_DIR\\grails\\bla\" \"$Global:PGVM_DIR\\grails\\1.3.7\"\n\n      It 'returns the item of the junction correctly' {\n          (Get-Junction-Target \"$Global:PGVM_DIR\\grails\\bla\").FullName -eq \"$Global:PGVM_DIR\\grails\\1.3.7\"\n      }\n\n      (Get-Item \"$Global:PGVM_DIR\\grails\\bla\").Delete()\n      Reset-PGVM-Dir\n    }\n\n    Context 'Provided path is no junction' {\n      Mock-PGVM-Dir\n      New-Item -ItemType Directory \"$Global:PGVM_DIR\\grails\\1.3.7\" | Out-Null\n\n      It 'returns correctly a null object without exception' {\n          Get-Junction-Target \"$Global:PGVM_DIR\\grails\\1.3.7\" -eq $null\n      }\n\n      Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Get-Online-Mode check the state variables for GVM-API availablitiy and for force offline mode' {\n    Context 'GVM-Api unavailable but may be connected' {\n        $Script:GVM_AVAILABLE = $false\n        $Script:GVM_FORCE_OFFLINE = $false\n\n        It 'returns $false' {\n            Get-Online-Mode | Should Be $false\n        }\n    }\n\n    Context 'GVM-Api unavailable and may not be connected' {\n        $Script:GVM_AVAILABLE = $false\n        $Script:GVM_FORCE_OFFLINE = $true\n\n        It 'returns $false' {\n            Get-Online-Mode | Should Be $false\n        }\n    }\n\n    Context 'GVM-Api is available and may not be connected' {\n        $Script:GVM_AVAILABLE = $true\n        $Script:GVM_FORCE_OFFLINE = $true\n\n        It 'returns $false' {\n            Get-Online-Mode | Should Be $false\n        }\n    }\n\n    Context 'GVM-Api is available and may be connected' {\n        $Script:GVM_AVAILABLE = $true\n        $Script:GVM_FORCE_OFFLINE = $false\n\n        It 'returns $true' {\n            Get-Online-Mode | Should Be $true\n        }\n    }\n}\n\n\nDescribe 'Check-Online-Mode throws an error when offline' {\n    Context 'Offline' {\n        Mock-Offline\n\n        It 'throws an error' {\n            { Check-Online-Mode } | Should Throw\n        }\n    }\n\n    Context 'Online' {\n        Mock-Online\n\n        It 'throws no error' {\n            { Check-Online-Mode } | Should Not Throw\n        }\n    }\n}\n\nDescribe 'Invoke-API-Call helps doing calls to the GVM-API' {\n    Context 'Successful API call only with API path' {\n        $Script:PGVM_SERVICE = 'blub'\n        Mock Invoke-RestMethod { 'called' } -parameterFilter { $Uri -eq 'blub/na/rock' }\n\n        It 'returns the result from Invoke-RestMethod' {\n            Invoke-API-Call 'na/rock' | Should Be 'called'\n        }\n    }\n\n    Context 'Failed API call only with API path' {\n        $Script:PGVM_SERVICE = 'blub'\n        $Script:GVM_AVAILABLE = $true\n        Mock Invoke-RestMethod { throw 'error' } -parameterFilter { $Uri -eq 'blub/na/rock' }\n        Mock Check-Online-Mode -verifiable\n\n        Invoke-API-Call 'na/rock'\n\n        It 'sets GVM_AVAILABLE to false' {\n            $Script:GVM_AVAILABLE | Should Be $false\n        }\n\n        It 'calls Check-Online-Mode which throws an error' {\n            Assert-VerifiableMocks\n        }\n    }\n\n    Context 'Failed API call with API path and IgnoreFailure' {\n        $Script:PGVM_SERVICE = 'blub'\n        $Script:GVM_AVAILABLE = $true\n        Mock Invoke-RestMethod { throw 'error' } -parameterFilter { $Uri -eq 'blub/na/rock' }\n        Mock Check-Online-Mode\n\n        Invoke-API-Call 'na/rock' -IgnoreFailure\n\n        It 'sets GVM_AVAILABLE to false' {\n            $Script:GVM_AVAILABLE | Should Be $false\n        }\n\n        It 'do not call Check-Online-Mode' {\n            Assert-MockCalled Check-Online-Mode 0\n        }\n    }\n\n    Context 'Successful API call with API path and FilePath' {\n        $Script:PGVM_SERVICE = 'blub'\n        Mock Invoke-RestMethod -verifiable -parameterFilter { $Uri -eq 'blub/na/rock' -and $OutFile -eq 'TestDrive:a.txt' }\n\n        Invoke-API-Call 'na/rock' TestDrive:a.txt\n\n        It 'calls Invoke-RestMethod with file path' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Cleanup-Directory' {\n    Context 'Directory with subdirectories and files' {\n        New-Item -ItemType Directory TestDrive:bla | Out-Null\n        New-Item -ItemType Directory TestDrive:bla\\a | Out-Null\n        New-Item -ItemType Directory TestDrive:bla\\b | Out-Null\n        New-Item -ItemType File TestDrive:bla\\c | Out-Null\n        New-Item -ItemType File TestDrive:bla\\a\\a | Out-Null\n\n        Mock Write-Output -verifiable -parameterFilter { $InputObject -eq '2 archive(s) flushed, freeing 0 MB' }\n\n        Cleanup-Directory TestDrive:bla\n\n        It 'Cleans the Test-Path file' {\n            Test-Path TestDrive:bla | Should Be $False\n        }\n\n        It 'Write info to host' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Handle-Broadcast' {\n    Context 'Cache broadcast message different than new broadcast' {\n        Mock-PGVM-Dir\n        $Script:PGVM_BROADCAST_PATH = \"$Global:PGVM_DIR\\broadcast.txt\"\n        Set-Content $Script:PGVM_BROADCAST_PATH 'Old Broadcast message'\n        Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'New Broadcast message' }\n\n        Handle-Broadcast list 'New Broadcast message'\n\n        It 'outputs the broadcast message' {\n            Assert-VerifiableMocks\n        }\n\n        It 'sets the new broadcast message in file' {\n            Get-Content $Script:PGVM_BROADCAST_PATH | Should Be 'New Broadcast message'\n        }\n\n\n        Reset-PGVM-Dir\n    }\n\n    Context 'No cached broadcast message' {\n        Mock-PGVM-Dir\n\n        $Script:PGVM_BROADCAST_PATH = \"$Global:PGVM_DIR\\broadcast.txt\"\n        Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'New Broadcast message' }\n\n        Handle-Broadcast list 'New Broadcast message'\n\n        It 'outputs the broadcast message' {\n            Assert-VerifiableMocks\n        }\n\n        It 'sets the new broadcast message in file' {\n            Get-Content $Script:PGVM_BROADCAST_PATH | Should Be 'New Broadcast message'\n        }\n\n        Reset-PGVM-Dir\n    }\n\n    Context 'b do not print the new broadcast message' {\n        Mock-PGVM-Dir\n\n        $Script:PGVM_BROADCAST_PATH = \"$Global:PGVM_DIR\\broadcast.txt\"\n        Mock Write-Output -verifiable\n\n        Handle-Broadcast b 'New Broadcast message'\n\n        It 'no Broadcast' {\n            Assert-MockCalled Write-Output 0\n        }\n\n        It 'sets the new broadcast message in file' {\n            Test-Path $Script:PGVM_BROADCAST_PATH | Should Be $false\n        }\n\n        Reset-PGVM-Dir\n    }\n\n    Context 'Broadcast do nOt print the new broadcast message' {\n        Mock-PGVM-Dir\n\n        $Script:PGVM_BROADCAST_PATH = \"$Global:PGVM_DIR\\broadcast.txt\"\n        Mock Write-Output -verifiable\n\n        Handle-Broadcast broadcast 'New Broadcast message'\n\n        It 'no Broadcast' {\n            Assert-MockCalled Write-Output 0\n        }\n\n        It 'sets the new broadcast message in file' {\n            Test-Path $Script:PGVM_BROADCAST_PATH | Should Be $false\n        }\n\n        Reset-PGVM-Dir\n    }\n\n    Context 'selfupdate do not print the new broadcast message' {\n        Mock-PGVM-Dir\n\n        $Script:PGVM_BROADCAST_PATH = \"$Global:PGVM_DIR\\broadcast.txt\"\n        Mock Write-Output -verifiable\n\n        Handle-Broadcast selfupdate 'New Broadcast message'\n\n        It 'no Broadcast' {\n            Assert-MockCalled Write-Output 0\n        }\n\n        It 'sets the new broadcast message in file' {\n            Test-Path $Script:PGVM_BROADCAST_PATH | Should Be $false\n        }\n\n        Reset-PGVM-Dir\n    }\n\n    Context 'flush do not print the new broadcast message' {\n        Mock-PGVM-Dir\n\n        $Script:PGVM_BROADCAST_PATH = \"$Global:PGVM_DIR\\broadcast.txt\"\n        Mock Write-Output -verifiable\n\n        Handle-Broadcast flush 'New Broadcast message'\n\n        It 'no Broadcast' {\n            Assert-MockCalled Write-Output 0\n        }\n\n        It 'sets the new broadcast message in file' {\n            Test-Path $Script:PGVM_BROADCAST_PATH | Should Be $false\n        }\n\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Init-Candidate-Cache' {\n    Context 'Candidate cache file does not exists' {\n        Mock-PGVM-Dir\n        $Script:PGVM_CANDIDATES_PATH = \"$Global:PGVM_DIR\\candidates.txt\"\n\n        It 'throws an error' {\n            { Init-Candidate-Cache } | Should Throw\n        }\n\n        Reset-PGVM-Dir\n    }\n\n    Context 'Candidate cache file does exists' {\n        Mock-PGVM-Dir\n        $Script:PGVM_CANDIDATES_PATH = \"$Global:PGVM_DIR\\candidates.txt\"\n        Set-Content $Script:PGVM_CANDIDATES_PATH 'grails,groovy,test'\n        $Script:GVM_CANDIDATES = $null\n\n        Init-Candidate-Cache\n\n        It 'sets `$Script:GVM_CANDIDATES' {\n            $Script:GVM_CANDIDATEs | Should Be grails,groovy,test\n        }\n\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Update-Candidate-Cache' {\n    Context 'Checks online mode and than get version and candidates from api' {\n        Mock-PGVM-Dir\n\n        $Script:GVM_API_VERSION_PATH = \"$Global:PGVM_DIR\\version.txt\"\n        $Script:PGVM_CANDIDATES_PATH = \"$Global:PGVM_DIR\\candidates.txt\"\n\n        Mock Check-Online-Mode -verifiable\n        Mock Invoke-API-Call -verifiable -parameterFilter { $Path -eq 'app/version' -and $FileTarget -eq \"$Global:PGVM_DIR\\version.txt\" }\n        Mock Invoke-API-Call -verifiable -parameterFilter { $Path -eq 'candidates' -and $FileTarget -eq \"$Global:PGVM_DIR\\candidates.txt\" }\n\n        Update-Candidates-Cache\n\n        It 'calls the Check-Online-Mode and two API paths' {\n            Assert-VerifiableMocks\n        }\n\n        Reset-PGVM-Dir\n    }\n}\n\nDescribe 'Write-Offline-Version-List' {\n    Context 'no versions of grails installed' {\n        Mock Write-Output\n        Mock Get-Current-Candidate-Version { $null } -parameterFilter { $Candidate -eq 'grails' }\n        Mock Get-Installed-Candidate-Version-List { $null } -parameterFilter { $Candidate -eq 'grails' }\n\n        Write-Offline-Version-List grails\n\n        It 'Outputs 11 lines' {\n            Assert-MockCalled Write-Output 9\n        }\n    }\n\n    Context 'Three versions of grails installed' {\n        Mock Write-Output\n        Mock Get-Current-Candidate-Version { 1.1.1 } -parameterFilter { $Candidate -eq 'grails' }\n        Mock Get-Installed-Candidate-Version-List { 1.1.1,2.2.2,2.3.0 } -parameterFilter { $Candidate -eq 'grails' }\n\n        Write-Offline-Version-List grails\n\n        It 'Outputs 11 lines' {\n            Assert-MockCalled Write-Output 11\n        }\n    }\n}\n\nDescribe 'Write-Version-List' {\n    Context 'Three versions of grails installed' {\n        Mock Write-Output\n        Mock Get-Current-Candidate-Version { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' }\n        Mock Get-Installed-Candidate-Version-List { return '1.1.1','2.2.2','2.3.0' } -parameterFilter { $Candidate -eq 'grails' }\n        Mock Invoke-API-Call { 'bla' } -parameterFilter { $Path -eq 'candidates/grails/list?platform=posh&current=1.1.1&installed=1.1.1,2.2.2,2.3.0' }\n\n        Write-Version-List grails\n\n        It 'writes to host' {\n            Assert-MockCalled Write-Output 1\n        }\n    }\n}\n\nDescribe 'Install-Local-Version' {\n    Context 'LocalPath is no directory' {\n        New-Item -ItemType File TestDrive:a.txt | Out-Null\n\n        It 'throws an error' {\n            { Install-Local-Version grails snapshot TestDrive:a.txt } | Should Throw\n        }\n    }\n\n    Context 'LocalPath is valid' {\n        New-Item -ItemType Directory TestDrive:Snapshot | Out-Null\n        Mock Write-Output\n        Mock Set-Junction-Via-Mklink -verifiable -parameterFilter { $Link -eq \"$Global:PGVM_DIR\\grails\\snapshot\" -and $Target -eq 'TestDrive:Snapshot' }\n\n        Install-Local-Version grails snapshot TestDrive:Snapshot\n\n        It 'creates junction for candidate version' {\n            Assert-VerifiableMocks\n        }\n    }\n}\n\nDescribe 'Install-Remote-Version' {\n    Context 'Install of a valid version without local archive' {\n        Mock-PGVM-Dir\n\n        Mock Write-Output\n        Mock Check-Online-Mode -verifiable\n        $Script:PGVM_SERVICE = 'foobar'\n        $Script:PGVM_ARCHIVES_PATH = \"$Global:PGVM_DIR\\archives\"\n        $Script:PGVM_TEMP_PATH = \"$Global:PGVM_DIR\\temp\"\n        $testFilePath = \"$PSScriptRoot\\test\\grails-1.3.9.zip\"\n\n        Mock Download-File -verifiable { Copy-Item $testFilePath \"$Script:PGVM_ARCHIVES_PATH\\grails-1.3.9.zip\" } -parameterFilter { $Url -eq 'foobar/download/grails/1.3.9?platform=posh' -and $TargetFile -eq \"$Script:PGVM_ARCHIVES_PATH\\grails-1.3.9.zip\" }\n\n        Install-Remote-Version grails 1.3.9\n\n        It 'downloads the archive' {\n            Assert-VerifiableMocks\n        }\n\n        It 'install it correctly' {\n            Test-Path \"$Global:PGVM_DIR\\grails\\1.3.9\\bin\\grails\" | Should be $true\n        }\n\n        Reset-PGVM-DIR\n    }\n\n    Context 'Install of a valid version with local archive' {\n        Mock-PGVM-Dir\n\n        Mock Write-Output\n        Mock Download-File\n\n        $Script:PGVM_ARCHIVES_PATH = \"$Global:PGVM_DIR\\archives\"\n        $Script:PGVM_TEMP_PATH = \"$Global:PGVM_DIR\\temp\"\n        New-Item -ItemType Directory $Script:PGVM_ARCHIVES_PATH | Out-Null\n        Copy-Item \"$PSScriptRoot\\test\\grails-1.3.9.zip\" \"$Script:PGVM_ARCHIVES_PATH\\grails-1.3.9.zip\"\n\n        Install-Remote-Version grails 1.3.9\n\n        It 'does not download the archive again' {\n            Assert-MockCalled Download-File 0\n        }\n\n        It 'install it correctly' {\n            Test-Path \"$Global:PGVM_DIR\\grails\\1.3.9\\bin\\grails\" | Should be $true\n        }\n\n        Reset-PGVM-DIR\n    }\n\n    Context 'Install of a currupt archive' {\n        Mock-PGVM-Dir\n\n        Mock Write-Output\n        Mock Download-File\n\n        $Script:PGVM_ARCHIVES_PATH = \"$Global:PGVM_DIR\\archives\"\n        $Script:PGVM_TEMP_PATH = \"$Global:PGVM_DIR\\temp\"\n        New-Item -ItemType Directory $Script:PGVM_ARCHIVES_PATH | Out-Null\n        Copy-Item \"$PSScriptRoot\\test\\grails-2.2.2.zip\" \"$Script:PGVM_ARCHIVES_PATH\\grails-2.2.2.zip\"\n\n        It 'fails because of no unziped files' {\n            {  Install-Remote-Version grails 2.2.2 } | Should Throw\n        }\n\n        It 'does not download the archive again' {\n            Assert-MockCalled Download-File 0\n        }\n\n        Reset-PGVM-DIR\n    }\n}\n"
  },
  {
    "path": "Utils.ps1",
    "content": "﻿function Write-Offline-Broadcast() {\n    Write-Output @\"\n==== BROADCAST =================================================================\n\nOFFLINE MODE ENABLED! Some functionality is now disabled.\n\n================================================================================\n\"@\n}\n\nfunction Write-Online-Broadcast() {\n    Write-Output @\"\n==== BROADCAST =================================================================\n\nONLINE MODE RE-ENABLED! All functionality now restored.\n\n================================================================================\n\n\"@\n}\n\nfunction Write-New-Version-Broadcast() {\n    if ( $Script:GVM_API_NEW_VERSION -or $Script:PGVM_NEW_VERSION ) {\nWrite-Output @\"\n==== UPDATE AVAILABLE ==========================================================\n\nA new version is available. Please consider to execute:\n\n    gvm selfupdate\n\n================================================================================\n\"@\n    }\n}\n\nfunction Check-GVM-API-Version() {\n    Write-Verbose 'Checking GVM-API version'\n    try {\n        $apiVersion = Get-GVM-API-Version\n        $gvmRemoteVersion = Invoke-API-Call \"app/version\"\n\n        if ( $gvmRemoteVersion -gt $apiVersion) {\n            if ( $Global:PGVM_AUTO_SELFUPDATE ) {\n                Invoke-Self-Update\n            } else {\n                $Script:GVM_API_NEW_VERSION = $true\n            }\n        }\n    } catch {\n        $Script:GVM_AVAILABLE = $false\n    }\n}\n\nfunction Check-Posh-Gvm-Version() {\n    Write-Verbose 'Checking posh-gvm version'\n    if ( Is-New-Posh-GVM-Version-Available ) {\n        if ( $Global:PGVM_AUTO_SELFUPDATE ) {\n            Invoke-Self-Update\n        } else {\n            $Script:PGVM_NEW_VERSION = $true\n        }\n    }\n}\n\nfunction Get-Posh-Gvm-Version() {\n    return Get-Content $Script:PGVM_VERSION_PATH\n}\n\nfunction Is-New-Posh-GVM-Version-Available() {\n    try {\n        $localVersion = (Get-Posh-Gvm-Version).Trim()\n        $currentVersion = (Invoke-RestMethod $Script:PGVM_VERSION_SERVICE).Trim()\n\n        Write-Verbose \"posh-gvm version check $currentVersion > $localVersion = $($currentVersion -gt $localVersion)\"\n\n        return ( $currentVersion -gt $localVersion )\n    } catch {\n        return $false\n    }\n}\n\nfunction Get-GVM-API-Version() {\n\tif ( !(Test-Path $Script:GVM_API_VERSION_PATH) ) {\n\t\treturn $null\n\t}\n    return Get-Content $Script:GVM_API_VERSION_PATH\n}\n\nfunction Check-Available-Broadcast($Command) {\n    $version = Get-GVM-API-Version\n    if ( !( $version ) ) {\n        return\n    }\n\n    $liveBroadcast = Invoke-Broadcast-API-Call\n\n\tWrite-Verbose \"Online-Mode: $Script:GVM_AVAILABLE\"\n\n\tif ( $Script:GVM_ONLINE -and !($Script:GVM_AVAILABLE) ) {\n\t\tWrite-Offline-Broadcast\n\t} elseif ( !($Script:GVM_ONLINE) -and $Script:GVM_AVAILABLE ) {\n\t\tWrite-Online-Broadcast\n\t}\n\t$Script:GVM_ONLINE = $Script:GVM_AVAILABLE\n\n\tif ( $liveBroadcast ) {\n\t\tHandle-Broadcast $Command $liveBroadcast\n\t}\n}\n\nfunction Invoke-Broadcast-API-Call {\n    try {\n        $target = \"$Script:PGVM_BROADCAST_SERVICE/broadcast/latest\"\n        Write-Verbose \"Broadcast API call to: $target\"\n        return Invoke-RestMethod $target\n    } catch {\n        Write-Verbose \"Could not reached broadcast API\"\n        $Script:GVM_AVAILABLE = $false\n        return $null\n    }\n}\n\nfunction Invoke-Self-Update($Force) {\n    Write-Verbose 'Perform Invoke-Self-Update'\n    Write-Output 'Update list of available candidates...'\n    Update-Candidates-Cache\n    $Script:GVM_API_NEW_VERSION = $false\n    if ( $Force ) {\n        Invoke-Posh-Gvm-Update\n    } else {\n        if ( Is-New-Posh-GVM-Version-Available ) {\n            Invoke-Posh-Gvm-Update\n        }\n    }\n    $Script:PGVM_NEW_VERSION = $false\n}\n\nfunction Invoke-Posh-Gvm-Update {\n    Write-Output 'Update posh-gvm...'\n    . \"$psScriptRoot\\GetPoshGvm.ps1\"\n}\n\nfunction Check-Candidate-Present($Candidate) {\n    if ( !($Candidate) ) {\n        throw 'No candidate provided.'\n    }\n\n    if ( !($Script:GVM_CANDIDATES -contains $Candidate) ) {\n        throw \"Stop! $Candidate is no valid candidate!\"\n    }\n}\n\nfunction Check-Version-Present($Version) {\n    if ( !($Version)) {\n        throw 'No version provided.'\n    }\n}\n\nfunction Check-Candidate-Version-Available($Candidate, $Version) {\n    Check-Candidate-Present $Candidate\n\n    $UseDefault = $false\n    if ( !($Version) ) {\n        Write-Verbose 'No version provided. Fallback to default version!'\n        $UseDefault = $true\n    }\n\n    # Check locally\n    elseif ( Is-Candidate-Version-Locally-Available $Candidate $Version ) {\n        return $Version\n    }\n\n    # Check if offline\n    if ( ! (Get-Online-Mode) ) {\n        if ( $UseDefault ) {\n            $Version = Get-Current-Candidate-Version $Candidate\n            if ( $Version ) {\n                return $Version\n            } else {\n                throw \"Stop! No local default version for $Candidate and in offline mode.\"\n            }\n        }\n\n        throw \"Stop! $Candidate $Version is not available in offline mode.\"\n    }\n\n    if ( $UseDefault ) {\n        Write-Verbose 'Try to get default version from remote'\n        return Invoke-API-Call \"candidates/$Candidate/default\"\n    }\n\n    $VersionAvailable = Invoke-API-Call \"candidates/$Candidate/$Version\"\n\n    if ( $VersionAvailable -eq 'valid' ) {\n        return $Version\n    } else {\n        throw \"Stop! $Version is not a valid $Candidate version.\"\n    }\n}\n\nfunction Get-Current-Candidate-Version($Candidate) {\n    $currentLink = \"$Global:PGVM_DIR\\$Candidate\\current\"\n\n    $targetItem = Get-Junction-Target $currentLink\n\n    if ($targetItem) {\n        return $targetItem.Name\n    }\n\n    return $null\n}\n\nfunction Get-Junction-Target($linkPath) {\n    if ( Test-Path $linkPath ) {\n        try {\n            $linkItem = Get-Item $linkPath\n\n            if (Get-Member -InputObject $linkItem -Name \"ReparsePoint\") {\n                return (Get-Item $linkItem.ReparsePoint.Target)\n            }\n\n            if (Get-Member -InputObject $linkItem -Name \"Target\") {\n                return (Get-Item $linkItem.Target)\n            }\n        } catch {\n            return $null\n        }\n    }\n\n    return $null\n}\n\nfunction Get-Env-Candidate-Version($Candidate) {\n    $envLink = [System.Environment]::GetEnvironmentVariable(([string]$Candidate).ToUpper() + \"_HOME\")\n\n    if ( $envLink -match '(.*)current$' ) {\n        Get-Current-Candidate-Version $Candidate\n    } else {\n        return (Get-Item $envLink).Name\n    }\n}\n\nfunction Check-Candidate-Version-Locally-Available($Candidate, $Version) {\n    if ( !(Is-Candidate-Version-Locally-Available $Candidate $Version) ) {\n        throw \"Stop! $Candidate $Version is not installed.\"\n    }\n}\n\nfunction Is-Candidate-Version-Locally-Available($Candidate, $Version) {\n    if ( $Version ) {\n        return Test-Path \"$Global:PGVM_DIR\\$Candidate\\$Version\"\n    } else {\n        return $false\n    }\n}\n\nfunction Get-Installed-Candidate-Version-List($Candidate) {\n    return Get-ChildItem \"$Global:PGVM_DIR\\$Candidate\" | ?{ $_.PSIsContainer -and $_.Name -ne 'current' } | Foreach { $_.Name }\n}\n\nfunction Set-Env-Candidate-Version($Candidate, $Version) {\n    $candidateEnv = ([string]$candidate).ToUpper() + \"_HOME\"\n    $candidateDir = \"$Global:PGVM_DIR\\$candidate\"\n    $candidateHome = \"$candidateDir\\$Version\"\n    $candidateBin = \"$candidateHome\\bin\"\n\n    if ( !([Environment]::GetEnvironmentVariable($candidateEnv) -eq $candidateHome) ) {\n        [Environment]::SetEnvironmentVariable($candidateEnv, $candidateHome)\n    }\n\n    $env:PATH = \"$candidateBin;$env:PATH\"\n}\n\nfunction Set-Linked-Candidate-Version($Candidate, $Version) {\n    $Link = \"$Global:PGVM_DIR\\$Candidate\\current\"\n    $Target = \"$Global:PGVM_DIR\\$Candidate\\$Version\"\n    Set-Junction-Via-Mklink $Link $Target\n}\n\nfunction Set-Junction-Via-Mklink($Link, $Target) {\n    if ( Test-Path $Link ) {\n        (Get-Item $Link).Delete()\n    }\n\n    Invoke-Expression -Command \"cmd.exe /c mklink /J '$Link' '$Target'\" | Out-Null\n}\n\nfunction Get-Online-Mode() {\n    return $Script:GVM_AVAILABLE -and ! ($Script:GVM_FORCE_OFFLINE)\n}\n\nfunction Check-Online-Mode() {\n    if ( ! (Get-Online-Mode) ) {\n        throw 'This command is not available in offline mode.'\n    }\n}\n\nfunction Invoke-API-Call([string]$Path, [string]$FileTarget, [switch]$IgnoreFailure) {\n    try {\n        $target = \"$Script:PGVM_SERVICE/$Path\"\n\n        if ( $FileTarget ) {\n            return Invoke-RestMethod $target -OutFile $FileTarget\n        }\n\n        return Invoke-RestMethod $target\n    } catch {\n        $Script:GVM_AVAILABLE = $false\n        if ( ! ($IgnoreFailure) ) {\n            Check-Online-Mode\n        } else {\n\t\t\treturn $null\n\t\t}\n    }\n}\n\nfunction Cleanup-Directory($Path) {\n    $dirStats = Get-ChildItem $Path -Recurse | Measure-Object -property length -sum\n    Remove-Item -Force -Recurse $Path\n    $count = $dirStats.Count\n    $size = $dirStats.Sum/(1024*1024)\n    Write-Output \"$count archive(s) flushed, freeing $size MB\"\n}\n\nfunction Handle-Broadcast($Command, $Broadcast) {\n    $oldBroadcast = $null\n    if (Test-Path $Script:PGVM_BROADCAST_PATH) {\n        $oldBroadcast = (Get-Content $Script:PGVM_BROADCAST_PATH) -join \"`n\"\n        Write-Verbose 'Old broadcast message loaded'\n    }\n\n    if ($oldBroadcast -ne $Broadcast -and !($Command -match 'b(roadcast)?') -and $Command -ne 'selfupdate' -and $Command -ne 'flush' ) {\n        Write-Verbose 'Showing the new broadcast message'\n        Set-Content $Script:PGVM_BROADCAST_PATH $Broadcast\n        Write-Output $Broadcast\n    }\n}\n\nfunction Init-Candidate-Cache() {\n    if ( !(Test-Path $Script:PGVM_CANDIDATES_PATH) ) {\n        throw 'Can not retrieve list of candidates'\n    }\n\n    $Script:GVM_CANDIDATES = (Get-Content $Script:PGVM_CANDIDATES_PATH).Split(',')\n    Write-Verbose \"Available candidates: $Script:GVM_CANDIDATES\"\n}\n\nfunction Update-Candidates-Cache() {\n    Write-Verbose 'Update candidates-cache from GVM-API'\n    Check-Online-Mode\n    Invoke-Api-Call 'app/version' $Script:GVM_API_VERSION_PATH\n    Invoke-API-Call 'candidates' $Script:PGVM_CANDIDATES_PATH\n}\n\nfunction Write-Offline-Version-List($Candidate) {\n    Write-Verbose 'Get version list from directory'\n\n    Write-Output '------------------------------------------------------------'\n    Write-Output \"Offline Mode: only showing installed ${Candidate} versions\"\n    Write-Output '------------------------------------------------------------'\n    Write-Output ''\n\n    $current = Get-Current-Candidate-Version $Candidate\n    $versions = Get-Installed-Candidate-Version-List $Candidate\n\n    if ($versions) {\n        foreach ($version in $versions) {\n            if ($version -eq $current) {\n                Write-Output \" > $version\"\n            } else {\n                Write-Output \" * $version\"\n            }\n        }\n    } else {\n        Write-Output '    None installed!'\n    }\n\n    Write-Output '------------------------------------------------------------'\n\tWrite-Output '* - installed                                               '\n\tWrite-Output '> - currently in use                                        '\n\tWrite-Output '------------------------------------------------------------'\n}\n\nfunction Write-Version-List($Candidate) {\n    Write-Verbose 'Get version list from API'\n\n    $current = Get-Current-Candidate-Version $Candidate\n    $versions = (Get-Installed-Candidate-Version-List $Candidate) -join ','\n    Invoke-API-Call \"candidates/$Candidate/list?platform=posh&current=$current&installed=$versions\" | Write-Output\n}\n\nfunction Install-Local-Version($Candidate, $Version, $LocalPath) {\n    $dir = Get-Item $LocalPath\n\n    if ( !(Test-Path $dir -PathType Container) ) {\n        throw \"Local installation path $LocalPath is no directory\"\n    }\n\n    Write-Output \"Linking $Candidate $Version to $LocalPath\"\n    $link = \"$Global:PGVM_DIR\\$Candidate\\$Version\"\n    Set-Junction-Via-Mklink $link $LocalPath\n    Write-Output \"Done installing!\"\n}\n\nfunction Install-Remote-Version($Candidate, $Version) {\n\n    if ( !(Test-Path $Script:PGVM_ARCHIVES_PATH) ) {\n        New-Item -ItemType Directory $Script:PGVM_ARCHIVES_PATH | Out-Null\n    }\n\n    $archive = \"$Script:PGVM_ARCHIVES_PATH\\$Candidate-$Version.zip\"\n    if ( Test-Path $archive ) {\n        Write-Output \"Found a previously downloaded $Candidate $Version archive. Not downloading it again...\"\n    } else {\n\t\tCheck-Online-Mode\n        Write-Output \"`nDownloading: $Candidate $Version`n\"\n        Download-File \"$Script:PGVM_SERVICE/download/$Candidate/$Version`?platform=posh\" $archive\n    }\n\n    Write-Output \"Installing: $Candidate $Version\"\n\n    # create temp dir if necessary\n    if ( !(Test-Path $Script:PGVM_TEMP_PATH) ) {\n        New-Item -ItemType Directory $Script:PGVM_TEMP_PATH | Out-Null\n    }\n\n    # unzip downloaded archive\n    Unzip-Archive $archive $Script:PGVM_TEMP_PATH\n\n\t# check if unzip successfully\n\tif ( !(Test-Path \"$Script:PGVM_TEMP_PATH\\*-$Version\") ) {\n\t\tthrow \"Could not unzip the archive of $Candidate $Version. Please delete archive from $Script:PGVM_ARCHIVES_PATH (or delete all with 'gvm flush archives'\"\n\t}\n\n    # move to target location\n    # Move was replaced by copy and remove because of random access denied errors\n    # when Unzip was done by via -com shell.application\n    # Move-Item \"$Script:PGVM_TEMP_PATH\\*-$Version\" \"$Global:PGVM_DIR\\$Candidate\\$Version\"\n    Copy-Item \"$Script:PGVM_TEMP_PATH\\*-$Version\" \"$Global:PGVM_DIR\\$Candidate\\$Version\" -Recurse\n    Remove-Item \"$Script:PGVM_TEMP_PATH\\*-$Version\" -Recurse -Force\n    Write-Output \"Done installing!\"\n}\n\nfunction Unzip-Archive($Archive, $Target) {\n    if ( $Script:SEVENZ_On_PATH ) {\n        $zipProcess = Start-Process 7z.exe -ArgumentList \"x -o`\"$Target`\" -y `\"$Archive`\"\" -Wait -PassThru -NoNewWindow\n\n        if ($zipProcess.ExitCode -ne 0) {\n            Remove-Item $Target -Recurse -Force\n        }\n    } elseif ( $Script:UNZIP_ON_PATH ) {\n        unzip.exe -oq $Archive -d $Target\n    } else {\n        # use the windows shell as general fallback (no working on Windows Server Core because there is no shell)\n        $shell = New-Object -com shell.application\n        $shell.namespace($Target).copyhere($shell.namespace($Archive).items(), 0x10)\n    }\n}\n\nfunction Download-File($Url, $TargetFile) {\n\t<#\n\t\tAdepted from http://blogs.msdn.com/b/jasonn/archive/2008/06/13/downloading-files-from-the-internet-in-powershell-with-progress.aspx\n\t#>\n    Write-Verbose \"Try to download $Url with HttpWebRequest\"\n\t$uri = New-Object \"System.Uri\" $Url\n    $request = [System.Net.HttpWebRequest]::Create($uri)\n    $request.set_Timeout(15000)\n    $response = $request.GetResponse()\n\t$totalLength = [System.Math]::Floor($response.get_ContentLength()/1024)\n\t$responseStream = $response.GetResponseStream()\n    $targetStream = New-Object -TypeName System.IO.FileStream -ArgumentList $targetFile, Create\n\t$buffer = new-object byte[] 10KB\n    $count = $responseStream.Read($buffer,0,$buffer.length)\n    $downloadedBytes = $count\n\twhile ($count -gt 0)\n    {\n        if ($totalLength -lt 0) {\n            $totalLength = [System.Math]::Floor($response.get_ContentLength()/1024)\n        }\n        [System.Console]::CursorLeft = 0\n        [System.Console]::Write(\"Downloaded {0}K of {1}K\", [System.Math]::Floor($downloadedBytes/1024), $totalLength)\n        $targetStream.Write($buffer, 0, $count)\n        $count = $responseStream.Read($buffer,0,$buffer.length)\n        $downloadedBytes = $downloadedBytes + $count\n    }\n    $targetStream.Flush()\n    $targetStream.Close()\n    $targetStream.Dispose()\n    $responseStream.Dispose()\n    Write-Output ''\n}\n"
  },
  {
    "path": "VERSION.txt",
    "content": "1.3.1\n"
  },
  {
    "path": "posh-gvm.psm1",
    "content": "﻿<#\nposh-gvm / POwerSHell Groovy enVironment Manager\n\nhttps://github.com/flofreud/posh-gvm\n\nNeeded:\n- Powershell 3.0 (For Windows 7 install Windows Management Framework 3.0)\n#>\n\n#region Config\nif ( !(Test-Path Variable:Global:PGVM_DIR) ) {\n\t$Global:PGVM_DIR = \"$env:USERPROFILE\\.posh_gvm\"\n}\nif ( !(Test-Path Variable:Global:PGVM_AUTO_ANSWER) ) {\n\t$Global:PGVM_AUTO_ANSWER = $false\n}\nif ( !(Test-Path Variable:Global:PGVM_AUTO_SELFUPDATE) ) {\n\t$Global:PGVM_AUTO_SELFUPDATE = $false\n}\n\n$Script:PGVM_INIT = $false\n$Script:PGVM_SERVICE = 'https://api.sdkman.io'\n$Script:PGVM_BROADCAST_SERVICE = 'https://api.sdkman.io/2'\n$Script:GVM_BASE_VERSION = '1.3.13'\n\n$Script:PGVM_CANDIDATES_PATH = \"$Global:PGVM_DIR\\.meta\\candidates.txt\"\n$Script:PGVM_BROADCAST_PATH = \"$Global:PGVM_DIR\\.meta\\broadcast.txt\"\n$Script:GVM_API_VERSION_PATH = \"$Global:PGVM_DIR\\.meta\\version.txt\"\n$Script:PGVM_ARCHIVES_PATH = \"$Global:PGVM_DIR\\.meta\\archives\"\n$Script:PGVM_TEMP_PATH = \"$Global:PGVM_DIR\\.meta\\tmp\"\n\n$Script:GVM_API_NEW_VERSION = $false\n$Script:PGVM_NEW_VERSION = $false\n$Script:PGVM_VERSION_PATH = \"$psScriptRoot\\VERSION.txt\"\n$Script:PGVM_VERSION_SERVICE = \"https://raw.githubusercontent.com/flofreud/posh-gvm/master/VERSION.txt\"\n\n$Script:GVM_AVAILABLE = $true\n$Script:GVM_ONLINE = $true\n$Script:GVM_FORCE_OFFLINE = $false\n$Script:GVM_CANDIDATES = $null\n$Script:FIRST_RUN = $true\n\n$Script:UNZIP_ON_PATH = $false\n#endregion\n\nPush-Location $psScriptRoot\n. .\\Utils.ps1\n. .\\Commands.ps1\n. .\\Init.ps1\n. .\\TabExpansion.ps1\nPop-Location\n\nInit-Posh-Gvm\n\nExport-ModuleMember 'gvm'\n"
  }
]