├── VERSION.txt ├── test ├── grails-1.3.9.zip └── grails-2.2.2.zip ├── README.md ├── CHANGELOG.md ├── posh-gvm.psm1 ├── Init.ps1 ├── GetPoshGvm.ps1 ├── TestUtils.ps1 ├── TabExpansion.ps1 ├── Init.Tests.ps1 ├── Commands.ps1 ├── LICENSE ├── Utils.ps1 ├── Commands.Tests.ps1 └── Utils.Tests.ps1 /VERSION.txt: -------------------------------------------------------------------------------- 1 | 1.3.1 2 | -------------------------------------------------------------------------------- /test/grails-1.3.9.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flofreud/posh-gvm/HEAD/test/grails-1.3.9.zip -------------------------------------------------------------------------------- /test/grails-2.2.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flofreud/posh-gvm/HEAD/test/grails-2.2.2.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The code inside of this repository is broken. If you need the functionality of SDKMAN on Windows consider using Docker or WSL. 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### Version 1.3.0 2 | * BUGFIX: update url to API endpoint 3 | * BUGFIX: support for symlink handling in Win10 4 | * IMPROVE: use 7zip for archive extraction if available on path 5 | * BUGFIX: walkaround for rare ACCESS_DENIED error on SDK installation 6 | * BUGFIX: always show correct download file sizes 7 | 8 | ### Version 1.2.2 9 | * BUGFIX: explicitly handle a missing version definition for uninstall 10 | * BUGFIX: added -Force for Remove-Item in the uninstall process 11 | 12 | ### Version 1.2.1 13 | * BUGFIX: fixed wrong url construction for broadcast api 14 | 15 | ### Version 1.2.0 16 | * IMPROVE: update to the new broadcast api for GVM 17 | 18 | ### Version 1.1.4 19 | * IMPROVE: version check requests where executed on module import and took some time, these checks will now be executed on first gvm-call 20 | 21 | ### Version 1.1.3 22 | * IMPROVE: the new version messaging 23 | 24 | ### Version 1.1.2 25 | * BUGFIX: installation routine in GetPoshGvm.ps1 broken 26 | 27 | ### Version 1.1.1 28 | * BUGFIX: default of $Global:PGVM_AUTO_SELFUPDATE was $true but should have been $false 29 | 30 | ### Version 1.1.0 31 | * FEATURE: use unzip.exe if available on path for better install performance 32 | * FEATURE: self-update 33 | * FEATURE: automatic check for new posh-gvm versions 34 | 35 | ### Version 1.0.0 36 | * posh-gvm before it has self-update functionality 37 | -------------------------------------------------------------------------------- /posh-gvm.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | posh-gvm / POwerSHell Groovy enVironment Manager 3 | 4 | https://github.com/flofreud/posh-gvm 5 | 6 | Needed: 7 | - Powershell 3.0 (For Windows 7 install Windows Management Framework 3.0) 8 | #> 9 | 10 | #region Config 11 | if ( !(Test-Path Variable:Global:PGVM_DIR) ) { 12 | $Global:PGVM_DIR = "$env:USERPROFILE\.posh_gvm" 13 | } 14 | if ( !(Test-Path Variable:Global:PGVM_AUTO_ANSWER) ) { 15 | $Global:PGVM_AUTO_ANSWER = $false 16 | } 17 | if ( !(Test-Path Variable:Global:PGVM_AUTO_SELFUPDATE) ) { 18 | $Global:PGVM_AUTO_SELFUPDATE = $false 19 | } 20 | 21 | $Script:PGVM_INIT = $false 22 | $Script:PGVM_SERVICE = 'https://api.sdkman.io' 23 | $Script:PGVM_BROADCAST_SERVICE = 'https://api.sdkman.io/2' 24 | $Script:GVM_BASE_VERSION = '1.3.13' 25 | 26 | $Script:PGVM_CANDIDATES_PATH = "$Global:PGVM_DIR\.meta\candidates.txt" 27 | $Script:PGVM_BROADCAST_PATH = "$Global:PGVM_DIR\.meta\broadcast.txt" 28 | $Script:GVM_API_VERSION_PATH = "$Global:PGVM_DIR\.meta\version.txt" 29 | $Script:PGVM_ARCHIVES_PATH = "$Global:PGVM_DIR\.meta\archives" 30 | $Script:PGVM_TEMP_PATH = "$Global:PGVM_DIR\.meta\tmp" 31 | 32 | $Script:GVM_API_NEW_VERSION = $false 33 | $Script:PGVM_NEW_VERSION = $false 34 | $Script:PGVM_VERSION_PATH = "$psScriptRoot\VERSION.txt" 35 | $Script:PGVM_VERSION_SERVICE = "https://raw.githubusercontent.com/flofreud/posh-gvm/master/VERSION.txt" 36 | 37 | $Script:GVM_AVAILABLE = $true 38 | $Script:GVM_ONLINE = $true 39 | $Script:GVM_FORCE_OFFLINE = $false 40 | $Script:GVM_CANDIDATES = $null 41 | $Script:FIRST_RUN = $true 42 | 43 | $Script:UNZIP_ON_PATH = $false 44 | #endregion 45 | 46 | Push-Location $psScriptRoot 47 | . .\Utils.ps1 48 | . .\Commands.ps1 49 | . .\Init.ps1 50 | . .\TabExpansion.ps1 51 | Pop-Location 52 | 53 | Init-Posh-Gvm 54 | 55 | Export-ModuleMember 'gvm' 56 | -------------------------------------------------------------------------------- /Init.ps1: -------------------------------------------------------------------------------- 1 | #region Initialization 2 | function Init-Posh-Gvm() { 3 | Write-Verbose 'Init posh-gvm' 4 | 5 | $ErrorActionPreference = 'Stop' 6 | $ProgressPreference = 'SilentlyContinue' 7 | 8 | Check-JAVA-HOME 9 | 10 | # Check if $Global:PGVM_DIR is available, if not create it 11 | if ( !( Test-Path "$Global:PGVM_DIR\.meta" ) ) { 12 | New-Item -ItemType Directory "$Global:PGVM_DIR\.meta" | Out-Null 13 | } 14 | 15 | # Load candidates cache 16 | if ( ! (Test-Path $Script:PGVM_CANDIDATES_PATH) ) { 17 | Update-Candidates-Cache 18 | } 19 | 20 | Init-Candidate-Cache 21 | 22 | #Setup default paths 23 | Foreach ( $candidate in $Script:GVM_CANDIDATES ) { 24 | if ( !( Test-Path "$Global:PGVM_DIR\$candidate" ) ) { 25 | New-Item -ItemType Directory "$Global:PGVM_DIR\$candidate" | Out-Null 26 | } 27 | 28 | Set-Env-Candidate-Version $candidate 'current' 29 | } 30 | 31 | # Check if we can use unzip (which is much faster) 32 | Check-Unzip-On-Path 33 | } 34 | 35 | function Check-JAVA-HOME() { 36 | # Check for JAVA_HOME, If not set, try to interfere it 37 | if ( ! (Test-Path env:JAVA_HOME) ) { 38 | try { 39 | [Environment]::SetEnvironmentVariable('JAVA_HOME', (Get-Item (Get-Command 'javac').Path).Directory.Parent.FullName) 40 | } catch { 41 | throw "Could not find java, please set JAVA_HOME" 42 | } 43 | } 44 | } 45 | 46 | function Check-Unzip-On-Path() { 47 | try { 48 | Get-Command 'unzip.exe' | Out-Null 49 | $Script:UNZIP_ON_PATH = $true 50 | } catch { 51 | $Script:UNZIP_ON_PATH = $false 52 | } 53 | 54 | try { 55 | Get-Command '7z.exe' | Out-Null 56 | $Script:SEVENZ_ON_PATH = $true 57 | } catch { 58 | $Script:SEVENZ_ON_PATH = $false 59 | } 60 | } 61 | #endregion 62 | -------------------------------------------------------------------------------- /GetPoshGvm.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | Paragon for the installation script is PsGet 3 | #> 4 | 5 | function Install-Posh-Gvm() { 6 | $poshGvmZipUrl = 'https://github.com/flofreud/posh-gvm/archive/master.zip' 7 | 8 | $poshGvmPath = Find-Module-Location 9 | 10 | try { 11 | # create temp dir 12 | $tempDir = [guid]::NewGuid().ToString() 13 | $tempDir = Join-Path -Path $env:TEMP -ChildPath $tempDir 14 | New-Item -ItemType Directory $tempDir | Out-Null 15 | 16 | # download current version 17 | $poshGvmZip = "$tempDir\posh-gvm-master.zip" 18 | Write-Output "Downloading posh-gvm from $poshGvmZipUrl" 19 | 20 | $client = (New-Object Net.WebClient) 21 | $client.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials 22 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 23 | $client.DownloadFile($poshGvmZipUrl, $poshGvmZip) 24 | 25 | # unzip archive 26 | $shell = New-Object -com shell.application 27 | $shell.namespace($tempDir).copyhere($shell.namespace($poshGvmZip).items(), 0x14) 28 | 29 | # check if unzip successfully 30 | if ( Test-Path "$tempDir\posh-gvm-master" ) { 31 | if ( !(Test-Path $poshGvmPath) ) { 32 | New-Item -ItemType Directory $poshGvmPath | Out-Null 33 | } 34 | 35 | Copy-Item "$tempDir\posh-gvm-master\*" $poshGvmPath -Force -Recurse 36 | Write-Output "posh-gvm installed!" 37 | Write-Output "Please see https://github.com/flofreud/posh-gvm#usage for details to get started." 38 | Write-Warning "Execute 'Import-Module posh-gvm -Force' so changes take effect!" 39 | } else { 40 | Write-Warning 'Could not unzip archive containing posh-gvm. Most likely the archive is currupt. Please try to install again.' 41 | } 42 | } finally { 43 | # clear temp dir 44 | Remove-Item -Recurse -Force $tempDir 45 | } 46 | } 47 | 48 | function Find-Module-Location { 49 | $moduleDescriptor = Get-Module posh-gvm 50 | 51 | if ( $moduleDescriptor ) { 52 | return (Get-Item ($moduleDescriptor).Path).Directory.FullName 53 | } else { 54 | $modulePaths = @($Env:PSModulePath -split ';') 55 | # set module path to posh default 56 | $targetModulePath = Join-Path -Path ([Environment]::GetFolderPath('MyDocuments')) -ChildPath WindowsPowerShell\Modules 57 | # if its not use select the first defined 58 | if ( $modulePaths -inotcontains $targetModulePath ) { 59 | $targetModulePath = $modulePaths | Select-Object -Index 0 60 | } 61 | 62 | return "$targetModulePath\posh-gvm" 63 | } 64 | } 65 | 66 | Install-Posh-Gvm 67 | -------------------------------------------------------------------------------- /TestUtils.ps1: -------------------------------------------------------------------------------- 1 | . .\Utils.ps1 2 | 3 | function Mock-Check-Candidate-Grails { 4 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 5 | } 6 | 7 | function Mock-Online { 8 | Mock Get-Online-Mode { return $true } 9 | } 10 | 11 | function Mock-Offline { 12 | Mock Get-Online-Mode { return $false } 13 | } 14 | 15 | function Mock-Grails-1.1.1-Locally-Available($Available) { 16 | if ( $Available ) { 17 | Mock Is-Candidate-Version-Locally-Available { return $true } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 18 | } else { 19 | Mock Is-Candidate-Version-Locally-Available { return $false } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 20 | } 21 | } 22 | 23 | function Mock-Current-Grails-1.2 { 24 | Mock Get-Current-Candidate-Version { return 1.2 } -parameterFilter { $Candidate -eq 'grails' } 25 | } 26 | 27 | function Mock-No-Current-Grails { 28 | Mock Get-Current-Candidate-Version { return $null } -parameterFilter { $Candidate -eq 'grails' } 29 | } 30 | 31 | function Mock-Api-Call-Default-Grails-2.2 { 32 | Mock Invoke-API-Call { return 2.2 } -parameterFilter { $Path -eq 'candidates/grails/default' } 33 | } 34 | 35 | function Mock-Api-Call-Grails-1.1.1-Available($Available) { 36 | if ( $Available ) { 37 | Mock Invoke-API-Call { return $true } -parameterFilter { $Path -eq 'candidates/grails/1.1.1' } 38 | } else { 39 | Mock Invoke-API-Call { return $false } -parameterFilter { $Path -eq 'candidates/grails/1.1.1' } 40 | } 41 | } 42 | 43 | function Mock-PGVM-Dir { 44 | $Script:backup_PGVM_DIR = $Global:PGVM_DIR 45 | New-Item -ItemType Directory "TestDrive:.posh-gvm" | Out-Null 46 | $Global:PGVM_DIR = (Get-Item "TestDrive:.posh-gvm").FullName 47 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails" | Out-Null 48 | } 49 | 50 | function Reset-PGVM-Dir { 51 | $link = "$Global:PGVM_DIR\grails\current" 52 | if ( Test-Path $link ) { 53 | (Get-Item $link).Delete() 54 | } 55 | 56 | $Global:PGVM_DIR = $Script:backup_PGVM_DIR 57 | } 58 | 59 | function Mock-Grails-Home($Version) { 60 | $Script:backup_GRAILS_HOME = [System.Environment]::GetEnvironmentVariable('GRAILS_HOME') 61 | [System.Environment]::SetEnvironmentVariable('GRAILS_HOME', "$Global:PGVM_DIR\grails\$Version") 62 | } 63 | 64 | function Reset-Grails-Home { 65 | [System.Environment]::SetEnvironmentVariable('GRAILS_HOME', $Script:backup_GRAILS_HOME) 66 | } 67 | 68 | function Mock-Dispatcher-Test([switch]$Offline) { 69 | Mock-PGVM-Dir 70 | $Script:GVM_FORCE_OFFLINE = $false 71 | $Script:FIRST_RUN = $false 72 | if ( !($Offline) ) { 73 | Mock Check-Available-Broadcast -verifiable 74 | Write-New-Version-Broadcast -verifiable 75 | } 76 | Mock Init-Candidate-Cache -verifiable 77 | } 78 | 79 | function Reset-Dispatcher-Test { 80 | Reset-PGVM-Dir 81 | } -------------------------------------------------------------------------------- /TabExpansion.ps1: -------------------------------------------------------------------------------- 1 | # Check if function TabExpansion already exists and backup existing version to 2 | # prevent breaking other TabExpansion implementations. 3 | # Taken from posh-git https://github.com/dahlbyk/posh-git/blob/master/GitTabExpansion.ps1#L297 4 | $tabExpansionBackup = 'PoshGVM_DefaultTabExpansion' 5 | if (Test-Path Function:\TabExpansion) { 6 | Rename-Item Function:\TabExpansion $tabExpansionBackup -ErrorAction SilentlyContinue 7 | } 8 | 9 | function TabExpansion($line, $lastWord) { 10 | $lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart() 11 | 12 | switch -regex ($lastBlock) { 13 | # Execute gvm tab expansion for gvm command 14 | '^gvm (.*)' { gvmTabExpansion($lastBlock) } 15 | # Fall back on existing tab expansion 16 | default { if (Test-Path Function:\$tabExpansionBackup) { & $tabExpansionBackup $line $lastWord } } 17 | } 18 | } 19 | 20 | $Script:PGVM_TAB_COMMANDS = @('install','uninstall','rm','list','use','default','current','version','broadcast','help','offline','selfupdate','flush') 21 | function gvmTabExpansion($lastBlock) { 22 | if ( !($lastBlock -match '^gvm\s+(?\S+)?(? .*)?$') ) { 23 | return 24 | } 25 | $command = $Matches['cmd'] 26 | $arguments = $Matches['args'] 27 | 28 | if ( !($arguments) ) { 29 | # Try to complete the command 30 | return $Script:PGVM_TAB_COMMANDS | Where-Object { $_.StartsWith($command) } 31 | } 32 | 33 | $arguments = $arguments.TrimStart() 34 | # Help add correct parameters 35 | switch -regex ($command) { 36 | '^i(nstall)?' { gvmTabExpandion-Need-Candidate $command $arguments } 37 | '^(uninstall|rm)'{ gvmTabExpandion-Need-Candidate $command $arguments } 38 | '^(ls|list)' { gvmTabExpandion-Need-Candidate $command $arguments } 39 | '^u(se)?' { gvmTabExpandion-Need-Candidate $command $arguments } 40 | '^d(efault)?' { gvmTabExpandion-Need-Candidate $command $arguments } 41 | '^c(urrent)?' { gvmTabExpandion-Need-Candidate $command $arguments } 42 | '^offline' { gvmTabExpansion-Offline $arguments } 43 | '^flush' { gvmTabExpansion-Flush $arguments } 44 | default {} 45 | } 46 | } 47 | 48 | function gvmTabExpandion-Need-Candidate($Command, $LastBlock) { 49 | if ( !($LastBlock -match "^(?\S+)?(? .*)?$") ) { 50 | return 51 | } 52 | $candidate = $Matches['candidate'] 53 | $arguments = $Matches['args'] 54 | 55 | Init-Candidate-Cache 56 | 57 | if ( !($arguments) ) { 58 | # Try to complete the command 59 | return $Script:GVM_CANDIDATES | Where-Object { $_.StartsWith($candidate) } 60 | } 61 | 62 | if ( !($Script:GVM_CANDIDATES -contains $candidate) ) { 63 | return 64 | } 65 | 66 | $arguments = $arguments.TrimStart() 67 | # Help add correct parameters 68 | switch -regex ($command) { 69 | #'^i(nstall)?' { gvmTabExpandion-Need-Version $candidate $arguments } 70 | '^(uninstall|rm)'{ gvmTabExpandion-Need-Version $candidate $arguments } 71 | '^u(se)?' { gvmTabExpandion-Need-Version $candidate $arguments } 72 | '^d(efault)?' { gvmTabExpandion-Need-Version $candidate $arguments } 73 | default {} 74 | } 75 | } 76 | 77 | function gvmTabExpandion-Need-Version($Candidate, $LastBlock) { 78 | Get-Installed-Candidate-Version-List $Candidate | Where-Object { $_.StartsWith($LastBlock) } 79 | } 80 | 81 | function gvmTabExpansion-Offline($Arguments) { 82 | @('enable','disable') | Where-Object { ([string]$_).StartsWith($Arguments) } 83 | } 84 | 85 | function gvmTabExpansion-Flush($Arguments) { 86 | @('candidates','broadcast','archives','temp') | Where-Object { ([string]$_).StartsWith($Arguments) } 87 | } 88 | 89 | Export-ModuleMember TabExpansion 90 | Export-ModuleMember gvmTabExpansion -------------------------------------------------------------------------------- /Init.Tests.ps1: -------------------------------------------------------------------------------- 1 | . .\Utils.ps1 2 | . .\Init.ps1 3 | . .\TestUtils.ps1 4 | 5 | Describe 'Init-Posh-Gvm' { 6 | Context 'PGVM-Dir with only a grails folder' { 7 | Mock-PGVM-Dir 8 | Mock Check-JAVA-HOME -verifiable 9 | Mock Update-Candidates-Cache -verifiable 10 | Mock Init-Candidate-Cache -verifiable 11 | Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq 'current' } 12 | Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'groovy' -and $Version -eq 'current' } 13 | Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'bla' -and $Version -eq 'current' } 14 | $Script:PGVM_CANDIDATES_PATH = "$Global:PGVM_DIR\.meta\candidates.txt" 15 | $Script:GVM_CANDIDATES = 'grails','groovy','bla' 16 | 17 | Init-Posh-Gvm 18 | 19 | It "creates .meta" { 20 | Test-Path "$Global:PGVM_DIR\.meta" | Should Be $true 21 | } 22 | 23 | It "creates grails" { 24 | Test-Path "$Global:PGVM_DIR\grails" | Should Be $true 25 | } 26 | 27 | It "creates groovy" { 28 | Test-Path "$Global:PGVM_DIR\groovy" | Should Be $true 29 | } 30 | 31 | It "creates bla" { 32 | Test-Path "$Global:PGVM_DIR\bla" | Should Be $true 33 | } 34 | 35 | It "calls methods to test JAVA_HOME, API version, loads candidate cache and setup env variables" { 36 | Assert-VerifiableMocks 37 | } 38 | 39 | Reset-PGVM-Dir 40 | } 41 | 42 | Context 'PGVM-Dir with only a grails folder and a candidates list' { 43 | Mock-PGVM-Dir 44 | Mock Check-JAVA-HOME -verifiable 45 | Mock Update-Candidates-Cache 46 | Mock Init-Candidate-Cache -verifiable 47 | Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq 'current' } 48 | Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'groovy' -and $Version -eq 'current' } 49 | Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'bla' -and $Version -eq 'current' } 50 | $Script:PGVM_CANDIDATES_PATH = "$Global:PGVM_DIR\.meta\candidates.txt" 51 | New-Item -ItemType Directory "$Global:PGVM_DIR\.meta" | Out-Null 52 | New-Item -ItemType File $Script:PGVM_CANDIDATES_PATH | Out-Null 53 | $Script:GVM_CANDIDATES = 'grails','groovy','bla' 54 | 55 | Init-Posh-Gvm 56 | 57 | It "creates .meta" { 58 | Test-Path "$Global:PGVM_DIR\.meta" | Should Be $true 59 | } 60 | 61 | It "creates grails" { 62 | Test-Path "$Global:PGVM_DIR\grails" | Should Be $true 63 | } 64 | 65 | It "creates groovy" { 66 | Test-Path "$Global:PGVM_DIR\groovy" | Should Be $true 67 | } 68 | 69 | It "creates bla" { 70 | Test-Path "$Global:PGVM_DIR\bla" | Should Be $true 71 | } 72 | 73 | It "calls methods to test JAVA_HOME, API version, loads candidate cache and setup env variables" { 74 | Assert-VerifiableMocks 75 | } 76 | 77 | It "does not call update-candidates-cache" { 78 | Assert-MockCalled Update-Candidates-Cache 0 79 | } 80 | 81 | Reset-PGVM-Dir 82 | } 83 | } 84 | 85 | Describe 'Check-JAVA-HOME' { 86 | Context 'JAVA_HOME is set' { 87 | Mock Get-Command 88 | Mock Test-Path { $true } -parameterFilter { $Path -eq 'env:Java_HOME' } 89 | 90 | Check-JAVA-HOME 91 | 92 | It "changes nothing" { 93 | Assert-MockCalled Get-Command 0 94 | } 95 | } 96 | 97 | Context 'JAVA_HOME is not set but javac is on path' { 98 | $backupJAVAHOME = [Environment]::GetEnvironmentVariable('JAVA_HOME') 99 | Mock Test-Path { $false } -parameterFilter { $Path -eq 'env:Java_HOME' } 100 | Mock Get-Command { New-Object PSObject -Property @{ Path = (Get-Item 'C:\Windows\explorer.exe') } } -parameterFilter { $Name -eq 'javac' } 101 | $expectedNewJAVAHOME = 'C:\' 102 | 103 | Check-JAVA-HOME 104 | 105 | It "sets JAVA_HOME to javac parent" { 106 | [Environment]::GetEnvironmentVariable('JAVA_HOME') | Should Be $expectedNewJAVAHOME 107 | } 108 | 109 | [Environment]::SetEnvironmentVariable('JAVA_HOME', $backupJAVAHOME) 110 | } 111 | 112 | Context 'JAVA_HOME is not set and javax is not on path' { 113 | Mock Test-Path { $false } -parameterFilter { $Path -eq 'env:Java_HOME' } 114 | Mock Get-Command { throw 'error' } -parameterFilter { $Name -eq 'javac' } 115 | 116 | It "throws an error" { 117 | { Check-JAVA-HOME } | Should Throw 118 | } 119 | } 120 | } -------------------------------------------------------------------------------- /Commands.ps1: -------------------------------------------------------------------------------- 1 | function gvm([string]$Command, [string]$Candidate, [string]$Version, [string]$InstallPath, [switch]$Verbose, [switch]$Force) { 2 | $ErrorActionPreference = 'Stop' 3 | $ProgressPreference = 'SilentlyContinue' 4 | if ($Verbose) { $VerbosePreference = 'Continue' } 5 | 6 | if ( !( Test-Path $Global:PGVM_DIR ) ) { 7 | Write-Warning "$Global:PGVM_DIR does not exists. Reinitialize posh-gvm" 8 | Init-Posh-Gvm 9 | } 10 | 11 | $Script:GVM_AVAILABLE = $true 12 | if ( !($Script:GVM_FORCE_OFFLINE) -and $Command -ne 'offline' ) { 13 | Check-Available-Broadcast $Command 14 | 15 | if ( $Script:GVM_AVAILABLE ) { 16 | if ( $Script:FIRST_RUN ) { 17 | Check-GVM-API-Version 18 | Check-Posh-Gvm-Version 19 | $Script:FIRST_RUN = $false 20 | } 21 | Write-New-Version-Broadcast 22 | } 23 | } 24 | 25 | Init-Candidate-Cache 26 | 27 | Write-Verbose "Command: $Command" 28 | 29 | if ($Command -eq '') { 30 | $Command = 'help' 31 | } 32 | 33 | try { 34 | switch -regex ($Command) { 35 | '^i(nstall)?$' { Install-Candidate-Version $Candidate $Version $InstallPath } 36 | '^(uninstall|rm)$'{ Uninstall-Candidate-Version $Candidate $Version } 37 | '^(ls|list)$' { List-Candidate-Versions $Candidate } 38 | '^u(se)?$' { Use-Candidate-Version $Candidate $Version } 39 | '^d(efault)?$' { Set-Default-Version $Candidate $Version } 40 | '^c(urrent)?$' { Show-Current-Version $Candidate } 41 | '^v(ersion)?$' { Show-Posh-Gvm-Version } 42 | '^b(roadcast)?$' { Show-Broadcast-Message } 43 | '^h(elp)?$' { Show-Help } 44 | '^offline$' { Set-Offline-Mode $Candidate } 45 | '^selfupdate$' { Invoke-Self-Update($Force) } 46 | '^flush$' { Flush-Cache $Candidate } 47 | default { Write-Warning "Invalid command: $Command. Check gvm help!" } 48 | } 49 | } catch { 50 | if ( $_.CategoryInfo.Category -eq 'OperationStopped') { 51 | Write-Warning $_.CategoryInfo.TargetName 52 | } else { 53 | throw 54 | } 55 | } 56 | } 57 | 58 | function Install-Candidate-Version($Candidate, $Version, $InstallPath) { 59 | Write-Verbose 'Perform Install-Candidate-Version' 60 | Check-Candidate-Present $Candidate 61 | 62 | $localInstallation = $false 63 | if ($Version -and $InstallPath) { 64 | #local installation 65 | try { 66 | $Version = Check-Candidate-Version-Available $Candidate $Version 67 | } catch { 68 | $localInstallation = $true 69 | } 70 | if ( !($localInstallation) ) { 71 | throw 'Stop! Local installation for $Candidate $Version not possible. It exists remote already.' 72 | } 73 | } else { 74 | $Version = Check-Candidate-Version-Available $Candidate $Version 75 | } 76 | 77 | if ( Is-Candidate-Version-Locally-Available $Candidate $Version ) { 78 | throw "Stop! $Candidate $Version is already installed." 79 | } 80 | 81 | if ( $localInstallation ) { 82 | Install-Local-Version $Candidate $Version $InstallPath 83 | } else { 84 | Install-Remote-Version $Candidate $Version 85 | } 86 | 87 | $default = $false 88 | if ( !$Global:PGVM_AUTO_ANSWER ) { 89 | $default = (Read-Host -Prompt "Do you want $Candidate $Version to be set as default? (Y/n)") -match '(y|\A\z)' 90 | } else { 91 | $default = $true 92 | } 93 | 94 | if ( $default ) { 95 | Write-Output "Setting $Candidate $Version as default." 96 | Set-Linked-Candidate-Version $Candidate $Version 97 | } 98 | } 99 | 100 | function Uninstall-Candidate-Version($Candidate, $Version) { 101 | Write-Verbose 'Perform Uninstall-Candidate-Version' 102 | Check-Candidate-Present $Candidate 103 | Check-Version-Present $Version 104 | 105 | if ( !(Is-Candidate-Version-Locally-Available $Candidate $Version) ) { 106 | throw "$Candidate $Version is not installed." 107 | } 108 | 109 | $current = Get-Current-Candidate-Version $Candidate 110 | 111 | if ( $current -eq $Version ) { 112 | Write-Output "Unselecting $Candidate $Version..." 113 | (Get-Item "$Global:PGVM_DIR\$Candidate\current").Delete() 114 | } 115 | 116 | Write-Output "Uninstalling $Candidate $Version..." 117 | Remove-Item -Recurse -Force "$Global:PGVM_DIR\$Candidate\$Version" 118 | } 119 | 120 | function List-Candidate-Versions($Candidate) { 121 | Write-Verbose 'Perform List-Candidate-Version' 122 | Check-Candidate-Present $Candidate 123 | if ( Get-Online-Mode ) { 124 | Write-Version-List $Candidate 125 | } else { 126 | Write-Offline-Version-List $Candidate 127 | } 128 | } 129 | 130 | function Use-Candidate-Version($Candidate, $Version) { 131 | Write-Verbose 'Perform Use-Candidate-Version' 132 | $Version = Check-Candidate-Version-Available $Candidate $Version 133 | 134 | if ( $Version -eq (Get-Env-Candidate-Version $Candidate) ) { 135 | Write-Output "$Candidate $Version is used. Nothing changed." 136 | } else { 137 | Check-Candidate-Version-Locally-Available $Candidate $Version 138 | Set-Env-Candidate-Version $Candidate $Version 139 | Write-Output "Using $CANDIDATE version $Version in this shell." 140 | } 141 | } 142 | 143 | function Set-Default-Version($Candidate, $Version) { 144 | Write-Verbose 'Perform Set-Default-Version' 145 | $Version = Check-Candidate-Version-Available $Candidate $Version 146 | 147 | if ( $Version -eq (Get-Current-Candidate-Version $Candidate) ) { 148 | Write-Output "$Candidate $Version is already default. Nothing changed." 149 | } else { 150 | Check-Candidate-Version-Locally-Available $Candidate $Version 151 | Set-Linked-Candidate-Version $Candidate $Version 152 | Write-Output "Default $Candidate version set to $Version" 153 | } 154 | } 155 | 156 | function Show-Current-Version($Candidate) { 157 | Write-Verbose 'Perform Set-Current-Version' 158 | 159 | if ( !($Candidate) ) { 160 | Write-Output 'Using:' 161 | foreach ( $c in $Script:GVM_CANDIDATES ) { 162 | $v = Get-Env-Candidate-Version $c 163 | if ($v) { 164 | Write-Output "$c`: $v" 165 | } 166 | } 167 | return 168 | } 169 | 170 | Check-Candidate-Present $Candidate 171 | $Version = Get-Env-Candidate-Version $Candidate 172 | if ( $Version ) { 173 | Write-Output "Using $Candidate version $Version" 174 | } else { 175 | Write-Output "Not using any version of $Candidate" 176 | } 177 | } 178 | 179 | function Show-Posh-Gvm-Version() { 180 | $poshGvmVersion = Get-Posh-Gvm-Version 181 | $apiVersion = Get-GVM-API-Version 182 | Write-Output "posh-gvm (POwer SHell Groovy enVironment Manager) $poshGvmVersion base on GVM $GVM_BASE_VERSION and GVM API $apiVersion" 183 | } 184 | 185 | function Show-Broadcast-Message() { 186 | Write-Verbose 'Perform Show-Broadcast-Message' 187 | Get-Content $Script:PGVM_BROADCAST_PATH | Write-Output 188 | } 189 | 190 | function Set-Offline-Mode($Flag) { 191 | Write-Verbose 'Perform Set-Offline-Mode' 192 | switch ($Flag) { 193 | 'enable' { $Script:GVM_FORCE_OFFLINE = $true; Write-Output 'Forced offline mode enabled.' } 194 | 'disable' { $Script:GVM_FORCE_OFFLINE = $false; $Script:GVM_ONLINE = $true; Write-Output 'Online mode re-enabled!' } 195 | default { throw "Stop! $Flag is not a valid offline offline mode." } 196 | } 197 | } 198 | 199 | function Flush-Cache($DataType) { 200 | Write-Verbose 'Perform Flush-Cache' 201 | switch ($DataType) { 202 | 'candidates' { 203 | if ( Test-Path $Script:PGVM_CANDIDATES_PATH ) { 204 | Remove-Item $Script:PGVM_CANDIDATES_PATH 205 | Write-Output 'Candidates have been flushed.' 206 | } else { 207 | Write-Warning 'No candidate list found so not flushed.' 208 | } 209 | } 210 | 'broadcast' { 211 | if ( Test-Path $Script:PGVM_BROADCAST_PATH ) { 212 | Remove-Item $Script:PGVM_BROADCAST_PATH 213 | Write-Output 'Broadcast have been flushed.' 214 | } else { 215 | Write-Warning 'No prior broadcast found so not flushed.' 216 | } 217 | } 218 | 'version' { 219 | if ( Test-Path $Script:GVM_API_VERSION_PATH ) { 220 | Remove-Item $Script:GVM_API_VERSION_PATH 221 | Write-Output 'Version Token have been flushed.' 222 | } else { 223 | Write-Warning 'No prior Remote Version found so not flushed.' 224 | } 225 | } 226 | 'archives' { Cleanup-Directory $Script:PGVM_ARCHIVES_PATH } 227 | 'temp' { Cleanup-Directory $Script:PGVM_TEMP_PATH } 228 | 'tmp' { Cleanup-Directory $Script:PGVM_TEMP_PATH } 229 | default { throw 'Stop! Please specify what you want to flush.' } 230 | } 231 | } 232 | 233 | function Show-Help() { 234 | Write-Output @" 235 | Usage: gvm [version] 236 | gvm offline 237 | 238 | commands: 239 | install or i [version] 240 | uninstall or rm 241 | list or ls 242 | use or u [version] 243 | default or d [version] 244 | current or c [candidate] 245 | version or v 246 | broadcast or b 247 | help or h 248 | offline 249 | selfupdate [-Force] 250 | flush 251 | candidate : $($Script:GVM_CANDIDATES -join ', ') 252 | 253 | version : where optional, defaults to latest stable if not provided 254 | 255 | eg: gvm install groovy 256 | "@ 257 | } 258 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | -------------------------------------------------------------------------------- /Utils.ps1: -------------------------------------------------------------------------------- 1 | function Write-Offline-Broadcast() { 2 | Write-Output @" 3 | ==== BROADCAST ================================================================= 4 | 5 | OFFLINE MODE ENABLED! Some functionality is now disabled. 6 | 7 | ================================================================================ 8 | "@ 9 | } 10 | 11 | function Write-Online-Broadcast() { 12 | Write-Output @" 13 | ==== BROADCAST ================================================================= 14 | 15 | ONLINE MODE RE-ENABLED! All functionality now restored. 16 | 17 | ================================================================================ 18 | 19 | "@ 20 | } 21 | 22 | function Write-New-Version-Broadcast() { 23 | if ( $Script:GVM_API_NEW_VERSION -or $Script:PGVM_NEW_VERSION ) { 24 | Write-Output @" 25 | ==== UPDATE AVAILABLE ========================================================== 26 | 27 | A new version is available. Please consider to execute: 28 | 29 | gvm selfupdate 30 | 31 | ================================================================================ 32 | "@ 33 | } 34 | } 35 | 36 | function Check-GVM-API-Version() { 37 | Write-Verbose 'Checking GVM-API version' 38 | try { 39 | $apiVersion = Get-GVM-API-Version 40 | $gvmRemoteVersion = Invoke-API-Call "app/version" 41 | 42 | if ( $gvmRemoteVersion -gt $apiVersion) { 43 | if ( $Global:PGVM_AUTO_SELFUPDATE ) { 44 | Invoke-Self-Update 45 | } else { 46 | $Script:GVM_API_NEW_VERSION = $true 47 | } 48 | } 49 | } catch { 50 | $Script:GVM_AVAILABLE = $false 51 | } 52 | } 53 | 54 | function Check-Posh-Gvm-Version() { 55 | Write-Verbose 'Checking posh-gvm version' 56 | if ( Is-New-Posh-GVM-Version-Available ) { 57 | if ( $Global:PGVM_AUTO_SELFUPDATE ) { 58 | Invoke-Self-Update 59 | } else { 60 | $Script:PGVM_NEW_VERSION = $true 61 | } 62 | } 63 | } 64 | 65 | function Get-Posh-Gvm-Version() { 66 | return Get-Content $Script:PGVM_VERSION_PATH 67 | } 68 | 69 | function Is-New-Posh-GVM-Version-Available() { 70 | try { 71 | $localVersion = (Get-Posh-Gvm-Version).Trim() 72 | $currentVersion = (Invoke-RestMethod $Script:PGVM_VERSION_SERVICE).Trim() 73 | 74 | Write-Verbose "posh-gvm version check $currentVersion > $localVersion = $($currentVersion -gt $localVersion)" 75 | 76 | return ( $currentVersion -gt $localVersion ) 77 | } catch { 78 | return $false 79 | } 80 | } 81 | 82 | function Get-GVM-API-Version() { 83 | if ( !(Test-Path $Script:GVM_API_VERSION_PATH) ) { 84 | return $null 85 | } 86 | return Get-Content $Script:GVM_API_VERSION_PATH 87 | } 88 | 89 | function Check-Available-Broadcast($Command) { 90 | $version = Get-GVM-API-Version 91 | if ( !( $version ) ) { 92 | return 93 | } 94 | 95 | $liveBroadcast = Invoke-Broadcast-API-Call 96 | 97 | Write-Verbose "Online-Mode: $Script:GVM_AVAILABLE" 98 | 99 | if ( $Script:GVM_ONLINE -and !($Script:GVM_AVAILABLE) ) { 100 | Write-Offline-Broadcast 101 | } elseif ( !($Script:GVM_ONLINE) -and $Script:GVM_AVAILABLE ) { 102 | Write-Online-Broadcast 103 | } 104 | $Script:GVM_ONLINE = $Script:GVM_AVAILABLE 105 | 106 | if ( $liveBroadcast ) { 107 | Handle-Broadcast $Command $liveBroadcast 108 | } 109 | } 110 | 111 | function Invoke-Broadcast-API-Call { 112 | try { 113 | $target = "$Script:PGVM_BROADCAST_SERVICE/broadcast/latest" 114 | Write-Verbose "Broadcast API call to: $target" 115 | return Invoke-RestMethod $target 116 | } catch { 117 | Write-Verbose "Could not reached broadcast API" 118 | $Script:GVM_AVAILABLE = $false 119 | return $null 120 | } 121 | } 122 | 123 | function Invoke-Self-Update($Force) { 124 | Write-Verbose 'Perform Invoke-Self-Update' 125 | Write-Output 'Update list of available candidates...' 126 | Update-Candidates-Cache 127 | $Script:GVM_API_NEW_VERSION = $false 128 | if ( $Force ) { 129 | Invoke-Posh-Gvm-Update 130 | } else { 131 | if ( Is-New-Posh-GVM-Version-Available ) { 132 | Invoke-Posh-Gvm-Update 133 | } 134 | } 135 | $Script:PGVM_NEW_VERSION = $false 136 | } 137 | 138 | function Invoke-Posh-Gvm-Update { 139 | Write-Output 'Update posh-gvm...' 140 | . "$psScriptRoot\GetPoshGvm.ps1" 141 | } 142 | 143 | function Check-Candidate-Present($Candidate) { 144 | if ( !($Candidate) ) { 145 | throw 'No candidate provided.' 146 | } 147 | 148 | if ( !($Script:GVM_CANDIDATES -contains $Candidate) ) { 149 | throw "Stop! $Candidate is no valid candidate!" 150 | } 151 | } 152 | 153 | function Check-Version-Present($Version) { 154 | if ( !($Version)) { 155 | throw 'No version provided.' 156 | } 157 | } 158 | 159 | function Check-Candidate-Version-Available($Candidate, $Version) { 160 | Check-Candidate-Present $Candidate 161 | 162 | $UseDefault = $false 163 | if ( !($Version) ) { 164 | Write-Verbose 'No version provided. Fallback to default version!' 165 | $UseDefault = $true 166 | } 167 | 168 | # Check locally 169 | elseif ( Is-Candidate-Version-Locally-Available $Candidate $Version ) { 170 | return $Version 171 | } 172 | 173 | # Check if offline 174 | if ( ! (Get-Online-Mode) ) { 175 | if ( $UseDefault ) { 176 | $Version = Get-Current-Candidate-Version $Candidate 177 | if ( $Version ) { 178 | return $Version 179 | } else { 180 | throw "Stop! No local default version for $Candidate and in offline mode." 181 | } 182 | } 183 | 184 | throw "Stop! $Candidate $Version is not available in offline mode." 185 | } 186 | 187 | if ( $UseDefault ) { 188 | Write-Verbose 'Try to get default version from remote' 189 | return Invoke-API-Call "candidates/$Candidate/default" 190 | } 191 | 192 | $VersionAvailable = Invoke-API-Call "candidates/$Candidate/$Version" 193 | 194 | if ( $VersionAvailable -eq 'valid' ) { 195 | return $Version 196 | } else { 197 | throw "Stop! $Version is not a valid $Candidate version." 198 | } 199 | } 200 | 201 | function Get-Current-Candidate-Version($Candidate) { 202 | $currentLink = "$Global:PGVM_DIR\$Candidate\current" 203 | 204 | $targetItem = Get-Junction-Target $currentLink 205 | 206 | if ($targetItem) { 207 | return $targetItem.Name 208 | } 209 | 210 | return $null 211 | } 212 | 213 | function Get-Junction-Target($linkPath) { 214 | if ( Test-Path $linkPath ) { 215 | try { 216 | $linkItem = Get-Item $linkPath 217 | 218 | if (Get-Member -InputObject $linkItem -Name "ReparsePoint") { 219 | return (Get-Item $linkItem.ReparsePoint.Target) 220 | } 221 | 222 | if (Get-Member -InputObject $linkItem -Name "Target") { 223 | return (Get-Item $linkItem.Target) 224 | } 225 | } catch { 226 | return $null 227 | } 228 | } 229 | 230 | return $null 231 | } 232 | 233 | function Get-Env-Candidate-Version($Candidate) { 234 | $envLink = [System.Environment]::GetEnvironmentVariable(([string]$Candidate).ToUpper() + "_HOME") 235 | 236 | if ( $envLink -match '(.*)current$' ) { 237 | Get-Current-Candidate-Version $Candidate 238 | } else { 239 | return (Get-Item $envLink).Name 240 | } 241 | } 242 | 243 | function Check-Candidate-Version-Locally-Available($Candidate, $Version) { 244 | if ( !(Is-Candidate-Version-Locally-Available $Candidate $Version) ) { 245 | throw "Stop! $Candidate $Version is not installed." 246 | } 247 | } 248 | 249 | function Is-Candidate-Version-Locally-Available($Candidate, $Version) { 250 | if ( $Version ) { 251 | return Test-Path "$Global:PGVM_DIR\$Candidate\$Version" 252 | } else { 253 | return $false 254 | } 255 | } 256 | 257 | function Get-Installed-Candidate-Version-List($Candidate) { 258 | return Get-ChildItem "$Global:PGVM_DIR\$Candidate" | ?{ $_.PSIsContainer -and $_.Name -ne 'current' } | Foreach { $_.Name } 259 | } 260 | 261 | function Set-Env-Candidate-Version($Candidate, $Version) { 262 | $candidateEnv = ([string]$candidate).ToUpper() + "_HOME" 263 | $candidateDir = "$Global:PGVM_DIR\$candidate" 264 | $candidateHome = "$candidateDir\$Version" 265 | $candidateBin = "$candidateHome\bin" 266 | 267 | if ( !([Environment]::GetEnvironmentVariable($candidateEnv) -eq $candidateHome) ) { 268 | [Environment]::SetEnvironmentVariable($candidateEnv, $candidateHome) 269 | } 270 | 271 | $env:PATH = "$candidateBin;$env:PATH" 272 | } 273 | 274 | function Set-Linked-Candidate-Version($Candidate, $Version) { 275 | $Link = "$Global:PGVM_DIR\$Candidate\current" 276 | $Target = "$Global:PGVM_DIR\$Candidate\$Version" 277 | Set-Junction-Via-Mklink $Link $Target 278 | } 279 | 280 | function Set-Junction-Via-Mklink($Link, $Target) { 281 | if ( Test-Path $Link ) { 282 | (Get-Item $Link).Delete() 283 | } 284 | 285 | Invoke-Expression -Command "cmd.exe /c mklink /J '$Link' '$Target'" | Out-Null 286 | } 287 | 288 | function Get-Online-Mode() { 289 | return $Script:GVM_AVAILABLE -and ! ($Script:GVM_FORCE_OFFLINE) 290 | } 291 | 292 | function Check-Online-Mode() { 293 | if ( ! (Get-Online-Mode) ) { 294 | throw 'This command is not available in offline mode.' 295 | } 296 | } 297 | 298 | function Invoke-API-Call([string]$Path, [string]$FileTarget, [switch]$IgnoreFailure) { 299 | try { 300 | $target = "$Script:PGVM_SERVICE/$Path" 301 | 302 | if ( $FileTarget ) { 303 | return Invoke-RestMethod $target -OutFile $FileTarget 304 | } 305 | 306 | return Invoke-RestMethod $target 307 | } catch { 308 | $Script:GVM_AVAILABLE = $false 309 | if ( ! ($IgnoreFailure) ) { 310 | Check-Online-Mode 311 | } else { 312 | return $null 313 | } 314 | } 315 | } 316 | 317 | function Cleanup-Directory($Path) { 318 | $dirStats = Get-ChildItem $Path -Recurse | Measure-Object -property length -sum 319 | Remove-Item -Force -Recurse $Path 320 | $count = $dirStats.Count 321 | $size = $dirStats.Sum/(1024*1024) 322 | Write-Output "$count archive(s) flushed, freeing $size MB" 323 | } 324 | 325 | function Handle-Broadcast($Command, $Broadcast) { 326 | $oldBroadcast = $null 327 | if (Test-Path $Script:PGVM_BROADCAST_PATH) { 328 | $oldBroadcast = (Get-Content $Script:PGVM_BROADCAST_PATH) -join "`n" 329 | Write-Verbose 'Old broadcast message loaded' 330 | } 331 | 332 | if ($oldBroadcast -ne $Broadcast -and !($Command -match 'b(roadcast)?') -and $Command -ne 'selfupdate' -and $Command -ne 'flush' ) { 333 | Write-Verbose 'Showing the new broadcast message' 334 | Set-Content $Script:PGVM_BROADCAST_PATH $Broadcast 335 | Write-Output $Broadcast 336 | } 337 | } 338 | 339 | function Init-Candidate-Cache() { 340 | if ( !(Test-Path $Script:PGVM_CANDIDATES_PATH) ) { 341 | throw 'Can not retrieve list of candidates' 342 | } 343 | 344 | $Script:GVM_CANDIDATES = (Get-Content $Script:PGVM_CANDIDATES_PATH).Split(',') 345 | Write-Verbose "Available candidates: $Script:GVM_CANDIDATES" 346 | } 347 | 348 | function Update-Candidates-Cache() { 349 | Write-Verbose 'Update candidates-cache from GVM-API' 350 | Check-Online-Mode 351 | Invoke-Api-Call 'app/version' $Script:GVM_API_VERSION_PATH 352 | Invoke-API-Call 'candidates' $Script:PGVM_CANDIDATES_PATH 353 | } 354 | 355 | function Write-Offline-Version-List($Candidate) { 356 | Write-Verbose 'Get version list from directory' 357 | 358 | Write-Output '------------------------------------------------------------' 359 | Write-Output "Offline Mode: only showing installed ${Candidate} versions" 360 | Write-Output '------------------------------------------------------------' 361 | Write-Output '' 362 | 363 | $current = Get-Current-Candidate-Version $Candidate 364 | $versions = Get-Installed-Candidate-Version-List $Candidate 365 | 366 | if ($versions) { 367 | foreach ($version in $versions) { 368 | if ($version -eq $current) { 369 | Write-Output " > $version" 370 | } else { 371 | Write-Output " * $version" 372 | } 373 | } 374 | } else { 375 | Write-Output ' None installed!' 376 | } 377 | 378 | Write-Output '------------------------------------------------------------' 379 | Write-Output '* - installed ' 380 | Write-Output '> - currently in use ' 381 | Write-Output '------------------------------------------------------------' 382 | } 383 | 384 | function Write-Version-List($Candidate) { 385 | Write-Verbose 'Get version list from API' 386 | 387 | $current = Get-Current-Candidate-Version $Candidate 388 | $versions = (Get-Installed-Candidate-Version-List $Candidate) -join ',' 389 | Invoke-API-Call "candidates/$Candidate/list?platform=posh¤t=$current&installed=$versions" | Write-Output 390 | } 391 | 392 | function Install-Local-Version($Candidate, $Version, $LocalPath) { 393 | $dir = Get-Item $LocalPath 394 | 395 | if ( !(Test-Path $dir -PathType Container) ) { 396 | throw "Local installation path $LocalPath is no directory" 397 | } 398 | 399 | Write-Output "Linking $Candidate $Version to $LocalPath" 400 | $link = "$Global:PGVM_DIR\$Candidate\$Version" 401 | Set-Junction-Via-Mklink $link $LocalPath 402 | Write-Output "Done installing!" 403 | } 404 | 405 | function Install-Remote-Version($Candidate, $Version) { 406 | 407 | if ( !(Test-Path $Script:PGVM_ARCHIVES_PATH) ) { 408 | New-Item -ItemType Directory $Script:PGVM_ARCHIVES_PATH | Out-Null 409 | } 410 | 411 | $archive = "$Script:PGVM_ARCHIVES_PATH\$Candidate-$Version.zip" 412 | if ( Test-Path $archive ) { 413 | Write-Output "Found a previously downloaded $Candidate $Version archive. Not downloading it again..." 414 | } else { 415 | Check-Online-Mode 416 | Write-Output "`nDownloading: $Candidate $Version`n" 417 | Download-File "$Script:PGVM_SERVICE/download/$Candidate/$Version`?platform=posh" $archive 418 | } 419 | 420 | Write-Output "Installing: $Candidate $Version" 421 | 422 | # create temp dir if necessary 423 | if ( !(Test-Path $Script:PGVM_TEMP_PATH) ) { 424 | New-Item -ItemType Directory $Script:PGVM_TEMP_PATH | Out-Null 425 | } 426 | 427 | # unzip downloaded archive 428 | Unzip-Archive $archive $Script:PGVM_TEMP_PATH 429 | 430 | # check if unzip successfully 431 | if ( !(Test-Path "$Script:PGVM_TEMP_PATH\*-$Version") ) { 432 | throw "Could not unzip the archive of $Candidate $Version. Please delete archive from $Script:PGVM_ARCHIVES_PATH (or delete all with 'gvm flush archives'" 433 | } 434 | 435 | # move to target location 436 | # Move was replaced by copy and remove because of random access denied errors 437 | # when Unzip was done by via -com shell.application 438 | # Move-Item "$Script:PGVM_TEMP_PATH\*-$Version" "$Global:PGVM_DIR\$Candidate\$Version" 439 | Copy-Item "$Script:PGVM_TEMP_PATH\*-$Version" "$Global:PGVM_DIR\$Candidate\$Version" -Recurse 440 | Remove-Item "$Script:PGVM_TEMP_PATH\*-$Version" -Recurse -Force 441 | Write-Output "Done installing!" 442 | } 443 | 444 | function Unzip-Archive($Archive, $Target) { 445 | if ( $Script:SEVENZ_On_PATH ) { 446 | $zipProcess = Start-Process 7z.exe -ArgumentList "x -o`"$Target`" -y `"$Archive`"" -Wait -PassThru -NoNewWindow 447 | 448 | if ($zipProcess.ExitCode -ne 0) { 449 | Remove-Item $Target -Recurse -Force 450 | } 451 | } elseif ( $Script:UNZIP_ON_PATH ) { 452 | unzip.exe -oq $Archive -d $Target 453 | } else { 454 | # use the windows shell as general fallback (no working on Windows Server Core because there is no shell) 455 | $shell = New-Object -com shell.application 456 | $shell.namespace($Target).copyhere($shell.namespace($Archive).items(), 0x10) 457 | } 458 | } 459 | 460 | function Download-File($Url, $TargetFile) { 461 | <# 462 | Adepted from http://blogs.msdn.com/b/jasonn/archive/2008/06/13/downloading-files-from-the-internet-in-powershell-with-progress.aspx 463 | #> 464 | Write-Verbose "Try to download $Url with HttpWebRequest" 465 | $uri = New-Object "System.Uri" $Url 466 | $request = [System.Net.HttpWebRequest]::Create($uri) 467 | $request.set_Timeout(15000) 468 | $response = $request.GetResponse() 469 | $totalLength = [System.Math]::Floor($response.get_ContentLength()/1024) 470 | $responseStream = $response.GetResponseStream() 471 | $targetStream = New-Object -TypeName System.IO.FileStream -ArgumentList $targetFile, Create 472 | $buffer = new-object byte[] 10KB 473 | $count = $responseStream.Read($buffer,0,$buffer.length) 474 | $downloadedBytes = $count 475 | while ($count -gt 0) 476 | { 477 | if ($totalLength -lt 0) { 478 | $totalLength = [System.Math]::Floor($response.get_ContentLength()/1024) 479 | } 480 | [System.Console]::CursorLeft = 0 481 | [System.Console]::Write("Downloaded {0}K of {1}K", [System.Math]::Floor($downloadedBytes/1024), $totalLength) 482 | $targetStream.Write($buffer, 0, $count) 483 | $count = $responseStream.Read($buffer,0,$buffer.length) 484 | $downloadedBytes = $downloadedBytes + $count 485 | } 486 | $targetStream.Flush() 487 | $targetStream.Close() 488 | $targetStream.Dispose() 489 | $responseStream.Dispose() 490 | Write-Output '' 491 | } 492 | -------------------------------------------------------------------------------- /Commands.Tests.ps1: -------------------------------------------------------------------------------- 1 | . .\Commands.ps1 2 | . .\Utils.ps1 3 | . .\Init.ps1 4 | . .\TestUtils.ps1 5 | 6 | Describe 'gvm' { 7 | Context 'No posh-gvm dir available'{ 8 | $Script:GVM_FORCE_OFFLINE = $true 9 | Mock-PGVM-Dir 10 | Remove-Item $global:PGVM_DIR -Recurse 11 | Mock Init-Posh-Gvm -verifiable 12 | Mock Init-Candidate-Cache -verifiable 13 | Mock Show-Help 14 | gvm 15 | 16 | It 'initalize posh-gvm' { 17 | Assert-VerifiableMocks 18 | } 19 | 20 | It 'prints help' { 21 | Assert-MockCalled Show-Help 1 22 | } 23 | 24 | Reset-PGVM-Dir 25 | } 26 | 27 | Context 'Posh-gvm dir available'{ 28 | $Script:GVM_FORCE_OFFLINE = $true 29 | Mock-PGVM-Dir 30 | Mock Init-Posh-Gvm 31 | Mock Init-Candidate-Cache -verifiable 32 | Mock Show-Help 33 | gvm 34 | 35 | It 'initalize posh-gvm' { 36 | Assert-VerifiableMocks 37 | } 38 | 39 | It 'does not init again' { 40 | Assert-MockCalled Init-Posh-Gvm 0 41 | } 42 | 43 | It 'prints help' { 44 | Assert-MockCalled Show-Help 1 45 | } 46 | 47 | } 48 | 49 | Context 'posh-gvm is forced offline' { 50 | Mock-PGVM-DIR 51 | Mock Init-Candidate-Cache -verifiable 52 | Mock Check-Available-Broadcast 53 | Mock Show-Help -verifiable 54 | $Script:GVM_FORCE_OFFLINE = $true 55 | 56 | gvm 57 | 58 | It 'does not load broadcast message from api' { 59 | Assert-MockCalled Check-Available-Broadcast 0 60 | } 61 | 62 | It 'performs default command actions' { 63 | Assert-VerifiableMocks 64 | } 65 | 66 | Reset-PGVM-DIR 67 | } 68 | 69 | Context 'posh-gvm offline command called' { 70 | Mock-PGVM-DIR 71 | Mock Init-Candidate-Cache -verifiable 72 | Mock Check-Available-Broadcast 73 | Mock Set-Offline-Mode -verifiable 74 | $Script:GVM_FORCE_OFFLINE = $false 75 | 76 | gvm offline 77 | 78 | It 'does not load broadcast message from api' { 79 | Assert-MockCalled Check-Available-Broadcast 0 80 | } 81 | 82 | It 'performs offline command actions' { 83 | Assert-VerifiableMocks 84 | } 85 | 86 | Reset-PGVM-DIR 87 | } 88 | 89 | Context 'posh-gvm online and command i called' { 90 | Mock-Dispatcher-Test 91 | Mock Install-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.2' -and $InstallPath -eq '\bla' } 92 | 93 | gvm i grails 2.2.2 \bla 94 | 95 | It 'checks for new broadcast, inits the Candidate-Cache and calls install-command' { 96 | Assert-VerifiableMocks 97 | } 98 | 99 | Reset-Dispatcher-Test 100 | } 101 | 102 | Context 'posh-gvm online and command install called' { 103 | Mock-Dispatcher-Test 104 | Mock Install-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.2' -and $InstallPath -eq '' } 105 | 106 | gvm install grails 2.2.2 107 | 108 | It 'checks for new broadcast, inits the Candidate-Cache and calls install-command' { 109 | Assert-VerifiableMocks 110 | } 111 | 112 | Reset-Dispatcher-Test 113 | } 114 | 115 | Context 'posh-gvm online and command uninstall called' { 116 | Mock-Dispatcher-Test 117 | Mock Uninstall-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.2' } 118 | 119 | gvm uninstall grails 2.2.2 120 | 121 | It 'checks for new broadcast, inits the Candidate-Cache and calls uninstall-command' { 122 | Assert-VerifiableMocks 123 | } 124 | 125 | Reset-Dispatcher-Test 126 | } 127 | 128 | Context 'posh-gvm online and command rm called' { 129 | Mock-Dispatcher-Test 130 | Mock Uninstall-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' } 131 | 132 | gvm rm grails 2.2.1 133 | 134 | It 'checks for new broadcast, inits the Candidate-Cache and calls uninstall-command' { 135 | Assert-VerifiableMocks 136 | } 137 | 138 | Reset-Dispatcher-Test 139 | } 140 | 141 | Context 'posh-gvm online and command ls called' { 142 | Mock-Dispatcher-Test 143 | Mock List-Candidate-Versions -verifiable -parameterFilter { $Candidate -eq 'grails' } 144 | 145 | gvm ls grails 146 | 147 | It 'checks for new broadcast, inits the Candidate-Cache and calls list-command' { 148 | Assert-VerifiableMocks 149 | } 150 | 151 | Reset-Dispatcher-Test 152 | } 153 | 154 | Context 'posh-gvm online and command list called' { 155 | Mock-Dispatcher-Test 156 | Mock List-Candidate-Versions -verifiable -parameterFilter { $Candidate -eq 'grails' } 157 | 158 | gvm list grails 159 | 160 | It 'checks for new broadcast, inits the Candidate-Cache and calls list-command' { 161 | Assert-VerifiableMocks 162 | } 163 | 164 | Reset-Dispatcher-Test 165 | } 166 | 167 | Context 'posh-gvm online and command u called' { 168 | Mock-Dispatcher-Test 169 | Mock Use-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' } 170 | 171 | gvm u grails 2.2.1 172 | 173 | It 'checks for new broadcast, inits the Candidate-Cache and calls use-command' { 174 | Assert-VerifiableMocks 175 | } 176 | 177 | Reset-Dispatcher-Test 178 | } 179 | 180 | Context 'posh-gvm online and command use called' { 181 | Mock-Dispatcher-Test 182 | Mock Use-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' } 183 | 184 | gvm use grails 2.2.1 185 | 186 | It 'checks for new broadcast, inits the Candidate-Cache and calls use-command' { 187 | Assert-VerifiableMocks 188 | } 189 | 190 | Reset-Dispatcher-Test 191 | } 192 | 193 | Context 'posh-gvm online and command d called' { 194 | Mock-Dispatcher-Test 195 | Mock Set-Default-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' } 196 | 197 | gvm d grails 2.2.1 198 | 199 | It 'checks for new broadcast, inits the Candidate-Cache and calls default-command' { 200 | Assert-VerifiableMocks 201 | } 202 | 203 | Reset-Dispatcher-Test 204 | } 205 | 206 | Context 'posh-gvm online and command default called' { 207 | Mock-Dispatcher-Test 208 | Mock Set-Default-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' } 209 | 210 | gvm default grails 2.2.1 211 | 212 | It 'checks for new broadcast, inits the Candidate-Cache and calls default-command' { 213 | Assert-VerifiableMocks 214 | } 215 | 216 | Reset-Dispatcher-Test 217 | } 218 | 219 | Context 'posh-gvm online and command c called' { 220 | Mock-Dispatcher-Test 221 | Mock Show-Current-Version -verifiable -parameterFilter { $Candidate -eq 'grails' } 222 | 223 | gvm c grails 224 | 225 | It 'checks for new broadcast, inits the Candidate-Cache and calls current-command' { 226 | Assert-VerifiableMocks 227 | } 228 | 229 | Reset-Dispatcher-Test 230 | } 231 | 232 | Context 'posh-gvm online and command current called' { 233 | Mock-Dispatcher-Test 234 | Mock Show-Current-Version -verifiable -parameterFilter { $Candidate -eq 'grails' } 235 | 236 | gvm current grails 237 | 238 | It 'checks for new broadcast, inits the Candidate-Cache and calls current-command' { 239 | Assert-VerifiableMocks 240 | } 241 | 242 | Reset-Dispatcher-Test 243 | } 244 | 245 | Context 'posh-gvm online and command v called' { 246 | Mock-Dispatcher-Test 247 | Mock Show-Posh-Gvm-Version -verifiable 248 | 249 | gvm v 250 | 251 | It 'checks for new broadcast, inits the Candidate-Cache and calls version-command' { 252 | Assert-VerifiableMocks 253 | } 254 | 255 | Reset-Dispatcher-Test 256 | } 257 | 258 | Context 'posh-gvm online and command version called' { 259 | Mock-Dispatcher-Test 260 | Mock Show-Posh-Gvm-Version -verifiable 261 | 262 | gvm version 263 | 264 | It 'checks for new broadcast, inits the Candidate-Cache and calls version-command' { 265 | Assert-VerifiableMocks 266 | } 267 | 268 | Reset-Dispatcher-Test 269 | } 270 | 271 | Context 'posh-gvm online and command b called' { 272 | Mock-Dispatcher-Test 273 | Mock Show-Broadcast-Message -verifiable 274 | 275 | gvm b 276 | 277 | It 'checks for new broadcast, inits the Candidate-Cache and calls broadcast-command' { 278 | Assert-VerifiableMocks 279 | } 280 | 281 | Reset-Dispatcher-Test 282 | } 283 | 284 | Context 'posh-gvm online and command broadcast called' { 285 | Mock-Dispatcher-Test 286 | Mock Show-Broadcast-Message -verifiable 287 | 288 | gvm broadcast 289 | 290 | It 'checks for new broadcast, inits the Candidate-Cache and calls broadcast-command' { 291 | Assert-VerifiableMocks 292 | } 293 | 294 | Reset-Dispatcher-Test 295 | } 296 | 297 | Context 'posh-gvm online and command h called' { 298 | Mock-Dispatcher-Test 299 | Mock Show-Help -verifiable 300 | 301 | gvm h 302 | 303 | It 'checks for new broadcast, inits the Candidate-Cache and calls help-command' { 304 | Assert-VerifiableMocks 305 | } 306 | 307 | Reset-Dispatcher-Test 308 | } 309 | 310 | Context 'posh-gvm online and command help called' { 311 | Mock-Dispatcher-Test 312 | Mock Show-Help -verifiable 313 | 314 | gvm help 315 | 316 | It 'checks for new broadcast, inits the Candidate-Cache and calls help-command' { 317 | Assert-VerifiableMocks 318 | } 319 | 320 | Reset-Dispatcher-Test 321 | } 322 | 323 | Context 'posh-gvm online and command offline called' { 324 | Mock-Dispatcher-Test -Offline 325 | Mock Set-Offline-Mode -verifiable -parameterFilter { $Flag -eq 'enable' } 326 | 327 | gvm offline enable 328 | 329 | It 'checks for new broadcast, inits the Candidate-Cache and calls offline-command' { 330 | Assert-VerifiableMocks 331 | } 332 | 333 | Reset-Dispatcher-Test 334 | } 335 | 336 | Context 'posh-gvm online and command selfupdate called' { 337 | Mock-Dispatcher-Test 338 | Mock Invoke-Self-Update -verifiable 339 | 340 | gvm selfupdate 341 | 342 | It 'checks for new broadcast, inits the Candidate-Cache and calls selfupdate-command' { 343 | Assert-VerifiableMocks 344 | } 345 | 346 | Reset-Dispatcher-Test 347 | } 348 | 349 | Context 'posh-gvm online and command flush called' { 350 | Mock-Dispatcher-Test 351 | Mock Flush-Cache -verifiable -parameterFilter { $DataType -eq 'version' } 352 | 353 | gvm flush version 354 | 355 | It 'checks for new broadcast, inits the Candidate-Cache and calls flush-command' { 356 | Assert-VerifiableMocks 357 | } 358 | 359 | Reset-Dispatcher-Test 360 | } 361 | } 362 | 363 | Describe 'Install-Candidate-Version' { 364 | Context 'Remote Version already installed' { 365 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 366 | Mock Check-Candidate-Version-Available { '1.1.1' } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 367 | Mock Is-Candidate-Version-Locally-Available { $true } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 368 | 369 | It 'throw an error' { 370 | { Install-Candidate-Version grails 1.1.1 } | Should Throw 371 | } 372 | 373 | It 'process precondition checks' { 374 | Assert-VerifiableMocks 375 | } 376 | } 377 | 378 | Context 'Local Version already installed' { 379 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 380 | Mock Check-Candidate-Version-Available { throw 'error' } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 381 | Mock Is-Candidate-Version-Locally-Available { $true } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 382 | 383 | It 'throw an error' { 384 | { Install-Candidate-Version grails 1.1.1 \bla } | Should Throw 385 | } 386 | 387 | It 'process precondition checks' { 388 | Assert-VerifiableMocks 389 | } 390 | } 391 | 392 | Context 'Local path but version is remote available already installed' { 393 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 394 | Mock Check-Candidate-Version-Available { 1.1.1 } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 395 | 396 | It 'throw an error' { 397 | { Install-Candidate-Version grails 1.1.1 \bla } | Should Throw 398 | } 399 | 400 | It 'process precondition checks' { 401 | Assert-VerifiableMocks 402 | } 403 | } 404 | 405 | Context 'Local version installation without defaulting' { 406 | $backupAutoAnswer = $Global:PGVM_AUTO_ANSWER 407 | $Global:PGVM_AUTO_ANSWER = $false 408 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 409 | Mock Check-Candidate-Version-Available { throw 'error' } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 410 | Mock Is-Candidate-Version-Locally-Available { $false } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 411 | Mock Install-Local-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' -and $LocalPath -eq '\bla' } 412 | Mock Read-Host { 'n' } 413 | Mock Set-Linked-Candidate-Version 414 | 415 | Install-Candidate-Version grails 1.1.1 \bla 416 | 417 | It 'installs the local version' { 418 | Assert-VerifiableMocks 419 | } 420 | 421 | It "does not set default" { 422 | Assert-MockCalled Set-Linked-Candidate-Version 0 423 | } 424 | 425 | $Global:PGVM_AUTO_ANSWER = $backupAutoAnswer 426 | } 427 | 428 | Context 'Local version installation with auto defaulting' { 429 | $backupAutoAnswer = $Global:PGVM_AUTO_ANSWER 430 | $Global:PGVM_AUTO_ANSWER = $true 431 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 432 | Mock Check-Candidate-Version-Available { throw 'error' } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 433 | Mock Is-Candidate-Version-Locally-Available { $false } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 434 | Mock Install-Local-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' -and $LocalPath -eq '\bla' } 435 | Mock Set-Linked-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 436 | Mock Write-Output -verifiable 437 | 438 | Install-Candidate-Version grails 1.1.1 \bla 439 | 440 | It 'installs the local version' { 441 | Assert-VerifiableMocks 442 | } 443 | 444 | $Global:PGVM_AUTO_ANSWER = $backupAutoAnswer 445 | } 446 | 447 | Context 'Remote version installation with prompt defaulting' { 448 | $backupAutoAnswer = $Global:PGVM_AUTO_ANSWER 449 | $Global:PGVM_AUTO_ANSWER = $false 450 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 451 | Mock Check-Candidate-Version-Available { '1.1.1' } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 452 | Mock Is-Candidate-Version-Locally-Available { $false } -verifiable { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 453 | Mock Install-Remote-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 454 | Mock Read-Host { 'y' } 455 | Mock Set-Linked-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 456 | Mock Write-Output -verifiable 457 | 458 | Install-Candidate-Version grails 1.1.1 459 | 460 | It 'installs the local version' { 461 | Assert-VerifiableMocks 462 | } 463 | 464 | $Global:PGVM_AUTO_ANSWER = $backupAutoAnswer 465 | } 466 | } 467 | 468 | Describe 'Uninstall-Candidate-Version' { 469 | Context 'No version is provided' { 470 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 471 | It 'throws an error' { 472 | { Uninstall-Candidate-Version grails } | Should Throw 473 | } 474 | } 475 | 476 | Context 'To be uninstalled version is not installed' { 477 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 478 | Mock Is-Candidate-Version-Locally-Available { $false } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '24.3' } 479 | 480 | It 'throws an error' { 481 | { Uninstall-Candidate-Version grails 24.3 } | Should Throw 482 | } 483 | 484 | It 'checks candidate' { 485 | Assert-VerifiableMocks 486 | } 487 | } 488 | 489 | Context 'To be uninstalled Version is current version' { 490 | Mock-PGVM-Dir 491 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\24.3" | Out-Null 492 | Set-Linked-Candidate-Version grails 24.3 493 | 494 | It 'finds current-junction defined' { 495 | Test-Path "$Global:PGVM_DIR\grails\current" | Should Be $true 496 | } 497 | 498 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 499 | Mock Is-Candidate-Version-Locally-Available { $true } -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '24.3' } 500 | Mock Get-Current-Candidate-Version { '24.3' } -verifiable -parameterFilter { $Candidate -eq 'grails' } 501 | Mock Write-Output -verifiable 502 | 503 | Uninstall-Candidate-Version grails 24.3 504 | 505 | It 'delete the current-junction' { 506 | Test-Path "$Global:PGVM_DIR\grails\current" | Should Be $false 507 | } 508 | 509 | It 'delete the version' { 510 | Test-Path "$Global:PGVM_DIR\grails\24.3" | Should Be $false 511 | } 512 | 513 | It "checks different preconditions correctly" { 514 | Assert-VerifiableMocks 515 | } 516 | 517 | Reset-PGVM-Dir 518 | } 519 | 520 | Context 'To be uninstalled version is installed' { 521 | Mock-PGVM-Dir 522 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\24.3" | Out-Null 523 | 524 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 525 | Mock Is-Candidate-Version-Locally-Available { $true } -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '24.3'} 526 | Mock Get-Current-Candidate-Version { $null } -verifiable -parameterFilter { $Candidate -eq 'grails' } 527 | Mock Write-Output -verifiable 528 | 529 | Uninstall-Candidate-Version grails 24.3 530 | 531 | It 'delete the version' { 532 | Test-Path "$Global:PGVM_DIR\grails\24.3" | Should Be $false 533 | } 534 | 535 | It "checks different preconditions correctly" { 536 | Assert-VerifiableMocks 537 | } 538 | 539 | Reset-PGVM-Dir 540 | } 541 | } 542 | 543 | Describe 'List-Candidate-Versions' { 544 | Context 'if in online mode' { 545 | Mock-Online 546 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 547 | Mock Write-Version-List -verifiable -parameterFilter { $Candidate -eq 'grails' } 548 | 549 | List-Candidate-Versions grails 550 | 551 | It 'write the version list retrieved from api' { 552 | Assert-VerifiableMocks 553 | } 554 | } 555 | 556 | Context 'If in offline mode' { 557 | Mock-Offline 558 | Mock Check-Candidate-Present -verifiable -parameterFilter { $Candidate -eq 'grails' } 559 | Mock Write-Offline-Version-List -verifiable -parameterFilter { $Candidate -eq 'grails' } 560 | 561 | List-Candidate-Versions grails 562 | 563 | It 'write the version list based on local file structure' { 564 | Assert-VerifiableMocks 565 | } 566 | } 567 | } 568 | 569 | Describe 'Use-Candidate-Version' { 570 | Context 'If new use version is already used' { 571 | Mock Check-Candidate-Version-Available { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 572 | Mock Get-Env-Candidate-Version { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' } 573 | Mock Write-Output -verifiable 574 | Mock Check-Candidate-Version-Locally-Available 575 | 576 | Use-Candidate-Version grails 1.1.1 577 | 578 | It 'changes nothing' { 579 | Assert-VerifiableMocks 580 | } 581 | 582 | It 'does not test candidate version' { 583 | Assert-MockCalled Check-Candidate-Version-Locally-Available 0 584 | } 585 | } 586 | 587 | Context 'If setting a different version as the current version to use' { 588 | Mock Check-Candidate-Version-Available { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 589 | Mock Get-Env-Candidate-Version { '1.1.0' } -parameterFilter { $Candidate -eq 'grails' } 590 | Mock Write-Output -verifiable 591 | Mock Check-Candidate-Version-Locally-Available -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 592 | Mock Set-Env-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 593 | 594 | Use-Candidate-Version grails 1.1.1 595 | 596 | It 'perform the changes' { 597 | Assert-VerifiableMocks 598 | } 599 | } 600 | } 601 | 602 | Describe 'Set-Default-Version' { 603 | Context 'If new default is already default' { 604 | Mock Check-Candidate-Version-Available { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 605 | Mock Get-Current-Candidate-Version { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' } 606 | Mock Write-Output -verifiable 607 | Mock Check-Candidate-Version-Locally-Available 608 | 609 | Set-Default-Version grails 1.1.1 610 | 611 | It 'changes nothing' { 612 | Assert-VerifiableMocks 613 | } 614 | 615 | It 'does not test candidate version' { 616 | Assert-MockCalled Check-Candidate-Version-Locally-Available 0 617 | } 618 | } 619 | 620 | Context 'If setting a new default' { 621 | Mock Check-Candidate-Version-Available { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 622 | Mock Get-Current-Candidate-Version { '1.1.0' } -parameterFilter { $Candidate -eq 'grails' } 623 | Mock Write-Output -verifiable 624 | Mock Check-Candidate-Version-Locally-Available -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 625 | Mock Set-Linked-Candidate-Version -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '1.1.1' } 626 | 627 | Set-Default-Version grails 1.1.1 628 | 629 | It 'perform the changes' { 630 | Assert-VerifiableMocks 631 | } 632 | } 633 | } 634 | 635 | Describe 'Show-Current-Version' { 636 | Context 'If called without candidate' { 637 | $Script:GVM_CANDIDATES = @('grails','groovy','bla') 638 | Mock Get-Env-Candidate-Version { '1.1.0' } -parameterFilter { $Candidate -eq 'grails' } 639 | Mock Get-Env-Candidate-Version { '2.1.0' } -parameterFilter { $Candidate -eq 'groovy' } 640 | Mock Get-Env-Candidate-Version { '0.1.0' } -parameterFilter { $Candidate -eq 'bla' } 641 | Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'Using:' } 642 | Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'grails: 1.1.0' } 643 | Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'groovy: 2.1.0' } 644 | Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'bla: 0.1.0' } 645 | 646 | Show-Current-Version 647 | 648 | It 'write the version for all currently used candidates' { 649 | Assert-VerifiableMocks 650 | } 651 | } 652 | 653 | Context 'If called with specifiv candidate and version available' { 654 | Mock Check-Candidate-Present -verifiable 655 | Mock Get-Env-Candidate-Version { '1.1.0' } -parameterFilter { $Candidate -eq 'grails' } 656 | Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'Using grails version 1.1.0' } 657 | 658 | Show-Current-Version grails 659 | 660 | It 'write version info' { 661 | Assert-VerifiableMocks 662 | } 663 | } 664 | 665 | Context 'If called with specifiv candidate and no version available' { 666 | Mock Check-Candidate-Present -verifiable 667 | Mock Get-Env-Candidate-Version { $null } -parameterFilter { $Candidate -eq 'grails' } 668 | Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'Not using any version of grails' } 669 | 670 | Show-Current-Version grails 671 | 672 | It 'write no version is available' { 673 | Assert-VerifiableMocks 674 | } 675 | } 676 | } 677 | 678 | Describe 'Show-Posh-Gvm-Version' { 679 | Context 'When called' { 680 | Mock Get-GVM-API-Version -verifiable 681 | Mock Get-Posh-Gvm-Version -verifiable 682 | Mock Write-Output -verifiable 683 | 684 | Show-Posh-Gvm-Version 685 | 686 | It 'write the version message to output' { 687 | Assert-VerifiableMocks 688 | } 689 | } 690 | } 691 | 692 | Describe 'Show-Broadcast-Message' { 693 | Context 'When called' { 694 | $Script:PGVM_BROADCAST_PATH = 'broadcast' 695 | Mock Get-Content { 'broadcast' } -verifiable -parameterFilter { $Path -eq 'broadcast' } 696 | Mock Write-Output -verifiable 697 | 698 | Show-Broadcast-Message 699 | 700 | It 'Write broadcast message to output' { 701 | Assert-VerifiableMocks 702 | } 703 | } 704 | } 705 | 706 | Describe 'Set-Offline-Mode' { 707 | Context 'If called with invalid flag' { 708 | It 'throws an error' { 709 | { Set-Offline-Mode invalid } | Should Throw 710 | } 711 | } 712 | 713 | Context 'If called with enable flag' { 714 | $Script:GVM_FORCE_OFFLINE = $false 715 | Mock Write-Output -verifiable 716 | 717 | Set-Offline-Mode enable 718 | 719 | It "set offline mode" { 720 | $Script:GVM_FORCE_OFFLINE | Should Be $true 721 | } 722 | 723 | It "writes info to output" { 724 | Assert-VerifiableMocks 725 | } 726 | } 727 | 728 | Context 'if called with disable flag' { 729 | $Script:GVM_ONLINE = $false 730 | $Script:GVM_FORCE_OFFLINE = $true 731 | Mock Write-Output -verifiable 732 | 733 | Set-Offline-Mode disable 734 | 735 | It "deactivate offline mode" { 736 | $Script:GVM_FORCE_OFFLINE | Should Be $false 737 | } 738 | 739 | It "set gvm to online" { 740 | $Script:GVM_ONLINE | Should Be $true 741 | } 742 | 743 | It "writes info to output" { 744 | Assert-VerifiableMocks 745 | } 746 | } 747 | } 748 | 749 | Describe 'Flush-Cache' { 750 | Context 'Try to delete existing candidates cache' { 751 | $Script:PGVM_CANDIDATES_PATH = 'test' 752 | Mock Test-Path { $true } -parameterFilter { $Path -eq 'test' } 753 | Mock Remove-Item -verifiable -parameterFilter { $Path -eq 'test' } 754 | Mock Write-Output -verifiable 755 | 756 | Flush-Cache candidates 757 | 758 | It 'deletes the file and writes flush message' { 759 | Assert-VerifiableMocks 760 | } 761 | } 762 | 763 | Context 'Try to delete non-existing candidates cache' { 764 | $Script:PGVM_CANDIDATES_PATH = 'test2' 765 | Mock Test-Path { $false } -parameterFilter { $Path -eq 'test2' } 766 | Mock Write-Warning -verifiable 767 | 768 | Flush-Cache candidates 769 | 770 | It 'writes warning about non existing file' { 771 | Assert-VerifiableMocks 772 | } 773 | } 774 | 775 | Context 'Try to delete existing broadcast cache' { 776 | $Script:PGVM_BROADCAST_PATH = 'test' 777 | Mock Test-Path { $true } -parameterFilter { $Path -eq 'test' } 778 | Mock Remove-Item -verifiable -parameterFilter { $Path -eq 'test' } 779 | Mock Write-Output -verifiable 780 | 781 | Flush-Cache broadcast 782 | 783 | It 'deletes the file and writes flush message' { 784 | Assert-VerifiableMocks 785 | } 786 | } 787 | 788 | Context 'Try to delete non-existing broadcast cache' { 789 | $Script:PGVM_BROADCAST_PATH = 'test2' 790 | Mock Test-Path { $false } -parameterFilter { $Path -eq 'test2' } 791 | Mock Write-Warning -verifiable 792 | 793 | Flush-Cache broadcast 794 | 795 | It 'writes warning about non existing file' { 796 | Assert-VerifiableMocks 797 | } 798 | } 799 | 800 | Context 'Try to delete existing version cache' { 801 | $Script:GVM_API_VERSION_PATH = 'test' 802 | Mock Test-Path { $true } -parameterFilter { $Path -eq 'test' } 803 | Mock Remove-Item -verifiable -parameterFilter { $Path -eq 'test' } 804 | Mock Write-Output -verifiable 805 | 806 | Flush-Cache version 807 | 808 | It 'deletes the file and writes flush message' { 809 | Assert-VerifiableMocks 810 | } 811 | } 812 | 813 | Context 'Try to delete non-existing version cache' { 814 | $Script:GVM_API_VERSION_PATH = 'test2' 815 | Mock Test-Path { $false } -parameterFilter { $Path -eq 'test2' } 816 | Mock Write-Warning -verifiable 817 | 818 | Flush-Cache version 819 | 820 | It 'writes warning about non existing file' { 821 | Assert-VerifiableMocks 822 | } 823 | } 824 | 825 | Context 'Cleanup archives directory' { 826 | $Script:PGVM_ARCHIVES_PATH = 'archives' 827 | Mock Cleanup-Directory -verifiable -parameterFilter { $Path -eq 'archives' } 828 | 829 | Flush-Cache archives 830 | 831 | It 'cleanup archives directory' { 832 | Assert-VerifiableMocks 833 | } 834 | } 835 | 836 | Context 'Cleanup temp directory' { 837 | $Script:PGVM_TEMP_PATH = 'temp' 838 | Mock Cleanup-Directory -verifiable -parameterFilter { $Path -eq 'temp' } 839 | 840 | Flush-Cache temp 841 | 842 | It 'cleanup temp directory' { 843 | Assert-VerifiableMocks 844 | } 845 | } 846 | 847 | Context 'Cleanup tmp directory' { 848 | $Script:PGVM_TEMP_PATH = 'temp' 849 | Mock Cleanup-Directory -verifiable -parameterFilter { $Path -eq 'temp' } 850 | 851 | Flush-Cache tmp 852 | 853 | It 'cleanup temp directory' { 854 | Assert-VerifiableMocks 855 | } 856 | } 857 | 858 | Context 'flush invalid parameter' { 859 | It 'throws an error' { 860 | { Flush-Cache invalid } | Should Throw 861 | } 862 | } 863 | } 864 | 865 | Describe 'Show-Help' { 866 | Context 'If Show-Help is called' { 867 | Mock Write-Output -verifiable 868 | 869 | Show-Help 870 | 871 | It 'write the help to the output' { 872 | Assert-VerifiableMocks 873 | } 874 | } 875 | } 876 | -------------------------------------------------------------------------------- /Utils.Tests.ps1: -------------------------------------------------------------------------------- 1 | . .\Utils.ps1 2 | . .\TestUtils.ps1 3 | 4 | Describe 'Check-GVM-API-Version' { 5 | Context 'API offline' { 6 | $Script:GVM_AVAILABLE = $true 7 | $Script:GVM_API_NEW_VERSION = $false 8 | Mock Get-GVM-API-Version 9 | Mock Invoke-API-Call { throw 'error' } -parameterFilter { $Path -eq 'app/Version' } 10 | 11 | Check-GVM-API-Version 12 | 13 | It 'the error handling set the app in offline mode' { 14 | $Script:GVM_AVAILABLE | Should be $false 15 | } 16 | 17 | It 'does not informs about new version' { 18 | $Script:GVM_API_NEW_VERSION | Should Be $false 19 | } 20 | } 21 | 22 | Context 'No new version' { 23 | $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE 24 | $Global:PGVM_AUTO_SELFUPDATE = $true 25 | $Script:GVM_API_NEW_VERSION = $false 26 | 27 | Mock Get-GVM-API-Version { 1.2.2 } 28 | Mock Invoke-API-Call { 1.2.2 } -parameterFilter { $Path -eq 'app/Version' } 29 | Mock Invoke-Self-Update 30 | 31 | Check-GVM-API-Version 32 | 33 | It 'do nothing' { 34 | Assert-MockCalled Invoke-Self-Update 0 35 | } 36 | 37 | It 'does not informs about new version' { 38 | $Script:GVM_API_NEW_VERSION | Should Be $false 39 | } 40 | 41 | $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE 42 | } 43 | 44 | Context 'New version and no auto selfupdate' { 45 | $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE 46 | $Global:PGVM_AUTO_SELFUPDATE = $false 47 | $Script:GVM_API_NEW_VERSION = $false 48 | 49 | Mock Get-GVM-API-Version { '1.2.2' } 50 | Mock Invoke-API-Call { '1.2.3' } -parameterFilter { $Path -eq 'app/Version' } 51 | 52 | Check-GVM-API-Version 53 | 54 | It 'informs about new version' { 55 | $Script:GVM_API_NEW_VERSION | Should Be $true 56 | } 57 | 58 | It 'write a warning about needed update' { 59 | Assert-VerifiableMocks 60 | } 61 | 62 | $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE 63 | } 64 | 65 | Context 'New version and auto selfupdate' { 66 | $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE 67 | $Global:PGVM_AUTO_SELFUPDATE = $true 68 | $Script:GVM_API_NEW_VERSION = $false 69 | 70 | Mock Get-GVM-API-Version { '1.2.2' } 71 | Mock Invoke-API-Call { '1.2.3' } -parameterFilter { $Path -eq 'app/Version' } 72 | Mock Invoke-Self-Update -verifiable 73 | 74 | Check-GVM-API-Version 75 | 76 | It 'updates self' { 77 | Assert-VerifiableMocks 78 | } 79 | 80 | It 'does not informs about new version' { 81 | $Script:GVM_API_NEW_VERSION | Should Be $false 82 | } 83 | 84 | $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE 85 | } 86 | } 87 | 88 | Describe 'Check-Posh-Gvm-Version' { 89 | Context 'No new Version' { 90 | $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE 91 | $Global:PGVM_AUTO_SELFUPDATE = $false 92 | $Script:PGVM_NEW_VERSION = $false 93 | 94 | Mock Is-New-Posh-GVM-Version-Available { $false } 95 | Mock Invoke-Self-Update 96 | 97 | Check-Posh-Gvm-Version 98 | 99 | It 'does not update itself' { 100 | Assert-MockCalled Invoke-Self-Update -Times 0 101 | } 102 | 103 | It 'does not informs about new version' { 104 | $Script:PGVM_NEW_VERSION | Should Be $false 105 | } 106 | 107 | $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE 108 | } 109 | 110 | Context 'New version and no auto selfupdate' { 111 | $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE 112 | $Global:PGVM_AUTO_SELFUPDATE = $false 113 | $Script:PGVM_NEW_VERSION = $false 114 | 115 | Mock Is-New-Posh-GVM-Version-Available { $true } 116 | Mock Invoke-Self-Update 117 | 118 | Check-Posh-Gvm-Version 119 | 120 | It 'informs about new version' { 121 | $Script:PGVM_NEW_VERSION | Should Be $true 122 | } 123 | 124 | It 'does not update itself' { 125 | Assert-MockCalled Invoke-Self-Update -Times 0 126 | } 127 | 128 | $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE 129 | } 130 | 131 | Context 'New version and auto selfupdate' { 132 | $backup_Global_PGVM_AUTO_SELFUPDTE = $Global:PGVM_AUTO_SELFUPDATE 133 | $Global:PGVM_AUTO_SELFUPDATE = $true 134 | $Script:PGVM_NEW_VERSION = $false 135 | 136 | Mock Is-New-Posh-GVM-Version-Available { $true } 137 | Mock Invoke-Self-Update -verifiable 138 | 139 | Check-Posh-Gvm-Version 140 | 141 | It 'updates self' { 142 | Assert-VerifiableMocks 143 | } 144 | 145 | It 'does not informs about new version' { 146 | $Script:PGVM_NEW_VERSION | Should Be $false 147 | } 148 | 149 | $Global:PGVM_AUTO_SELFUPDATE = $backup_Global_PGVM_AUTO_SELFUPDTE 150 | } 151 | } 152 | 153 | Describe 'Is-New-Posh-GVM-Version-Available' { 154 | Context 'New version available' { 155 | $Script:PGVM_VERSION_SERVICE = 'blub' 156 | $Script:PGVM_VERSION_PATH = 'TestDrive:VERSION.txt' 157 | Set-Content $Script:PGVM_VERSION_PATH '1.1.1' 158 | 159 | Mock Invoke-RestMethod { '1.2.1' } -parameterFilter { $Uri -eq 'blub' } 160 | 161 | $result = Is-New-Posh-GVM-Version-Available 162 | 163 | It 'returns $true' { 164 | $result | Should Be $true 165 | } 166 | } 167 | 168 | Context 'No new version available' { 169 | $Script:PGVM_VERSION_SERVICE = 'blub' 170 | $Script:PGVM_VERSION_PATH = 'TestDrive:VERSION.txt' 171 | Set-Content $Script:PGVM_VERSION_PATH '1.1.1' 172 | 173 | Mock Invoke-RestMethod { '1.1.1' } -parameterFilter { $Uri -eq 'blub' } 174 | 175 | $result = Is-New-Posh-GVM-Version-Available 176 | 177 | It 'returns $false' { 178 | $result | Should Be $false 179 | } 180 | } 181 | 182 | Context 'Version service error' { 183 | $Script:PGVM_VERSION_SERVICE = 'blub' 184 | $Script:PGVM_VERSION_PATH = 'TestDrive:VERSION.txt' 185 | Set-Content $Script:PGVM_VERSION_PATH '1.1.1' 186 | 187 | Mock Invoke-RestMethod { throw 'error' } -parameterFilter { $Uri -eq 'blub' } 188 | 189 | $result = Is-New-Posh-GVM-Version-Available 190 | 191 | It 'returns $false' { 192 | $result | Should Be $false 193 | } 194 | } 195 | } 196 | 197 | Describe 'Get-GVM-API-Version' { 198 | Context 'No cached version' { 199 | $Script:GVM_API_VERSION_PATH = 'TestDrive:version.txt' 200 | 201 | It 'returns `$null' { 202 | Get-GVM-API-Version | Should Be $null 203 | } 204 | } 205 | 206 | Context 'No cached version' { 207 | $Script:GVM_API_VERSION_PATH = 'TestDrive:version.txt' 208 | Set-Content $Script:GVM_API_VERSION_PATH '1.1.1' 209 | 210 | It 'returns $null' { 211 | Get-GVM-API-Version | Should Be 1.1.1 212 | } 213 | } 214 | } 215 | 216 | Describe 'Check-Available-Broadcast' { 217 | Context 'Last execution was online, still online' { 218 | $Script:GVM_ONLINE = $true 219 | $Script:GVM_AVAILABLE = $true 220 | Mock Get-GVM-API-Version { '1.2.3' } 221 | Mock Invoke-Broadcast-API-Call { 'Broadcast message' } 222 | Mock Handle-Broadcast -verifiable -parameterFilter { $Command -eq $null -and $Broadcast -eq 'Broadcast message' } 223 | Mock Write-Offline-Broadcast 224 | Mock Write-Online-Broadcast 225 | 226 | Check-Available-Broadcast 227 | 228 | It 'does not announce any mode changes' { 229 | Assert-MockCalled Write-Offline-Broadcast 0 230 | Assert-MockCalled Write-Online-Broadcast 0 231 | } 232 | 233 | It 'calls Handle-Broadcast' { 234 | Assert-VerifiableMocks 235 | } 236 | } 237 | 238 | Context 'Last execution was online, now offline' { 239 | $Script:GVM_ONLINE = $true 240 | $Script:GVM_AVAILABLE = $false 241 | Mock Get-GVM-API-Version { '1.2.4' } 242 | Mock Invoke-Broadcast-API-Call { $null } 243 | Mock Handle-Broadcast 244 | Mock Write-Offline-Broadcast 245 | Mock Write-Online-Broadcast 246 | 247 | Check-Available-Broadcast 248 | 249 | It 'does announce offline mode' { 250 | Assert-MockCalled Write-Offline-Broadcast 1 251 | Assert-MockCalled Write-Online-Broadcast 0 252 | } 253 | 254 | It 'does not call Handle-Broadcast' { 255 | Assert-MockCalled Handle-Broadcast 0 256 | } 257 | } 258 | 259 | Context 'Last execution was offline, still offline' { 260 | $Script:GVM_ONLINE = $false 261 | $Script:GVM_AVAILABLE = $false 262 | Mock Get-GVM-API-Version { '1.2.4' } 263 | Mock Invoke-Broadcast-API-Call { $null } 264 | Mock Handle-Broadcast 265 | Mock Write-Offline-Broadcast 266 | Mock Write-Online-Broadcast 267 | 268 | Check-Available-Broadcast 269 | 270 | It 'does not announce any mode changes' { 271 | Assert-MockCalled Write-Offline-Broadcast 0 272 | Assert-MockCalled Write-Online-Broadcast 0 273 | } 274 | 275 | It 'does not call Handle-Broadcast' { 276 | Assert-MockCalled Handle-Broadcast 0 277 | } 278 | } 279 | 280 | Context 'Last execution was offline, now online' { 281 | $Script:GVM_ONLINE = $false 282 | $Script:GVM_AVAILABLE = $true 283 | Mock Get-GVM-API-Version { '1.2.5' } 284 | Mock Invoke-Broadcast-API-Call { 'Broadcast message' } 285 | Mock Handle-Broadcast -verifiable -parameterFilter { $Command -eq $null -and $Broadcast -eq 'Broadcast message' } 286 | Mock Write-Offline-Broadcast 287 | Mock Write-Online-Broadcast 288 | 289 | Check-Available-Broadcast 290 | 291 | It 'does announce online mode' { 292 | Assert-MockCalled Write-Offline-Broadcast 0 293 | Assert-MockCalled Write-Online-Broadcast 1 294 | } 295 | 296 | It 'calls Handle-Broadcast' { 297 | Assert-VerifiableMocks 298 | } 299 | } 300 | } 301 | 302 | Describe 'Invoke-Self-Update' { 303 | Context 'Selfupdate will be triggered, no force, no new version' { 304 | Mock Update-Candidates-Cache -verifiable 305 | Mock Write-Output -verifiable 306 | Mock Is-New-Posh-GVM-Version-Available { $false } 307 | Mock Invoke-Posh-Gvm-Update 308 | 309 | Invoke-Self-Update 310 | 311 | It 'updates the candidate cache' { 312 | Assert-VerifiableMocks 313 | } 314 | 315 | It 'does not updates itself' { 316 | Assert-MockCalled Invoke-Posh-Gvm-Update -Times 0 317 | } 318 | } 319 | 320 | Context 'Selfupdate will be triggered, no force, new version' { 321 | Mock Update-Candidates-Cache -verifiable 322 | Mock Write-Output -verifiable 323 | Mock Is-New-Posh-GVM-Version-Available { $true } 324 | Mock Invoke-Posh-Gvm-Update -verifiable 325 | 326 | Invoke-Self-Update 327 | 328 | It 'updates the candidate cache and version' { 329 | Assert-VerifiableMocks 330 | } 331 | } 332 | 333 | Context 'Selfupdate will be triggered, force, no new version' { 334 | Mock Update-Candidates-Cache -verifiable 335 | Mock Write-Output -verifiable 336 | Mock Is-New-Posh-GVM-Version-Available { $false } 337 | Mock Invoke-Posh-Gvm-Update -verifiable 338 | 339 | Invoke-Self-Update -Force $true 340 | 341 | It 'updates the candidate cache and version' { 342 | Assert-VerifiableMocks 343 | } 344 | } 345 | } 346 | 347 | Describe 'Check-Candidate-Present checks if candidate parameter is valid' { 348 | It 'throws an error if no candidate is provided' { 349 | { Check-Candidate-Present } | Should Throw 350 | } 351 | 352 | $Script:GVM_CANDIDATES = @('grails','groovy') 353 | It 'throws error if candidate unknown' { 354 | { Check-Candidate-Present java } | Should Throw 355 | } 356 | 357 | It 'throws no error if candidate known' { 358 | { Check-Candidate-Present groovy } | Should Not Throw 359 | } 360 | } 361 | 362 | Describe 'Check-Version-Present checks if version parameter is defined' { 363 | It 'throws an error if no candidate is provided' { 364 | { Check-Version-Present } | Should Throw 365 | } 366 | 367 | It 'throws no error if version provided' { 368 | { Check-Version-Present 2.1.3 } | Should Not Throw 369 | } 370 | } 371 | 372 | Describe 'Check-Candidate-Version-Available select or vadidates a version for a candidate' { 373 | Context 'When grails version 1.1.1 is locally available' { 374 | Mock-Check-Candidate-Grails 375 | Mock-Grails-1.1.1-Locally-Available $true 376 | 377 | $result = Check-Candidate-Version-Available grails 1.1.1 378 | 379 | It 'check candidate parameter' { 380 | Assert-VerifiableMocks 381 | } 382 | 383 | It 'returns the 1.1.1' { 384 | $result | Should Be 1.1.1 385 | } 386 | } 387 | 388 | Context 'When gvm is offline and the provided version is not locally available' { 389 | Mock-Check-Candidate-Grails 390 | Mock-Offline 391 | Mock-Grails-1.1.1-Locally-Available $false 392 | 393 | It 'throws an error' { 394 | { Check-Candidate-Version-Available grails 1.1.1 } | Should Throw 395 | } 396 | 397 | It 'check candidate parameter' { 398 | Assert-VerifiableMocks 399 | } 400 | } 401 | 402 | Context 'When gvm is offline and no version is provided but there is a current version' { 403 | Mock-Check-Candidate-Grails 404 | Mock-Offline 405 | Mock-Current-Grails-1.2 406 | 407 | $result = Check-Candidate-Version-Available grails 408 | 409 | It 'check candidate parameter' { 410 | Assert-VerifiableMocks 411 | } 412 | 413 | It 'returns the current version' { 414 | $result | Should Be 1.2 415 | } 416 | } 417 | 418 | Context 'When gvm is offline and no version is provided and no current version is defined' { 419 | Mock-Check-Candidate-Grails 420 | Mock-Offline 421 | Mock-No-Current-Grails 422 | 423 | It 'throws an error' { 424 | { Check-Candidate-Version-Available grails } | Should Throw 425 | } 426 | 427 | It 'check candidate parameter' { 428 | Assert-VerifiableMocks 429 | } 430 | } 431 | 432 | Context 'When gvm is online and no version is provided' { 433 | Mock-Check-Candidate-Grails 434 | Mock-Online 435 | Mock-Api-Call-Default-Grails-2.2 436 | 437 | $result = Check-Candidate-Version-Available grails 438 | 439 | It 'the API default is returned' { 440 | $result | Should Be 2.2 441 | } 442 | 443 | It 'check candidate parameter' { 444 | Assert-VerifiableMocks 445 | } 446 | } 447 | 448 | Context 'When gvm is online and the provided version is valid' { 449 | Mock-Check-Candidate-Grails 450 | Mock-Online 451 | Mock-Api-Call-Grails-1.1.1-Available $true 452 | 453 | $result = Check-Candidate-Version-Available grails 1.1.1 454 | 455 | It 'returns the version' { 456 | $result | Should Be 1.1.1 457 | } 458 | 459 | It 'check candidate parameter' { 460 | Assert-VerifiableMocks 461 | } 462 | } 463 | 464 | Context 'When gvm is online and the provided version is invalid' { 465 | Mock-Check-Candidate-Grails 466 | Mock-Online 467 | Mock-Api-Call-Grails-1.1.1-Available $false 468 | 469 | It 'throws an error' { 470 | { Check-Candidate-Version-Available grails 1.1.1 } | Should Throw 471 | } 472 | 473 | It 'check candidate parameter' { 474 | Assert-VerifiableMocks 475 | } 476 | } 477 | } 478 | 479 | Describe 'Get-Current-Candidate-Version reads the currently linked version' { 480 | Context 'When current is not defined' { 481 | Mock-PGVM-Dir 482 | 483 | It 'returns $null if current not defined' { 484 | Get-Current-Candidate-Version grails | Should Be $null 485 | } 486 | 487 | Reset-PGVM-DIR 488 | } 489 | 490 | Context 'When current is defined' { 491 | Mock-PGVM-Dir 492 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\2.2.2" | Out-Null 493 | Set-Junction-Via-Mklink "$Global:PGVM_DIR\grails\current" "$Global:PGVM_DIR\grails\2.2.2" 494 | 495 | It 'returns the liked version' { 496 | Get-Current-Candidate-Version grails | Should Be 2.2.2 497 | } 498 | 499 | Reset-PGVM-Dir 500 | } 501 | } 502 | 503 | Describe 'Get-Env-Candidate-Version reads the version set in $Candidate-Home' { 504 | Context 'When GRAILS_HOME is set to a specific version' { 505 | Mock-PGVM-Dir 506 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\2.2.1" | Out-Null 507 | Mock-Grails-Home 2.2.1 508 | 509 | It 'returns the set version' { 510 | Get-Env-Candidate-Version grails | Should Be 2.2.1 511 | } 512 | 513 | Reset-Grails-Home 514 | Reset-PGVM-Dir 515 | } 516 | 517 | Context 'When GRAILS_HOME is set to current' { 518 | Mock-PGVM-Dir 519 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\2.2.1" | Out-Null 520 | Set-Junction-Via-Mklink "$Global:PGVM_DIR\grails\current" "$Global:PGVM_DIR\grails\2.2.1" 521 | 522 | Mock-Grails-Home current 523 | 524 | It 'returns the version linked to current' { 525 | Get-Env-Candidate-Version grails | Should Be 2.2.1 526 | } 527 | 528 | Reset-Grails-Home 529 | Reset-PGVM-Dir 530 | } 531 | } 532 | 533 | Describe 'Check-Candidate-Version-Locally-Available throws error message if not available' { 534 | Context 'Version not available' { 535 | Mock-Grails-1.1.1-Locally-Available $false 536 | It 'throws an error' { 537 | { Check-Candidate-Version-Locally-Available grails 1.1.1 } | Should Throw 538 | } 539 | } 540 | 541 | Context 'Version is available' { 542 | Mock-Grails-1.1.1-Locally-Available $true 543 | 544 | It 'not throws any error' { 545 | { Check-Candidate-Version-Locally-Available grails 1.1.1 } | Should Not Throw 546 | } 547 | } 548 | } 549 | 550 | Describe 'Is-Candidate-Version-Locally-Available check the path exists' { 551 | Context 'No version provided' { 552 | it 'returns $false' { 553 | Is-Candidate-Version-Locally-Available grails | Should Be $false 554 | } 555 | } 556 | 557 | Context 'COC path for grails 1.1.1 is missing' { 558 | Mock-PGVM-Dir 559 | 560 | it 'returns $false' { 561 | Is-Candidate-Version-Locally-Available grails 1.1.1 | Should Be $false 562 | } 563 | 564 | Reset-PGVM-Dir 565 | } 566 | 567 | Context 'COC path for grails 1.1.1 exists' { 568 | Mock-PGVM-Dir 569 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\1.1.1" | Out-Null 570 | 571 | it 'returns $true' { 572 | Is-Candidate-Version-Locally-Available grails 1.1.1 | Should Be $true 573 | } 574 | 575 | Reset-PGVM-Dir 576 | } 577 | } 578 | 579 | Describe 'Get-Installed-Candidate-Version-List' { 580 | Context 'Version 1.1, 1.3.7 and 2.2.1 of grails installed' { 581 | Mock-PGVM-Dir 582 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\1.1" | Out-Null 583 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\1.3.7" | Out-Null 584 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\2.2.1" | Out-Null 585 | Set-Junction-Via-Mklink "$Global:PGVM_DIR\grails\current" "$Global:PGVM_DIR\grails\2.2.1" 586 | 587 | It 'returns list of installed versions' { 588 | Get-Installed-Candidate-Version-List grails | Should Be 1.1,1.3.7,2.2.1 589 | } 590 | 591 | Reset-PGVM-Dir 592 | } 593 | } 594 | 595 | Describe 'Set-Env-Candidate-Version' { 596 | Context 'Env-Version of grails is current' { 597 | Mock-PGVM-Dir 598 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\1.3.7" | Out-Null 599 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\2.2.1" | Out-Null 600 | Set-Junction-Via-Mklink "$Global:PGVM_DIR\grails\current" "$Global:PGVM_DIR\grails\2.2.1" 601 | Mock-Grails-Home current 602 | $backupPATH = $env:Path 603 | 604 | Set-Env-Candidate-Version grails 1.3.7 605 | 606 | It 'sets GRAILS_HOME' { 607 | $env:GRAILS_HOME -eq "$Global:PGVM_DIR\grails\1.3.7" 608 | } 609 | 610 | It 'extends the Path' { 611 | $env:Path -eq "$Global:PGVM_DIR\grails\1.3.7\bin" 612 | } 613 | 614 | $env:Path = $backupPATH 615 | Reset-Grails-Home 616 | Reset-PGVM-Dir 617 | } 618 | } 619 | 620 | Describe 'Set-Linked-Candidate-Version' { 621 | Context 'In a initialized PGVM-Dir' { 622 | Mock-PGVM-Dir 623 | Mock Set-Junction-Via-Mklink -verifiable -parameterFilter { $Candidate -eq 'grails' -and $Version -eq '2.2.1' } 624 | 625 | Set-Linked-Candidate-Version grails 2.2.1 626 | 627 | It 'calls Set-Junction-Via-Mklink with the correct paths' { 628 | Assert-VerifiableMocks 629 | } 630 | 631 | Reset-PGVM-Dir 632 | } 633 | } 634 | 635 | Describe 'Set-Junction-Via-Mklink' { 636 | Context 'No junction for the link-path exists' { 637 | Mock-PGVM-Dir 638 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\1.3.7" | Out-Null 639 | 640 | Set-Junction-Via-Mklink "$Global:PGVM_DIR\grails\bla" "$Global:PGVM_DIR\grails\1.3.7" 641 | 642 | It 'creates a junction to the target location' { 643 | (Get-Junction-Target "$Global:PGVM_DIR\grails\bla").FullName -eq "$Global:PGVM_DIR\grails\1.3.7" 644 | } 645 | 646 | (Get-Item "$Global:PGVM_DIR\grails\bla").Delete() 647 | Reset-PGVM-Dir 648 | } 649 | 650 | Context 'A Junction for the link-path exists' { 651 | Mock-PGVM-Dir 652 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\1.3.7" | Out-Null 653 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\1.3.8" | Out-Null 654 | Set-Junction-Via-Mklink "$Global:PGVM_DIR\grails\bla" "$Global:PGVM_DIR\grails\1.3.8" 655 | Set-Junction-Via-Mklink "$Global:PGVM_DIR\grails\bla" "$Global:PGVM_DIR\grails\1.3.7" 656 | 657 | It 'creates a junction to the target location without errors' { 658 | (Get-Junction-Target "$Global:PGVM_DIR\grails\bla").FullName -eq "$Global:PGVM_DIR\grails\1.3.7" 659 | } 660 | 661 | (Get-Item "$Global:PGVM_DIR\grails\bla").Delete() 662 | Reset-PGVM-Dir 663 | } 664 | } 665 | 666 | Describe 'Get-Junction-Target' { 667 | Context 'Provided path is a junction' { 668 | Mock-PGVM-Dir 669 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\1.3.7" | Out-Null 670 | 671 | Set-Junction-Via-Mklink "$Global:PGVM_DIR\grails\bla" "$Global:PGVM_DIR\grails\1.3.7" 672 | 673 | It 'returns the item of the junction correctly' { 674 | (Get-Junction-Target "$Global:PGVM_DIR\grails\bla").FullName -eq "$Global:PGVM_DIR\grails\1.3.7" 675 | } 676 | 677 | (Get-Item "$Global:PGVM_DIR\grails\bla").Delete() 678 | Reset-PGVM-Dir 679 | } 680 | 681 | Context 'Provided path is no junction' { 682 | Mock-PGVM-Dir 683 | New-Item -ItemType Directory "$Global:PGVM_DIR\grails\1.3.7" | Out-Null 684 | 685 | It 'returns correctly a null object without exception' { 686 | Get-Junction-Target "$Global:PGVM_DIR\grails\1.3.7" -eq $null 687 | } 688 | 689 | Reset-PGVM-Dir 690 | } 691 | } 692 | 693 | Describe 'Get-Online-Mode check the state variables for GVM-API availablitiy and for force offline mode' { 694 | Context 'GVM-Api unavailable but may be connected' { 695 | $Script:GVM_AVAILABLE = $false 696 | $Script:GVM_FORCE_OFFLINE = $false 697 | 698 | It 'returns $false' { 699 | Get-Online-Mode | Should Be $false 700 | } 701 | } 702 | 703 | Context 'GVM-Api unavailable and may not be connected' { 704 | $Script:GVM_AVAILABLE = $false 705 | $Script:GVM_FORCE_OFFLINE = $true 706 | 707 | It 'returns $false' { 708 | Get-Online-Mode | Should Be $false 709 | } 710 | } 711 | 712 | Context 'GVM-Api is available and may not be connected' { 713 | $Script:GVM_AVAILABLE = $true 714 | $Script:GVM_FORCE_OFFLINE = $true 715 | 716 | It 'returns $false' { 717 | Get-Online-Mode | Should Be $false 718 | } 719 | } 720 | 721 | Context 'GVM-Api is available and may be connected' { 722 | $Script:GVM_AVAILABLE = $true 723 | $Script:GVM_FORCE_OFFLINE = $false 724 | 725 | It 'returns $true' { 726 | Get-Online-Mode | Should Be $true 727 | } 728 | } 729 | } 730 | 731 | 732 | Describe 'Check-Online-Mode throws an error when offline' { 733 | Context 'Offline' { 734 | Mock-Offline 735 | 736 | It 'throws an error' { 737 | { Check-Online-Mode } | Should Throw 738 | } 739 | } 740 | 741 | Context 'Online' { 742 | Mock-Online 743 | 744 | It 'throws no error' { 745 | { Check-Online-Mode } | Should Not Throw 746 | } 747 | } 748 | } 749 | 750 | Describe 'Invoke-API-Call helps doing calls to the GVM-API' { 751 | Context 'Successful API call only with API path' { 752 | $Script:PGVM_SERVICE = 'blub' 753 | Mock Invoke-RestMethod { 'called' } -parameterFilter { $Uri -eq 'blub/na/rock' } 754 | 755 | It 'returns the result from Invoke-RestMethod' { 756 | Invoke-API-Call 'na/rock' | Should Be 'called' 757 | } 758 | } 759 | 760 | Context 'Failed API call only with API path' { 761 | $Script:PGVM_SERVICE = 'blub' 762 | $Script:GVM_AVAILABLE = $true 763 | Mock Invoke-RestMethod { throw 'error' } -parameterFilter { $Uri -eq 'blub/na/rock' } 764 | Mock Check-Online-Mode -verifiable 765 | 766 | Invoke-API-Call 'na/rock' 767 | 768 | It 'sets GVM_AVAILABLE to false' { 769 | $Script:GVM_AVAILABLE | Should Be $false 770 | } 771 | 772 | It 'calls Check-Online-Mode which throws an error' { 773 | Assert-VerifiableMocks 774 | } 775 | } 776 | 777 | Context 'Failed API call with API path and IgnoreFailure' { 778 | $Script:PGVM_SERVICE = 'blub' 779 | $Script:GVM_AVAILABLE = $true 780 | Mock Invoke-RestMethod { throw 'error' } -parameterFilter { $Uri -eq 'blub/na/rock' } 781 | Mock Check-Online-Mode 782 | 783 | Invoke-API-Call 'na/rock' -IgnoreFailure 784 | 785 | It 'sets GVM_AVAILABLE to false' { 786 | $Script:GVM_AVAILABLE | Should Be $false 787 | } 788 | 789 | It 'do not call Check-Online-Mode' { 790 | Assert-MockCalled Check-Online-Mode 0 791 | } 792 | } 793 | 794 | Context 'Successful API call with API path and FilePath' { 795 | $Script:PGVM_SERVICE = 'blub' 796 | Mock Invoke-RestMethod -verifiable -parameterFilter { $Uri -eq 'blub/na/rock' -and $OutFile -eq 'TestDrive:a.txt' } 797 | 798 | Invoke-API-Call 'na/rock' TestDrive:a.txt 799 | 800 | It 'calls Invoke-RestMethod with file path' { 801 | Assert-VerifiableMocks 802 | } 803 | } 804 | } 805 | 806 | Describe 'Cleanup-Directory' { 807 | Context 'Directory with subdirectories and files' { 808 | New-Item -ItemType Directory TestDrive:bla | Out-Null 809 | New-Item -ItemType Directory TestDrive:bla\a | Out-Null 810 | New-Item -ItemType Directory TestDrive:bla\b | Out-Null 811 | New-Item -ItemType File TestDrive:bla\c | Out-Null 812 | New-Item -ItemType File TestDrive:bla\a\a | Out-Null 813 | 814 | Mock Write-Output -verifiable -parameterFilter { $InputObject -eq '2 archive(s) flushed, freeing 0 MB' } 815 | 816 | Cleanup-Directory TestDrive:bla 817 | 818 | It 'Cleans the Test-Path file' { 819 | Test-Path TestDrive:bla | Should Be $False 820 | } 821 | 822 | It 'Write info to host' { 823 | Assert-VerifiableMocks 824 | } 825 | } 826 | } 827 | 828 | Describe 'Handle-Broadcast' { 829 | Context 'Cache broadcast message different than new broadcast' { 830 | Mock-PGVM-Dir 831 | $Script:PGVM_BROADCAST_PATH = "$Global:PGVM_DIR\broadcast.txt" 832 | Set-Content $Script:PGVM_BROADCAST_PATH 'Old Broadcast message' 833 | Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'New Broadcast message' } 834 | 835 | Handle-Broadcast list 'New Broadcast message' 836 | 837 | It 'outputs the broadcast message' { 838 | Assert-VerifiableMocks 839 | } 840 | 841 | It 'sets the new broadcast message in file' { 842 | Get-Content $Script:PGVM_BROADCAST_PATH | Should Be 'New Broadcast message' 843 | } 844 | 845 | 846 | Reset-PGVM-Dir 847 | } 848 | 849 | Context 'No cached broadcast message' { 850 | Mock-PGVM-Dir 851 | 852 | $Script:PGVM_BROADCAST_PATH = "$Global:PGVM_DIR\broadcast.txt" 853 | Mock Write-Output -verifiable -parameterFilter { $InputObject -eq 'New Broadcast message' } 854 | 855 | Handle-Broadcast list 'New Broadcast message' 856 | 857 | It 'outputs the broadcast message' { 858 | Assert-VerifiableMocks 859 | } 860 | 861 | It 'sets the new broadcast message in file' { 862 | Get-Content $Script:PGVM_BROADCAST_PATH | Should Be 'New Broadcast message' 863 | } 864 | 865 | Reset-PGVM-Dir 866 | } 867 | 868 | Context 'b do not print the new broadcast message' { 869 | Mock-PGVM-Dir 870 | 871 | $Script:PGVM_BROADCAST_PATH = "$Global:PGVM_DIR\broadcast.txt" 872 | Mock Write-Output -verifiable 873 | 874 | Handle-Broadcast b 'New Broadcast message' 875 | 876 | It 'no Broadcast' { 877 | Assert-MockCalled Write-Output 0 878 | } 879 | 880 | It 'sets the new broadcast message in file' { 881 | Test-Path $Script:PGVM_BROADCAST_PATH | Should Be $false 882 | } 883 | 884 | Reset-PGVM-Dir 885 | } 886 | 887 | Context 'Broadcast do nOt print the new broadcast message' { 888 | Mock-PGVM-Dir 889 | 890 | $Script:PGVM_BROADCAST_PATH = "$Global:PGVM_DIR\broadcast.txt" 891 | Mock Write-Output -verifiable 892 | 893 | Handle-Broadcast broadcast 'New Broadcast message' 894 | 895 | It 'no Broadcast' { 896 | Assert-MockCalled Write-Output 0 897 | } 898 | 899 | It 'sets the new broadcast message in file' { 900 | Test-Path $Script:PGVM_BROADCAST_PATH | Should Be $false 901 | } 902 | 903 | Reset-PGVM-Dir 904 | } 905 | 906 | Context 'selfupdate do not print the new broadcast message' { 907 | Mock-PGVM-Dir 908 | 909 | $Script:PGVM_BROADCAST_PATH = "$Global:PGVM_DIR\broadcast.txt" 910 | Mock Write-Output -verifiable 911 | 912 | Handle-Broadcast selfupdate 'New Broadcast message' 913 | 914 | It 'no Broadcast' { 915 | Assert-MockCalled Write-Output 0 916 | } 917 | 918 | It 'sets the new broadcast message in file' { 919 | Test-Path $Script:PGVM_BROADCAST_PATH | Should Be $false 920 | } 921 | 922 | Reset-PGVM-Dir 923 | } 924 | 925 | Context 'flush do not print the new broadcast message' { 926 | Mock-PGVM-Dir 927 | 928 | $Script:PGVM_BROADCAST_PATH = "$Global:PGVM_DIR\broadcast.txt" 929 | Mock Write-Output -verifiable 930 | 931 | Handle-Broadcast flush 'New Broadcast message' 932 | 933 | It 'no Broadcast' { 934 | Assert-MockCalled Write-Output 0 935 | } 936 | 937 | It 'sets the new broadcast message in file' { 938 | Test-Path $Script:PGVM_BROADCAST_PATH | Should Be $false 939 | } 940 | 941 | Reset-PGVM-Dir 942 | } 943 | } 944 | 945 | Describe 'Init-Candidate-Cache' { 946 | Context 'Candidate cache file does not exists' { 947 | Mock-PGVM-Dir 948 | $Script:PGVM_CANDIDATES_PATH = "$Global:PGVM_DIR\candidates.txt" 949 | 950 | It 'throws an error' { 951 | { Init-Candidate-Cache } | Should Throw 952 | } 953 | 954 | Reset-PGVM-Dir 955 | } 956 | 957 | Context 'Candidate cache file does exists' { 958 | Mock-PGVM-Dir 959 | $Script:PGVM_CANDIDATES_PATH = "$Global:PGVM_DIR\candidates.txt" 960 | Set-Content $Script:PGVM_CANDIDATES_PATH 'grails,groovy,test' 961 | $Script:GVM_CANDIDATES = $null 962 | 963 | Init-Candidate-Cache 964 | 965 | It 'sets `$Script:GVM_CANDIDATES' { 966 | $Script:GVM_CANDIDATEs | Should Be grails,groovy,test 967 | } 968 | 969 | Reset-PGVM-Dir 970 | } 971 | } 972 | 973 | Describe 'Update-Candidate-Cache' { 974 | Context 'Checks online mode and than get version and candidates from api' { 975 | Mock-PGVM-Dir 976 | 977 | $Script:GVM_API_VERSION_PATH = "$Global:PGVM_DIR\version.txt" 978 | $Script:PGVM_CANDIDATES_PATH = "$Global:PGVM_DIR\candidates.txt" 979 | 980 | Mock Check-Online-Mode -verifiable 981 | Mock Invoke-API-Call -verifiable -parameterFilter { $Path -eq 'app/version' -and $FileTarget -eq "$Global:PGVM_DIR\version.txt" } 982 | Mock Invoke-API-Call -verifiable -parameterFilter { $Path -eq 'candidates' -and $FileTarget -eq "$Global:PGVM_DIR\candidates.txt" } 983 | 984 | Update-Candidates-Cache 985 | 986 | It 'calls the Check-Online-Mode and two API paths' { 987 | Assert-VerifiableMocks 988 | } 989 | 990 | Reset-PGVM-Dir 991 | } 992 | } 993 | 994 | Describe 'Write-Offline-Version-List' { 995 | Context 'no versions of grails installed' { 996 | Mock Write-Output 997 | Mock Get-Current-Candidate-Version { $null } -parameterFilter { $Candidate -eq 'grails' } 998 | Mock Get-Installed-Candidate-Version-List { $null } -parameterFilter { $Candidate -eq 'grails' } 999 | 1000 | Write-Offline-Version-List grails 1001 | 1002 | It 'Outputs 11 lines' { 1003 | Assert-MockCalled Write-Output 9 1004 | } 1005 | } 1006 | 1007 | Context 'Three versions of grails installed' { 1008 | Mock Write-Output 1009 | Mock Get-Current-Candidate-Version { 1.1.1 } -parameterFilter { $Candidate -eq 'grails' } 1010 | Mock Get-Installed-Candidate-Version-List { 1.1.1,2.2.2,2.3.0 } -parameterFilter { $Candidate -eq 'grails' } 1011 | 1012 | Write-Offline-Version-List grails 1013 | 1014 | It 'Outputs 11 lines' { 1015 | Assert-MockCalled Write-Output 11 1016 | } 1017 | } 1018 | } 1019 | 1020 | Describe 'Write-Version-List' { 1021 | Context 'Three versions of grails installed' { 1022 | Mock Write-Output 1023 | Mock Get-Current-Candidate-Version { '1.1.1' } -parameterFilter { $Candidate -eq 'grails' } 1024 | Mock Get-Installed-Candidate-Version-List { return '1.1.1','2.2.2','2.3.0' } -parameterFilter { $Candidate -eq 'grails' } 1025 | Mock Invoke-API-Call { 'bla' } -parameterFilter { $Path -eq 'candidates/grails/list?platform=posh¤t=1.1.1&installed=1.1.1,2.2.2,2.3.0' } 1026 | 1027 | Write-Version-List grails 1028 | 1029 | It 'writes to host' { 1030 | Assert-MockCalled Write-Output 1 1031 | } 1032 | } 1033 | } 1034 | 1035 | Describe 'Install-Local-Version' { 1036 | Context 'LocalPath is no directory' { 1037 | New-Item -ItemType File TestDrive:a.txt | Out-Null 1038 | 1039 | It 'throws an error' { 1040 | { Install-Local-Version grails snapshot TestDrive:a.txt } | Should Throw 1041 | } 1042 | } 1043 | 1044 | Context 'LocalPath is valid' { 1045 | New-Item -ItemType Directory TestDrive:Snapshot | Out-Null 1046 | Mock Write-Output 1047 | Mock Set-Junction-Via-Mklink -verifiable -parameterFilter { $Link -eq "$Global:PGVM_DIR\grails\snapshot" -and $Target -eq 'TestDrive:Snapshot' } 1048 | 1049 | Install-Local-Version grails snapshot TestDrive:Snapshot 1050 | 1051 | It 'creates junction for candidate version' { 1052 | Assert-VerifiableMocks 1053 | } 1054 | } 1055 | } 1056 | 1057 | Describe 'Install-Remote-Version' { 1058 | Context 'Install of a valid version without local archive' { 1059 | Mock-PGVM-Dir 1060 | 1061 | Mock Write-Output 1062 | Mock Check-Online-Mode -verifiable 1063 | $Script:PGVM_SERVICE = 'foobar' 1064 | $Script:PGVM_ARCHIVES_PATH = "$Global:PGVM_DIR\archives" 1065 | $Script:PGVM_TEMP_PATH = "$Global:PGVM_DIR\temp" 1066 | $testFilePath = "$PSScriptRoot\test\grails-1.3.9.zip" 1067 | 1068 | 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" } 1069 | 1070 | Install-Remote-Version grails 1.3.9 1071 | 1072 | It 'downloads the archive' { 1073 | Assert-VerifiableMocks 1074 | } 1075 | 1076 | It 'install it correctly' { 1077 | Test-Path "$Global:PGVM_DIR\grails\1.3.9\bin\grails" | Should be $true 1078 | } 1079 | 1080 | Reset-PGVM-DIR 1081 | } 1082 | 1083 | Context 'Install of a valid version with local archive' { 1084 | Mock-PGVM-Dir 1085 | 1086 | Mock Write-Output 1087 | Mock Download-File 1088 | 1089 | $Script:PGVM_ARCHIVES_PATH = "$Global:PGVM_DIR\archives" 1090 | $Script:PGVM_TEMP_PATH = "$Global:PGVM_DIR\temp" 1091 | New-Item -ItemType Directory $Script:PGVM_ARCHIVES_PATH | Out-Null 1092 | Copy-Item "$PSScriptRoot\test\grails-1.3.9.zip" "$Script:PGVM_ARCHIVES_PATH\grails-1.3.9.zip" 1093 | 1094 | Install-Remote-Version grails 1.3.9 1095 | 1096 | It 'does not download the archive again' { 1097 | Assert-MockCalled Download-File 0 1098 | } 1099 | 1100 | It 'install it correctly' { 1101 | Test-Path "$Global:PGVM_DIR\grails\1.3.9\bin\grails" | Should be $true 1102 | } 1103 | 1104 | Reset-PGVM-DIR 1105 | } 1106 | 1107 | Context 'Install of a currupt archive' { 1108 | Mock-PGVM-Dir 1109 | 1110 | Mock Write-Output 1111 | Mock Download-File 1112 | 1113 | $Script:PGVM_ARCHIVES_PATH = "$Global:PGVM_DIR\archives" 1114 | $Script:PGVM_TEMP_PATH = "$Global:PGVM_DIR\temp" 1115 | New-Item -ItemType Directory $Script:PGVM_ARCHIVES_PATH | Out-Null 1116 | Copy-Item "$PSScriptRoot\test\grails-2.2.2.zip" "$Script:PGVM_ARCHIVES_PATH\grails-2.2.2.zip" 1117 | 1118 | It 'fails because of no unziped files' { 1119 | { Install-Remote-Version grails 2.2.2 } | Should Throw 1120 | } 1121 | 1122 | It 'does not download the archive again' { 1123 | Assert-MockCalled Download-File 0 1124 | } 1125 | 1126 | Reset-PGVM-DIR 1127 | } 1128 | } 1129 | --------------------------------------------------------------------------------