From 114ba51bcbd2748085e88827c5d8bfbafd6ab755 Mon Sep 17 00:00:00 2001 From: "Alexander Harvey (eHealth NSW)" Date: Sat, 14 Sep 2024 19:05:23 +1000 Subject: [PATCH] [#111] Add support for HL7 Spy Adds a plugin Get-InnerHarbourHL7Spy.ps1 and a new private function Parse-SemVer for interrogating SemVers. https://hl7spy.ca/blog/ --- Nevergreen/Apps/Get-InnerHarbourHL7Spy.ps1 | 76 ++++++++++++++++++++++ Nevergreen/Private/Parse-SemVer.ps1 | 73 +++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 Nevergreen/Apps/Get-InnerHarbourHL7Spy.ps1 create mode 100644 Nevergreen/Private/Parse-SemVer.ps1 diff --git a/Nevergreen/Apps/Get-InnerHarbourHL7Spy.ps1 b/Nevergreen/Apps/Get-InnerHarbourHL7Spy.ps1 new file mode 100644 index 0000000..5da307b --- /dev/null +++ b/Nevergreen/Apps/Get-InnerHarbourHL7Spy.ps1 @@ -0,0 +1,76 @@ +$AppName = "HL7Spy" + +$Arch = "x64" # Apparently the only supported one. +$ReleaseUrl = "https://hl7spy.ca/blog/" +$ReleaseNotesUrl = "https://hl7spy.ca/release-history/" # N.B. This does not always appear to be kept upto date. +$InstallInstructionsUrl = "https://conevity.atlassian.net/wiki/spaces/HL7Spy4/pages/626065447/Download+Installation" + +Write-Verbose "Obtaining $($AppName) Release Versions from $($ReleaseUrl)...`n" + +$AppVersions = @( + @{AppName = "$($AppName)"; Type = 'exe'; URLPattern = 'HL7Spy\.(\d+\.\d+(\.\d+))'} +) + +foreach ($AppVersion in $AppVersions) { + + # Get all matching URLs + $URLs = Get-Link -Uri $ReleaseUrl -MatchProperty href -Pattern $AppVersion.URLPattern | + Set-UriPrefix -Prefix 'https://hl7spy.ca/' + + # If no URLs found, write a warning and continue + if (-not $URLs) { + Write-Warning "Could not find release for $($AppVersion.AppName) $($AppVersion.Type)" + continue + } + + # Get versions from URLs + $VersionUrlPairs = @() + foreach ($Url in $URLs) { + $VerString = Get-Version -String $Url + + # Parse the version string as a SemVer + try { + $SemVer = Parse-SemVer -VersionString $VerString + $IsStable = $true # Assuming no pre-release versions appear. + + $VersionUrlPairs += [PSCustomObject]@{ + Version = $SemVer + Url = $Url + IsStable = $IsStable + } + } catch { + Write-Warning "Invalid version format '$VerString' for URL '$Url'" + } + } + + # If no valid versions found, write a warning and continue + if (-not $VersionUrlPairs) { + Write-Warning "Could not extract valid versions for $($AppVersion.AppName) $($AppVersion.Type)" + continue + } + + # Sort versions descending + $HighestVersionPair = $VersionUrlPairs | Sort-Object -Descending -Property ` + @{ Expression = { $_.Version.Major } }, ` + @{ Expression = { $_.Version.Minor } }, ` + @{ Expression = { $_.Version.Patch } }, ` + @{ Expression = { $_.IsStable } } | ` + Select-Object -First 1 + + # Construct the version string + $VersionString = "$($HighestVersionPair.Version.Major)." + + "$($HighestVersionPair.Version.Minor)." + + "$($HighestVersionPair.Version.Patch)" + + ($HighestVersionPair.Version.PreRelease ? "-$($HighestVersionPair.Version.PreRelease)" : '') + + # Create the app with the highest version + New-NevergreenApp -Name $($AppVersion.AppName) ` + -Architecture $Arch ` + -Version $VersionString ` + -Uri $($HighestVersionPair.Url) ` + -Type $($AppVersion.Type) +} + +Write-Verbose "" +Write-Verbose "$($AppName) Install instructions are available here: $($InstallInstructionsUrl)" +Write-Verbose "$($AppName) (Version: $($Version)) Release notes are available here: $($ReleaseNotesUrl)" diff --git a/Nevergreen/Private/Parse-SemVer.ps1 b/Nevergreen/Private/Parse-SemVer.ps1 new file mode 100644 index 0000000..3586605 --- /dev/null +++ b/Nevergreen/Private/Parse-SemVer.ps1 @@ -0,0 +1,73 @@ +function Parse-SemVer { + <# + .SYNOPSIS + Parses a Semantic Versioning (SemVer) string into its components. + + .DESCRIPTION + The `Parse-SemVer` function takes a version string that follows the Semantic Versioning format + (e.g., '1.2.3', '1.2.3-alpha') and parses it into its constituent parts: Major, Minor, Patch, + and PreRelease. + + .PARAMETER VersionString + The version string to parse. It should follow the SemVer format: + Major.Minor.Patch[-PreRelease] + + .OUTPUTS + PSCustomObject + An object containing the following properties: + - Major (int): The major version number. + - Minor (int): The minor version number. + - Patch (int): The patch version number. + - PreRelease (string): The pre-release identifier, if any. + + .EXAMPLE + $SemVer = Parse-SemVer -VersionString '1.2.3' + $SemVer + + This will output: + ``` + Major : 1 + Minor : 2 + Patch : 3 + PreRelease : + ``` + + .EXAMPLE + $SemVer = Parse-SemVer -VersionString '2.5.0-beta' + $SemVer + + This will output: + ``` + Major : 2 + Minor : 5 + Patch : 0 + PreRelease : beta + ``` + + .NOTES + - The function uses a regular expression to parse the version string. + - If the version string does not match the expected SemVer pattern, the function will throw an error. + + .LINK + https://semver.org + + #> + + param ( + [string]$VersionString + ) + + $Pattern = '^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$' + $Match = [regex]::Match($VersionString, $Pattern) + + if ($Match.Success) { + return [PSCustomObject]@{ + Major = [int]$Match.Groups[1].Value + Minor = [int]$Match.Groups[2].Value + Patch = [int]$Match.Groups[3].Value + PreRelease = $Match.Groups[4].Value + } + } else { + throw "Invalid SemVer string: $VersionString" + } +}