106 lines
4.5 KiB
PowerShell
106 lines
4.5 KiB
PowerShell
|
function Format-ParseChocoPackages {
|
|||
|
<#
|
|||
|
.SYNOPSIS
|
|||
|
Returns a list of package objects parsed from choco-style "name|version" strings.
|
|||
|
|
|||
|
.DESCRIPTION
|
|||
|
Takes a list of package names and optional versions and returns array of PSObjects with properties containing
|
|||
|
the Name and Version (if entered) parsed.
|
|||
|
|
|||
|
.PARAMETER Text
|
|||
|
Can be either an array of package names with versions to parse or a NewLine-delimited string of
|
|||
|
package names and versions.
|
|||
|
|
|||
|
.PARAMETER Delimiter
|
|||
|
Delimiter to use when splitting the package name from the version in the $Text parameter. Defaults to "|"
|
|||
|
|
|||
|
.PARAMETER Validate
|
|||
|
Switch to use SemVer regular expression validation on the Version. Also performs duplicate check on 'PackageName but different Version' passed into -Text parameter.
|
|||
|
|
|||
|
.Example
|
|||
|
Format-ParseChocoPackages -Text @("alkami.api.afx|1.7.1-pre100","alkami.api.afx|1.7.1-pre100") -Validate
|
|||
|
Format-ParseChocoPackages -Text alkami.api.afx|1.7.1 -Validate
|
|||
|
Format-ParseChocoPackages -Text alkami.api.afx
|
|||
|
Format-ParseChocoPackages -Text chocolatey|v1.7.1.0
|
|||
|
#>
|
|||
|
[CmdletBinding()]
|
|||
|
[OutputType([System.Object])]
|
|||
|
[OutputType([System.Collections.ArrayList])]
|
|||
|
Param(
|
|||
|
[Parameter(Mandatory = $true)]
|
|||
|
[AllowNull()]
|
|||
|
[object]$Text,
|
|||
|
[Parameter(Mandatory = $false)]
|
|||
|
[string]$Delimiter = "|",
|
|||
|
[Parameter(Mandatory = $false)]
|
|||
|
[switch]$Validate
|
|||
|
)
|
|||
|
|
|||
|
if (!$Text) {
|
|||
|
$packages = @()
|
|||
|
return $packages
|
|||
|
}
|
|||
|
|
|||
|
$logLead = (Get-LogLeadName)
|
|||
|
|
|||
|
# Detect if it's a single string passed in and split it into a string-array per line.
|
|||
|
if(!($Text -is [array])) {
|
|||
|
$Text = $Text.Split([Environment]::NewLine)
|
|||
|
}
|
|||
|
|
|||
|
# Detect any exact duplicate lines and remove them.
|
|||
|
# If this is coming from Classify-Packages, we've already trimmed this. But if it isn't, we still want this unique to work as expected.
|
|||
|
if($Validate){
|
|||
|
$Text = $Text.Trim() | Sort-Object | Get-Unique
|
|||
|
}
|
|||
|
|
|||
|
Write-Verbose "$logLead : Parsing $($Text.Count) choco packages..."
|
|||
|
$chocoPackages = [System.Collections.ArrayList]::new()
|
|||
|
$packageMap = @{};
|
|||
|
$Text | ForEach-Object {
|
|||
|
if(!([string]::IsNullOrEmpty($_))) {
|
|||
|
|
|||
|
Write-Verbose "$logLead : Parsing $_"
|
|||
|
$option = [System.StringSplitOptions]::RemoveEmptyEntries
|
|||
|
$splitItem = $_.Trim().Split($Delimiter, $option)
|
|||
|
|
|||
|
Write-Verbose "$logLead : Package Name parsed to [$($splitItem[0])]"
|
|||
|
Write-Verbose "$logLead : Package Version parsed to [$($splitItem[1])]"
|
|||
|
|
|||
|
if($Validate -and $splitItem.Count -gt 2) {
|
|||
|
Write-Error "Package [$($_.Trim())] passed in is not in the correct SemVer3 format. Is there more than one package on a line?"
|
|||
|
}
|
|||
|
|
|||
|
# Make sure that the version isn't malformed. Should be in the proper Semver format. Regular Epxression taken from https://semver.org
|
|||
|
if($Validate -and $null -ne $splitItem[1] -and $splitItem[1] -cnotmatch "^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$") {
|
|||
|
|
|||
|
Write-Error "Version [$($splitItem[1])] of module [$($splitItem[0])] passed in is not in the correct SemVer3 format."
|
|||
|
}
|
|||
|
|
|||
|
$properties = @{ Name = $splitItem[0]; Version = $splitItem[1]; Feed = $null; Tags = $null; IsService = $null; StartMode = $null; IsValid = $false;}
|
|||
|
$pkg = New-Object -TypeName PSObject -Prop $properties
|
|||
|
|
|||
|
# Test if the package object is already in the array. Return error if same package name but different versions are in the input array.
|
|||
|
if($Validate) {
|
|||
|
|
|||
|
$lowerName = $pkg.Name.ToLower()
|
|||
|
|
|||
|
if($packageMap.ContainsKey($lowerName)) {
|
|||
|
|
|||
|
if($packageMap[$lowerName] -ne $pkg.Version) {
|
|||
|
Write-Error "Package [$($pkg.Name)] is in the list more than once with differing versions. Please review your package parameters and include only the correct version"
|
|||
|
Write-Host "##teamcity[buildProblem description='Multiple versions of $($pkg.Name) are in the install list' identity='$($pkg.Name)']"
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
$packageMap[$lowerName] = $pkg.Version
|
|||
|
}
|
|||
|
|
|||
|
$chocoPackages.Add($pkg) | Out-Null
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Write-Verbose "$logLead : Successfully parsed $($chocoPackages.Count) packages."
|
|||
|
|
|||
|
return $chocoPackages
|
|||
|
}
|