Public/Invoke-DevVm.ps1

<#
.SYNOPSIS
Main DevVm command dispatcher - provides a simplified CLI interface.
 
.DESCRIPTION
Provides a user-friendly command-line interface for DevVm operations.
Similar to tools like nvm, sdkman, etc.
 
.PARAMETER Command
The subcommand to execute (use, current, list, install, available, activate, cache, system, alias, init, initialize, help).
 
.PARAMETER Runtime
The runtime to operate on (node, java, maven, etc.).
 
.PARAMETER Version
The version to use or install.
 
.PARAMETER Persist
Where to persist the configuration (session, project, user, global).
 
.PARAMETER All
Show all available versions (not just latest of each release line).
 
.PARAMETER Update
Force fresh download of available versions, bypassing cache.
 
.PARAMETER Verify
Verify runtime commands after activation (show version output).
 
.PARAMETER Force
Force profile initialization or update (for initialize/init command).
 
.EXAMPLE
devvm use node 18.9.1
devvm use java 11.0.2 -Persist project
devvm current node
devvm list node
devvm install node 20.0.0
devvm available java
devvm available java -All
devvm available node -Update
devvm system
devvm cache
devvm cache clean
devvm activate
devvm activate -Verify
devvm initialize
devvm initialize -Force
devvm init -Force
 
#>

function Invoke-DevVm {
    [CmdletBinding()]
    param (
        [Parameter(Position = 0)]
        [ValidateSet('use', 'current', 'list', 'install', 'available', 'activate', 'cache', 'system', 'path', 'alias', 'initialize', 'init', 'help')]
        [string]$Command = 'help',

        [Parameter(Position = 1)]
        [string]$Runtime,

        [Parameter(Position = 2)]
        [string]$Version,

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

        [switch]$All,

        [switch]$Update,

        [switch]$Verify,

        [switch]$Force
    )

    switch ($Command.ToLower()) {
        'use' {
            if ([string]::IsNullOrWhiteSpace($Runtime)) {
                Write-Error "Runtime is required. Usage: devvm use <runtime> <version>"
                return
            }
            if ([string]::IsNullOrWhiteSpace($Version)) {
                Write-Error "Version is required. Usage: devvm use <runtime> <version>"
                return
            }
            # Validate runtime before calling Set-DevVmVersion to provide better error message
            if (-not (Test-DevVmRuntime -Runtime $Runtime)) {
                $supportedRuntimes = $script:DevVmConfig.RuntimeDefinitions.runtimes.PSObject.Properties.Name -join ', '
                Write-Error "Unknown runtime: '$Runtime'. Supported runtimes are: $supportedRuntimes"
                return
            }
            Set-DevVmVersion -Runtime $Runtime -Version $Version -Persist $Persist
        }

        'current' {
            if ([string]::IsNullOrWhiteSpace($Runtime)) {
                Write-Error "Runtime is required. Usage: devvm current <runtime>"
                return
            }
            # Validate runtime before calling Get-DevVmCurrent to provide better error message
            if (-not (Test-DevVmRuntime -Runtime $Runtime)) {
                $supportedRuntimes = $script:DevVmConfig.RuntimeDefinitions.runtimes.PSObject.Properties.Name -join ', '
                Write-Error "Unknown runtime: '$Runtime'. Supported runtimes are: $supportedRuntimes"
                return
            }
            Get-DevVmCurrent -Runtime $Runtime
        }

        'list' {
            if ([string]::IsNullOrWhiteSpace($Runtime)) {
                Write-Error "Runtime is required. Usage: devvm list <runtime>"
                return
            }
            # Validate runtime before calling Get-DevVmVersion to provide better error message
            if (-not (Test-DevVmRuntime -Runtime $Runtime)) {
                $supportedRuntimes = $script:DevVmConfig.RuntimeDefinitions.runtimes.PSObject.Properties.Name -join ', '
                Write-Error "Unknown runtime: '$Runtime'. Supported runtimes are: $supportedRuntimes"
                return
            }
            Get-DevVmVersion -Runtime $Runtime
        }

        'install' {
            if ([string]::IsNullOrWhiteSpace($Runtime)) {
                Write-Error "Runtime is required. Usage: devvm install <runtime> <version>"
                return
            }
            if ([string]::IsNullOrWhiteSpace($Version)) {
                Write-Error "Version is required. Usage: devvm install <runtime> <version>"
                return
            }
            # Validate runtime before calling Install-DevVmVersion to provide better error message
            if (-not (Test-DevVmRuntime -Runtime $Runtime)) {
                $supportedRuntimes = $script:DevVmConfig.RuntimeDefinitions.runtimes.PSObject.Properties.Name -join ', '
                Write-Error "Unknown runtime: '$Runtime'. Supported runtimes are: $supportedRuntimes"
                return
            }
            Install-DevVmVersion -Runtime $Runtime -Version $Version
        }

        'available' {
            if ([string]::IsNullOrWhiteSpace($Runtime)) {
                Write-Error "Runtime is required. Usage: devvm available <runtime> [-All] [-Update]"
                return
            }
            # Validate runtime before calling Find-DevVmAvailable to provide better error message
            if (-not (Test-DevVmRuntime -Runtime $Runtime)) {
                $supportedRuntimes = $script:DevVmConfig.RuntimeDefinitions.runtimes.PSObject.Properties.Name -join ', '
                Write-Error "Unknown runtime: '$Runtime'. Supported runtimes are: $supportedRuntimes"
                return
            }
            Find-DevVmAvailable -Runtime $Runtime -All:$All -Update:$Update
        }

        'activate' {
            if ([string]::IsNullOrWhiteSpace($Runtime)) {
                Invoke-DevVmActivate -Verify:$Verify
            } else {
                Invoke-DevVmActivate -Runtime $Runtime -Verify:$Verify
            }
        }

        'cache' {
            # Handle cache management: devvm cache [clean]
            if ([string]::IsNullOrWhiteSpace($Runtime) -or $Runtime -eq 'clean') {
                # devvm cache or devvm cache clean
                $cleanAll = if ($Runtime -eq 'clean') { $true } else { $false }
                if ($cleanAll) {
                    Clear-DevVmCache -All -Confirm:$false
                } else {
                    Clear-DevVmCache
                }
            } else {
                # devvm cache info or other subcommand
                Clear-DevVmCache
            }
        }

        'system' {
            # Show complete system information
            Get-DevVmSystem
        }

        'path' {
            # Handle PATH management: devvm path [show|clear] [runtime]
            if ([string]::IsNullOrWhiteSpace($Runtime) -or $Runtime -eq 'show') {
                # devvm path or devvm path show
                Show-DevVmPath
            } elseif ($Runtime -eq 'clear') {
                # devvm path clear [version_as_runtime_name]
                if ([string]::IsNullOrWhiteSpace($Version)) {
                    # Clear all
                    Clear-DevVmPath -Confirm:$true
                } else {
                    # Clear specific runtime (version param is used as runtime name)
                    Clear-DevVmPath -Runtime $Version -Confirm:$true
                }
            } else {
                Write-Error "Unknown path subcommand. Use: devvm path [show|clear] [runtime]"
            }
        }

        'alias' {
            # Handle alias management: devvm alias [list|add|remove] [name]
            if ([string]::IsNullOrWhiteSpace($Runtime) -or $Runtime -eq 'list') {
                # devvm alias or devvm alias list
                Get-DevVmAlias
            } elseif ($Runtime -eq 'add') {
                # devvm alias add <name>
                if ([string]::IsNullOrWhiteSpace($Version)) {
                    Write-Error "Alias name is required. Usage: devvm alias add <name>"
                    return
                }
                Set-DevVmAlias -Name $Version
            } elseif ($Runtime -eq 'remove') {
                # devvm alias remove <name>
                if ([string]::IsNullOrWhiteSpace($Version)) {
                    Write-Error "Alias name is required. Usage: devvm alias remove <name>"
                    return
                }
                Remove-DevVmAlias -Name $Version
            } else {
                Write-Error "Unknown alias subcommand. Use: devvm alias [list|add|remove] [name]"
            }
        }

        'initialize' {
            # Profile initialization (supports -Force flag)
            Initialize-DevVmProfile -Force:$Force
        }

        'init' {
            # Alias for initialize (supports -Force flag)
            Initialize-DevVmProfile -Force:$Force
        }

        'help' {
            Write-Output @"
 
DevVm - Version Manager for Windows
=================================================
 
Usage: devvm <command> [options]
 
Commands:
  use <runtime> <version> Set and activate a runtime version
                                Example: devvm use node 18.9.1
                                         devvm use node 18.9.1 -Persist project
                                         devvm use node 18.9.1 -Persist path
 
  current <runtime> Show currently active runtime version
                                Example: devvm current node
 
  list <runtime> List installed versions of a runtime
                                Example: devvm list node
 
  install <runtime> <version> Download and install a runtime version
                                Example: devvm install node 20.0.0
 
  available <runtime> Show available versions for download
                                Example: devvm available java
                                         devvm available java -All
                                         devvm available node -Update
 
  cache [clean] Manage cache of downloaded version lists
                                Example: devvm cache (show cache info)
                                         devvm cache clean (clear all cache)
 
  path [show|clear] [runtime] Manage persistent PATH entries
                                Example: devvm path (show status)
                                         devvm path show (show status)
                                         devvm path clear node (remove node from PATH)
                                         devvm path clear (remove all DevVm from PATH)
 
  system Show complete system information
                                (configuration + storage + cache)
                                Example: devvm system
 
  activate [runtime] Activate versions from .devvm files
                                Example: devvm activate
                                         devvm activate node
                                         devvm activate -Verify
 
  initialize, init Initialize DevVm in PowerShell profile
                                Example: devvm initialize
                                         devvm init -Force
                                Options: -Force (update if already initialized)
 
  help Show this help message
 
Persist Options:
  -Persist session (default) Only for current PowerShell session
  -Persist project Save to .devvm file in current directory
  -Persist user Save to user profile (~/.devvm)
  -Persist global Save to global configuration
  -Persist path Save to .devvm AND add to permanent user PATH
 
Config Precedence (highest wins):
  session > project > user > global
 
Supported Runtimes:
  node, java, maven and lein
 
Examples:
  devvm use node 18.9.1 # Use Node.js 18.9.1 in current session
  devvm use node 18.9.1 -Persist project # Save Node.js 18.9.1 to project .devvm
  devvm use java 11.0.2 -Persist user # Set Java 11.0.2 for user profile
  devvm use java 17.0.5 -Persist path # Save to .devvm AND add to permanent PATH
  devvm current node # Show active Node.js version
  devvm list node # List installed Node.js versions
  devvm install node 20.0.0 # Install Node.js 20.0.0
  devvm available node # Show available Node.js versions (uses cache)
  devvm available java -All # Show ALL available Java versions
  devvm available node -Update # Force fresh download, bypass cache
  devvm cache # Show cache information
  devvm cache clean # Clear all cache
  devvm path # Show persistent PATH status
  devvm path clear node # Remove node from persistent PATH
  devvm path clear # Remove all DevVm from persistent PATH
  devvm alias # List all configured aliases
  devvm alias add vm # Create 'vm' as a custom alias
  devvm alias remove vm # Remove 'vm' custom alias
  devvm system # Show complete system information
  devvm activate -Verify # Verify runtime command output after activation
  devvm initialize # Initialize DevVm profile
  devvm init -Force # Force update profile initialization
 
"@

        }

        default {
            Write-Error "Unknown command: $Command. Use 'devvm help' for usage information."
        }
    }
}