AnyGet.psm1
|
# AnyGet - Universal Package Manager # Define supported sources $script:SupportedSources = @{ 'winget' = @{ 'Name' = 'Windows Package Manager' 'Command' = 'winget' 'InstallCommand' = 'winget install {0} --accept-package-agreements --accept-source-agreements' 'Platforms' = @('Windows') 'TestCommand' = 'winget --version' } 'scoop' = @{ 'Name' = 'Scoop' 'Command' = 'scoop' 'InstallCommand' = 'scoop install {0}' 'Platforms' = @('Windows', 'Linux', 'macOS') 'TestCommand' = 'scoop --version' } 'choco' = @{ 'Name' = 'Chocolatey' 'Command' = 'choco' 'InstallCommand' = 'choco install {0} -y' 'Platforms' = @('Windows') 'TestCommand' = 'choco --version' } 'npm' = @{ 'Name' = 'Node Package Manager' 'Command' = 'npm' 'InstallCommand' = 'npm install -g {0}' 'Platforms' = @('Windows', 'Linux', 'macOS') 'TestCommand' = 'npm --version' } } # Helper function to get current platform function Get-CurrentPlatform { if ($IsWindows -or $PSVersionTable.PSVersion.Major -lt 6) { return 'Windows' } elseif ($IsLinux) { return 'Linux' } elseif ($IsMacOS) { return 'macOS' } else { return 'Unknown' } } # Helper function to test if a source is available function Test-SourceAvailability { param([string]$Source) if (-not $script:SupportedSources.ContainsKey($Source)) { return $false } $sourceInfo = $script:SupportedSources[$Source] $currentPlatform = Get-CurrentPlatform if ($currentPlatform -notin $sourceInfo.Platforms) { return $false } try { $testCommand = $sourceInfo.TestCommand $null = Invoke-Expression $testCommand 2>$null return $LASTEXITCODE -eq 0 } catch { return $false } } # Get-AnyGetSources function function Get-AnyGetSources { <# .SYNOPSIS Get information about available package manager sources. .DESCRIPTION This function returns information about all supported package managers and their availability on the current system. .PARAMETER AvailableOnly Show only sources that are currently available on the system. .EXAMPLE Get-AnyGetSources Shows all supported package managers and their availability. .EXAMPLE Get-AnyGetSources -AvailableOnly Shows only package managers that are currently available. #> [CmdletBinding()] param( [Parameter(Mandatory = $false)] [switch]$AvailableOnly ) $currentPlatform = Get-CurrentPlatform $results = @() foreach ($source in $script:SupportedSources.Keys) { $sourceInfo = $script:SupportedSources[$source] $isAvailable = Test-SourceAvailability -Source $source $supportsCurrentPlatform = $currentPlatform -in $sourceInfo.Platforms if ($AvailableOnly -and -not $isAvailable) { continue } $result = [PSCustomObject]@{ Source = $source Name = $sourceInfo.Name Command = $sourceInfo.Command Available = $isAvailable Platforms = $sourceInfo.Platforms -join ', ' Status = if ($isAvailable) { 'Available' } elseif ($supportsCurrentPlatform) { 'Not Installed' } else { 'Not Supported' } } $results += $result } if ($results.Count -gt 0) { Write-Host "`nPackage Manager Sources:" -ForegroundColor Cyan Write-Host "=" * 50 -ForegroundColor Cyan $results | Format-Table -AutoSize -Property @( @{Name = 'Source'; Expression = { $_.Source }; Width = 10 }, @{Name = 'Name'; Expression = { $_.Name }; Width = 20 }, @{Name = 'Status'; Expression = { $_.Status }; Width = 15 }, @{Name = 'Platforms'; Expression = { $_.Platforms }; Width = 20 } ) Write-Host "`nCurrent Platform: $currentPlatform" -ForegroundColor Yellow Write-Host "Available Sources: $($results | Where-Object { $_.Available } | Measure-Object).Count" -ForegroundColor Green } else { Write-Warning "No package manager sources found matching the specified criteria." } return $results } # Install-AnyGet function function Install-AnyGet { <# .SYNOPSIS Install a package using any available package manager. .DESCRIPTION This function searches for and installs a package using the first available package manager that finds the package. .PARAMETER Name The name of the package to install. .PARAMETER Source The specific package manager to use. If not specified, will try all available sources. .PARAMETER Force Force installation without prompts. .EXAMPLE Install-AnyGet -Name "git" Installs git using the first available package manager. .EXAMPLE Install-AnyGet -Name "nodejs" -Source "winget" Installs nodejs specifically using winget. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory = $true, Position = 0)] [string]$Name, [Parameter(Mandatory = $false)] [ValidateSet('any', 'winget', 'scoop', 'choco', 'npm')] [string]$Source = 'any', [Parameter(Mandatory = $false)] [switch]$Force ) Write-Verbose "Installing package '$Name' using source '$Source'" # Get available sources $availableSources = @() foreach ($source in $script:SupportedSources.Keys) { if (Test-SourceAvailability -Source $source) { $availableSources += $source } } if ($availableSources.Count -eq 0) { Write-Error "No supported package managers are available on this system." return } # Determine which sources to try $sourcesToTry = @() if ($Source -eq 'any') { $sourcesToTry = $availableSources } else { if ($availableSources -contains $Source) { $sourcesToTry = @($Source) } else { Write-Error "Package manager '$Source' is not available on this system." return } } # Try each source until we find and install the package foreach ($sourceName in $sourcesToTry) { Write-Verbose "Trying to install '$Name' using $sourceName" $sourceInfo = $script:SupportedSources[$sourceName] $installCommand = $sourceInfo.InstallCommand -f $Name if ($Force) { switch ($sourceName) { 'winget' { $installCommand += ' --force' } 'choco' { $installCommand = $installCommand -replace ' -y', ' -y --force' } } } if ($PSCmdlet.ShouldProcess($Name, "Install using $sourceName")) { try { Write-Host "Installing '$Name' using $sourceName..." -ForegroundColor Green $result = Invoke-Expression $installCommand if ($LASTEXITCODE -eq 0) { Write-Host "Successfully installed '$Name' using $sourceName" -ForegroundColor Green return } else { Write-Warning "Failed to install '$Name' using $sourceName (Exit code: $LASTEXITCODE)" } } catch { Write-Warning "Error installing '$Name' using $sourceName`: $($_.Message)" } } } Write-Error "Failed to install '$Name' using any available package manager." } # Export functions Export-ModuleMember -Function @( 'Get-AnyGetSources', 'Install-AnyGet' ) |