ps/Modules/Alkami.PowerShell.Choco/Public/Invoke-ChocoInstallPackagesPrivate.ps1
2023-05-30 22:51:22 -07:00

158 lines
5.5 KiB
PowerShell

function Invoke-ChocoInstallPackagesPrivate {
<#
.SYNOPSIS
Installs a list of Chocolatey packages.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingInvokeExpression', '', Justification = 'Alkami generates this string manually, no user injection')]
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[Alias("PackagesToInstall")]
[object[]]$packages,
[Parameter(Mandatory = $false)]
[Alias("f")]
[switch]$force,
[Parameter(Mandatory = $false)]
[Alias("e")]
[string]$environment,
[Parameter(Mandatory = $false)]
[Alias("migrate", "m")]
[switch]$runMigrations,
[Parameter(Mandatory = $false)]
[Alias("start", "s")]
[switch]$startService,
[Parameter(Mandatory = $false)]
[switch]$forceSameVersion,
[Parameter(Mandatory = $false)]
[switch]$ignoreDependencies,
[Parameter(Mandatory = $false)]
[switch]$preventDowngrade,
[Parameter(Mandatory = $false)]
[switch]$SkipScripts
)
$loglead = Get-LogLeadName;
if (!(Test-IsAdmin)) {
throw "$loglead : User must be an administrator to run Chocolatey installs."
}
if($packages.Count -gt 1) {
$localPackages = Get-ChocoState -l;
} else {
$localPackages = Get-ChocoState -l -packageName $packages[0].Name;
}
$numPackages = $packages.count;
Write-Verbose "$loglead : Now installing $numPackages packages:";
$success = $true;
$counter = 0;
foreach ($package in $packages) {
$name = $package.Name;
$version = $package.Version;
$counter++
try {
$chocoParams = Get-ChocolateyParameterString $package -env $environment -start $startService.IsPresent -migrate $runMigrations.IsPresent;
$localPackage = ($localPackages | Where-Object { $_.Name -eq $name });
$isInstalled = $null -ne ($localPackage);
# Upgrade if the package is already installed.
# set local package version to null if not installed
if (!$isInstalled ) {
$commandFlag = "install"
$localPackageVersion = "0.0.0"
} else {
$commandFlag = "upgrade"
$localPackageVersion = $localpackage.Version
}
# Compare two sematic verions
# -1 if $Version1 < $Version2
# 0 if $Version1 = $Version2
# 1 if $Version1 > $Version2
switch ((Compare-SemVer -version1 $localPackageVersion -version2 $version)) {
1 {
$isSameVersion = $false
$isDowngrade = $true
}
0 {
# The Compare-SemVer function will say that certain pre-versions are the same version, and prevent installs.
# This string version comparison hack allows these packages to be considered different versions.
$isSameVersion = $localPackageVersion -eq $version
}
-1 {
$isSameVersion = $false
$isDowngrade = $false
}
Default {
}
}
$forceSwitch = "";
$forceInstall = $force.IsPresent -or ($forceSameVersion.IsPresent -and $isSameVersion);
if ($forceInstall) {
$forceSwitch = "-f";
}
# If we're not forcing a package, and it's the same version, then skip the choco install.
if((!$forceInstall) -and ($isInstalled) -and ($isSameVersion)) {
Write-Host "$loglead : Skipping install of $name $version because it is already installed."
continue;
}
# Handle ignore-dependency / allow-downgrade flags
$ignoreDependenciesFlag = if ($ignoreDependencies.IsPresent -or $isSameVersion -or $isDowngrade) {
"--ignore-dependencies"
} else {
""
};
$downgradeFlag = if ($preventDowngrade.IsPresent) {
""
} elseif ($isDowngrade) {
"--allow-downgrade"
} else {
""
};
#Skips running `chocoInstall.ps1` as part of `choco install/upgrade` process
#Still adds requested package to /lib
#Makes choco "think" this package is "installed" without running install script
$skipInstallScriptFlag = if ($SkipScripts.IsPresent) {
"--skipscripts"
} else {
""
}
if ($isSameVersion -and $forceInstall -and $skipInstallScriptFlag) {
Write-Host "$loglead : Skipping download to just copy same version with componentized installer."
continue
}
Write-Host "$loglead : Now installing ($counter/$numPackages) '$name $version':";
$command = "choco $commandFlag $name --version $version -y --no-progress $downgradeFlag $ignoreDependenciesFlag $forceSwitch $skipInstallScriptFlag --params $chocoParams;"
Write-Host "Command: $command"
Invoke-Expression $command
Write-Host "$loglead : Installation of '$name $version $skipInstallScriptFlag' done."
} catch {
Write-Error $_ | Format-List -force
$success = $false;
}
}
if (!($success)) {
throw "$loglead : Installation of one or more packages failed.";
}
}