versioning.ps1
param( [parameter(Mandatory = $true)] [psobject] $Exported ) # Semantic Versioning & { $Exported | Add-Member ` -MemberType ScriptMethod ` -Name ParseSemVer ` -Value { param( [string] $semVerString ) $semVerParts = $semVerString -split '[-\+]' If( $semVerParts.Count -gt 2 ){ $semVerParts = @( $semVerParts[0], (($semVerParts | Select-Object -Skip 1) -join "-") ) } $versionParts = $semVerParts[0] -split '\.' $versionParts = $versionParts | ForEach-Object { [int]$_ } # Convert main version parts to integers $major = $versionParts[0] $minor = $versionParts[1] $patch = $versionParts[2] $legacyPrerelease = If( $versionParts.Count -gt 3 ){ $versionParts[3..($versionParts.Length-1)] } $preRelease = $null if ($semVerParts.Length -gt 1) { $preRelease = $semVerParts[1] } # Create a custom object New-Object PSObject -Property @{ Major = $major Minor = $minor Patch = $patch LegacyPrerelease = $legacyPrerelease PreRelease = $preRelease Original = $semVerString } } $Exported | Add-Member ` -MemberType ScriptMethod ` -Name CompareSemVers ` -Value { param( $x, $y ) if ($x.Major -ne $y.Major) { return $x.Major - $y.Major } if ($x.Minor -ne $y.Minor) { return $x.Minor - $y.Minor } if ($x.Patch -ne $y.Patch) { return $x.Patch - $y.Patch } if ($x.LegacyPrerelease -and $y.LegacyPrerelease){ $max_length = [Math]::Max( $x.LegacyPrerelease.Count, $y.LegacyPrerelease.Count ) for ($i = 0; $i -lt $max_length; $i++) { $xlp = $x.LegacyPrerelease[ $i ] $ylp = $y.LegacyPrerelease[ $i ] If( $null -eq $xlp ){ return 1 } If( $null -eq $ylp ){ return -1 } If( $xlp -ne $ylp ){ return $xlp - $ylp } } } # Handle pre-release comparison if ($x.PreRelease -and $y.PreRelease) { return [string]::Compare($x.PreRelease, $y.PreRelease) } if ($x.PreRelease) { return -1 } if ($y.PreRelease) { return 1 } return 0 } } # NuGet APIs & { $Exported | Add-Member ` -MemberType NoteProperty ` -Name APIs ` -Value (& { $apis = Invoke-WebRequest https://api.nuget.org/v3/index.json ConvertFrom-Json $apis }) $Exported | Add-Member ` -MemberType ScriptMethod ` -Name SearchLatest ` -Value { param( $Name ) $resource = $this.APIs.resources | Where-Object { ($_."@type" -eq "SearchQueryService") -and ($_.comment -like "*(primary)*") } $id = $resource."@id" $results = Invoke-WebRequest "$id`?q=packageid:$Name&prerelease=false&take=1" $results = ConvertFrom-Json $results If( $Name -eq $results.data[0].id ){ $results.data[0].version } else { Write-Warning "Unable to find latest version of $Name via NuGet Search API" } } $Exported | Add-Member ` -MemberType ScriptMethod ` -Name GetAllVersions ` -Value { param( $Name ) $resource = $this.APIs.resources | Where-Object { $_."@type" -eq "PackageBaseAddress/3.0.0" } $id = $resource."@id" $versions = @( $id, $Name, "/index.json" ) -join "" $versions = Invoke-WebRequest $versions (ConvertFrom-Json $versions).versions } $Exported | Add-Member ` -MemberType ScriptMethod ` -Name GetPreRelease ` -Value { param( $Name, $Wanted ) $versions = $this.GetAllVersions( $Name ) If( $Wanted ){ $out = $versions | Where-Object { $_ -eq $Wanted } If( $out ){ $out } Else { $versions | Select-Object -last 1 } } Else { $versions | Select-Object -last 1 } } $Exported | Add-Member ` -MemberType ScriptMethod ` -Name GetStable ` -Value { param( $Name, $Wanted ) $version = $this.GetAllVersions( $Name ) | Where-Object { $parsed = $this.ParseSemVer( $_ ) -not( $parsed.PreRelease <# -or $parsed.LegacyPrerelease #> ) } | Where-Object { If( $Wanted ){ $_ -eq $Wanted } Else { $true } } | Select-Object -Last 1 If( $version ){ $version } else { # if this is the case, Import-Package will default to GetPrerelease Write-Warning "Unable to find stable version of $Name$( If( $Wanted ){ " under version $Wanted" } )" } } } # NuGet Version Ranges & { $Exported | Add-Member ` -MemberType ScriptMethod ` -Name ParseVersOnDeps ` -Value { param( $Dependencies ) $Dependencies | Where-Object { $_ } | ForEach-Object { $version = $_.version $Out = @{ "Name" = $_.id "Version" = (& { $parsed = @{ MinVersion = $null MaxVersion = $null MinVersionInclusive = $null MaxVersionInclusive = $null } $versions = $version.Split( ',' ) if( $versions.Count -eq 1 ){ if( $versions -match "[\[\(]" ){ $parsed.MinVersion = $versions[0].TrimStart( '[', '(' ).TrimEnd( ']', ')' ) $parsed.MinVersionInclusive = $versions[0].StartsWith( '[' ) } else { $parsed.MinVersion = $versions[0] $parsed.MinVersionInclusive = $true } } else { if( $versions[0] -and ($versions[0] -match "[\[\(]") ){ $parsed.MinVersion = $versions[0].TrimStart( '[', '(' ) $parsed.MinVersionInclusive = $versions[0].StartsWith( '[' ) } else { $parsed.MinVersion = $versions[0] $parsed.MinVersionInclusive = $true } if( $versions[1] -and ($versions[1] -match "[\]\)]") ){ $parsed.MaxVersion = $versions[1].TrimEnd( ']', ')' ) $parsed.MaxVersionInclusive = $versions[1].EndsWith( ']' ) } else { $parsed.MaxVersion = $versions[1] $parsed.MaxVersionInclusive = $true } } If( $parsed.MaxVersion -and $parsed.MaxVersionInclusive ){ $parsed.MaxVersion } ElseIf ( $parsed.MinVersion -and $parsed.MinVersionInclusive ){ $parsed.MinVersion } Else { # Warn user that exclusive versions are not yet supported, and prompt user for a version Write-Warning "[Import-Package:Preparation] Exclusive version ranges are not yet supported." } }) } $Out } } } |