Public/Set-DevVmVersion.ps1

<#
.SYNOPSIS
Sets the active version of a runtime for the current session or permanently.
 
.DESCRIPTION
Switches to a specific version of a runtime. Can be persisted to:
- 'session': Only for the current session
- 'project': Saves to nearest .devvm file
- 'global': Saves to global .devvm file
 
.PARAMETER Runtime
The runtime to set (node, java, maven, etc.)
 
.PARAMETER Version
The version to activate.
 
.PARAMETER Persist
Where to save the selection: 'session', 'project', or 'global'.
Default is 'session'.
 
.PARAMETER Verify
If specified, verifies the runtime command executes after activation by displaying its version output.
Default is $false (no verification).
 
.EXAMPLE
Set-DevVmVersion -Runtime node -Version 18.16.0
Set-DevVmVersion -Runtime node -Version 18.16.0 -Persist project
Set-DevVmVersion -Runtime java -Version 17.0.5 -Persist global
Set-DevVmVersion -Runtime java -Version 17.0.5 -Verify
 
#>

function Set-DevVmVersion {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param (
        [Parameter(Mandatory = $true)]
        [ValidateScript({ Test-DevVmRuntime $_ })]
        [string]$Runtime,

        [Parameter(Mandatory = $true)]
        [string]$Version,

        [ValidateSet('session', 'project', 'global')]
        [string]$Persist = 'session',

        [switch]$Verify = $false
    )

    $runtimeInfo = Get-DevVmRuntimeInfo -Runtime $Runtime
    if (-not $runtimeInfo) {
        Write-Error "Runtime '$Runtime' not configured"
        return
    }

    $basePath = Get-DevVmInstallPath -Runtime $Runtime
    $versionPath = Join-Path -Path $basePath -ChildPath $Version

    if (-not (Test-Path $versionPath)) {
        Write-Error "$Runtime version '$Version' not found at $basePath"
        return
    }

    if ($PSCmdlet.ShouldProcess("$Runtime $Version", 'Activate runtime version')) {
        # Update PATH for current session
        Update-DevVmSessionPath -Runtime $Runtime -Version $Version -BasePath $basePath -BinPath $runtimeInfo.binPath -Confirm:$false -WhatIf:$false

        if ($Verify) {
            # Verify the runtime command executes after activation (output is handled by Test-DevVmRuntimeCommand)
            Test-DevVmRuntimeCommand -Runtime $Runtime -Command $runtimeInfo.command -VersionFlag $runtimeInfo.versionFlag | Out-Null
        }

        if (-not $script:DevVmConfig.SessionSelections) {
            $script:DevVmConfig.SessionSelections = @{}
        }
        $script:DevVmConfig.SessionSelections[$Runtime] = $Version

        Write-Output "Activated $Runtime version $Version in current session"
    }
    else {
        Write-Verbose "Skipped activation for $Runtime $Version"
    }

    # Persist if requested
    if ($Persist -ne 'session') {
        if ($PSCmdlet.ShouldProcess("$Runtime $Version", "Persist selection to $Persist config")) {
            Save-DevVmVersionSelection -Runtime $Runtime -Version $Version -Target $Persist
            Write-Output "Saved selection to $Persist configuration"
        }
        else {
            Write-Verbose "Skipped persistence for $Runtime $Version to $Persist config"
        }
    }
}