OneGet / oneget

PackageManagement (aka OneGet) is a package manager for Windows
MIT License
2.38k stars 189 forks source link

Feature request: introduce update-package #502

Closed peppekerstens closed 3 years ago

peppekerstens commented 3 years ago

At this point there is update-module which works for most PowerShell modules. Update-package is only available via the package manager console for visual studio. (https://docs.microsoft.com/en-us/nuget/reference/ps-reference/ps-ref-update-package)

As not all packages are PowerShell modules, please provide a means to update packages through the universal package manager.

Below is a PowerShell based scaffolding/proposal for this:

<#
.SYNOPSIS
Single commandlet for updating packages managed by packagemanagement. 

.DESCRIPTION
Update logic for common, non-nested, non-dependency packages like PowerShell modules. 
Can be used for both install- and update actions; reduced to a single command.
Supports -WhatIf, -Confirm and -Force .
Uses same parameters which are present in each seperate commandlet like 'install-package'

Returns an object reporting taken action:
Property        Type            Description     
Name            String          Name of the package, provided by Name parameter
IsInstalled     Boolean         Returns True if the package is present/registered in the system
Version         System.Version  Detected version, if present, at start of the command
Latest          System.Version  Detected latest version in Source.
UpdateNeeded    Boolean         Returns True if a newer version is detected in Source. Independend of -RequiredVersion. 
                                Could also be derived from Version-Latest compare. Present to ease other logic/functions/code
UpdateSucceeded Boolean         Returns True if the install or update has succeed (in any form)
Source          String          Returns the system registered source friendlyname used for update or install.

.PARAMETER Name
Provide the name of the task package.

.PARAMETER Source
Force detection of a version within this system registered source friendlyname

.PARAMETER RequiredVersion
Force update/install to this specific version

.PARAMETER SkipPublisherCheck
Ignores any publisher reference checking (like certificate validity) during install/update process

.PARAMETER AllVersions
Uninstalls all previous present versions of the package.

.PARAMETER Force
Force install a newer version. Can result in a side-by-side install of a previous version.
#>
Function Update-Package {
    [CmdletBinding(
        SupportsShouldProcess = $true,
        ConfirmImpact = 'High')]
        [OutputType([PSObject])]
    param(
        [Parameter(Mandatory = $true)]
        [String[]]$Name,
        [String]$Source,
        [String]$RequiredVersion,
        [Switch]$SkipPublisherCheck,
        [Switch]$AllVersions, 
        [Switch]$Force,
        [ValidateSet("AllUsers","CurrentUser")]
        [String]$Scope
    )

    Begin {}

    Process {
        Foreach ($N in $Name) {
            #Check if source is available otherwise stop
            $ReturnInfo = [PSCustomObject]@{
                Name            = $N
                IsInstalled     = $false
                Version         = 0
                Latest          = 0
                UpdateNeeded    = $false
                UpdateSucceeded = $false
                Source          = $Source
            }
            $SplatParam = @{
                Name = $N
            }
            $SplatPublish = @{}
            ($SkipPublisherCheck) -and ($SplatPublish.SkipPublisherCheck = $SkipPublisherCheck) | out-null
            $SplatRequiredVersion = @{}
            ($RequiredVersion) -and ($SplatRequiredVersion.RequiredVersion = $RequiredVersion) | out-null
            ($Source) -and ($SplatParam.Source = $Source) | out-null
            $SplatScope = @{}
            ($Scope) -and ($SplatScope.Scope = $Scope) | out-null
            $Latest = Find-Package @SplatParam @SplatRequiredVersion -ErrorAction Stop
            $ReturnInfo.Latest = $Latest.Version
            $Update = $false
            Try {
                $SplatParam = @{
                    Name = $N
                }
                $Installed = Get-Package @SplatScope @SplatParam -ErrorAction Stop
                $ReturnInfo.IsInstalled = $true
                $ReturnInfo.Version = $Installed.Version
                $ReturnInfo.Source = $Installed.Source
                If ($RequiredVersion){
                    If ([System.Version]$Installed.Version -ne [System.Version]$RequiredVersion) {
                        $Update = $true
                        $ReturnInfo.UpdateNeeded = $true
                    }
                }
                Else{
                    If ([System.Version]$Installed.Version -lt [System.Version]$Latest.Version) {
                        $Update = $true
                        $ReturnInfo.UpdateNeeded = $true
                    }
                }
            }
            Catch {
                $Update = $true
                $ReturnInfo.UpdateNeeded = $true
            }
            $ReturnInfo.UpdateSucceeded = $false
            If ($Update) {
                Switch ($Force) {
                    $false {$Answer = $PSCmdlet.ShouldProcess($Name)}
                    $true {$Answer = $true; $SplatParam.Force = $Force}
                }
                If ($Answer) {
                    Try {
                        $SplatAllVersions = @{}
                        ($AllVersions) -and ($SplatAllVersions.AllVersions = $AllVersions) | out-null
                        Uninstall-Package @SplatParam @SplatScope @SplatAllVersions -ErrorAction Stop | out-null
                        ($Source) -and ($SplatParam.Source = $Source) | out-null
                        $ReturnInfo.Source = (Install-Package @SplatParam @SplatScope @SplatRequiredVersion @SplatPublish -ErrorAction Stop -WarningAction Stop).Source
                        $ReturnInfo.UpdateSucceeded = $true
                    }
                    Catch {
                        Try {                      
                            #Force installation
                            $ReturnInfo.Source = (Install-Package @SplatParam @SplatScope @SplatRequiredVersion @SplatPublish -ErrorAction Stop).Source
                            $ReturnInfo.UpdateSucceeded = $true
                        }
                        Catch {
                        }
                    }
                }
            }
            #Just post current status back...
            $ReturnInfo
        }
    }

    End {}
}
alerickson commented 3 years ago

Hi @peppekerstens PackageManagement is no longer in development. Releases are only occurring as needed for primarily security related issues. So unfortunately this feature won't be implemented.

If you're looking for a PowerShell specific package manager please see PowerShellGet.