Skip to content

Commit

Permalink
Merge pull request majkinetor#114 from majkinetor/streams
Browse files Browse the repository at this point in the history
Streams
  • Loading branch information
majkinetor authored Nov 12, 2017
2 parents b24c332 + 3ccd9db commit 3bd9e87
Show file tree
Hide file tree
Showing 22 changed files with 1,304 additions and 137 deletions.
117 changes: 73 additions & 44 deletions AU/Plugins/GitReleases.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,37 @@ function GetOrCreateRelease() {
"prerelease" = $false
} | ConvertTo-Json -Compress

Write-Verbose "Trying to create the new release $tagName..."
Write-Host "Creating the new release $tagName..."
return Invoke-RestMethod -UseBasicParsing -Method Post -Uri "https://api.github.com/repos/$repository/releases" -Body $json -Headers $headers
}

[array]$packages = if ($Force) { $Info.result.updated } else { $Info.result.pushed }

if ($packages.Length -eq 0) { Write-Host "No package updated, skipping"; return }

$packagesToRelease = New-Object 'System.Collections.Generic.List[hashtable]'

$packages | % {
if ($_.Streams) {
$_.Streams.Values | ? { $_.Updated } | % {
$packagesToRelease.Add(@{
Name = $_.Name
NuspecVersion = $_.NuspecVersion
RemoteVersion = $_.RemoteVersion
NuFile = Resolve-Path ("$($_.Path)/$($_.Name).$($_.RemoteVersion).nupkg")
})
}
}
else {
$packagesToRelease.Add(@{
Name = $_.Name
NuspecVersion = $_.NuspecVersion
RemoteVersion = $_.RemoteVersion
NuFile = Resolve-Path ("$($_.Path)/$($_.Name).$($_.RemoteVersion).nupkg")
})
}
}

$origin = git config --get remote.origin.url

if (!($origin -match "github.com\/([^\/]+\/[^\/\.]+)")) {
Expand All @@ -71,64 +95,69 @@ if (!($origin -match "github.com\/([^\/]+\/[^\/\.]+)")) {
$repository = $Matches[1]

$headers = @{
Authorization = "token $ApiToken"
Authorization = "token $ApiToken"
}

if ($releaseType -eq 'date' -and !$releaseHeader) {
$releaseHeader = 'Packages updated on <date>'
} elseif (!$releaseHeader) {
$releaseHeader = '<PackageName> <RemoteVersion>'
$releaseHeader = 'Packages updated on <date>'
}
elseif (!$releaseHeader) {
$releaseHeader = '<PackageName> <RemoteVersion>'
}

if ($releaseType -eq 'date' -and !$releaseDescription) {
$releaseDescription = 'We had packages that was updated on <date>'
} elseif (!$releaseDescription) {
$releaseDescription = '<PackageName> was updated from version <NuspecVersion> to <RemoteVersion>'
$releaseDescription = 'We had packages that was updated on <date>'
}
elseif (!$releaseDescription) {
$releaseDescription = '<PackageName> was updated from version <NuspecVersion> to <RemoteVersion>'
}

$date = Get-Date -UFormat $dateFormat

if ($releaseType -eq 'date') {
$release = GetOrCreateRelease `
-tagName $date `
-releaseName ($releaseHeader -replace '<date>',$date) `
-releaseDescription ($releaseDescription -replace '<date>',$date) `
-repository $repository `
-headers $headers

if (!$release) {
Write-Error "Unable to create a new release, please check your permissions..."
return
}
$release = GetOrCreateRelease `
-tagName $date `
-releaseName ($releaseHeader -replace '<date>', $date) `
-releaseDescription ($releaseDescription -replace '<date>', $date) `
-repository $repository `
-headers $headers

if (!$release) {
Write-Error "Unable to create a new release, please check your permissions..."
return
}
}

$uploadHeaders = $headers.Clone()
$uploadHeaders['Content-Type'] = 'application/zip'

$packages | % {
if ($releaseType -eq 'package') {
$releaseName = $releaseHeader -replace '<PackageName>',$_.Name -replace '<RemoteVersion>',$_.RemoteVersion -replace '<NuspecVersion>',$_.NuspecVersion -replace '<date>',$date
$packageDesc = $releaseDescription -replace '<PackageName>',$_.Name -replace '<RemoteVersion>',$_.RemoteVersion -replace '<NuspecVersion>',$_.NuspecVersion -replace '<date>',$date
$packagesToRelease | % {
# Because we grab all streams previously, we need to ignore
# cases when a stream haven't been updated (no nupkg file created)
if (!$_.NuFile) { return }

if ($releaseType -eq 'package') {
$releaseName = $releaseHeader -replace '<PackageName>', $_.Name -replace '<RemoteVersion>', $_.RemoteVersion -replace '<NuspecVersion>', $_.NuspecVersion -replace '<date>', $date
$packageDesc = $releaseDescription -replace '<PackageName>', $_.Name -replace '<RemoteVersion>', $_.RemoteVersion -replace '<NuspecVersion>', $_.NuspecVersion -replace '<date>', $date

$release = GetOrCreateRelease `
-tagName "$($_.Name)-$($_.RemoteVersion)" `
-releaseName $releaseName `
-releaseDescription $packageDesc `
-repository $repository `
-headers $headers
}

$release = GetOrCreateRelease `
-tagName "$($_.Name)-$($_.RemoteVersion)" `
-releaseName $releaseName `
-releaseDescription $packageDesc `
-repository $repository `
-headers $headers
}

$path = Resolve-Path "$($_.Path)\*.nupkg"
$fileName = [System.IO.Path]::GetFileName($path)

$existing = $release.assets | ? name -eq $fileName
if ($existing) {
Write-Verbose "Removing existing $fileName asset..."
Invoke-RestMethod -UseBasicParsing -Uri $existing.url -method Delete -Headers $headers | Out-Null
}

$uploadUrl = $release.upload_url -replace '\{.*\}$',''
$rawContent = [System.IO.File]::ReadAllBytes($path)
Write-Host "Uploading $fileName asset..."
Invoke-RestMethod -UseBasicParsing -Uri "${uploadUrl}?name=${fileName}&label=$($_.Name) v$($_.RemoteVersion)" -Body $rawContent -Headers $uploadHeaders -Method Post | Out-Null
$fileName = [System.IO.Path]::GetFileName($_.NuFile)

$existing = $release.assets | ? name -eq $fileName
if ($existing) {
Write-Verbose "Removing existing $fileName asset..."
Invoke-RestMethod -UseBasicParsing -Uri $existing.url -method Delete -Headers $headers | Out-Null
}

$uploadUrl = $release.upload_url -replace '\{.*\}$', ''
$rawContent = [System.IO.File]::ReadAllBytes($_.NuFile)
Write-Host "Uploading $fileName asset..."
Invoke-RestMethod -UseBasicParsing -Uri "${uploadUrl}?name=${fileName}&label=$($_.Name) v$($_.RemoteVersion)" -Body $rawContent -Headers $uploadHeaders -Method Post | Out-Null
}
62 changes: 62 additions & 0 deletions AU/Private/AUPackage.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class AUPackage {
[xml] $NuspecXml
[bool] $Ignored
[string] $IgnoreMessage
[string] $StreamsPath
[System.Collections.Specialized.OrderedDictionary] $Streams

AUPackage([string] $Path ){
if ([String]::IsNullOrWhiteSpace( $Path )) { throw 'Package path can not be empty' }
Expand All @@ -23,6 +25,18 @@ class AUPackage {

$this.NuspecXml = [AUPackage]::LoadNuspecFile( $this.NuspecPath )
$this.NuspecVersion = $this.NuspecXml.package.metadata.version

$this.StreamsPath = '{0}\{1}.json' -f $this.Path, $this.Name
$this.Streams = [AUPackage]::LoadStreams( $this.StreamsPath )
}

[hashtable] GetStreamDetails() {
return @{
Path = $this.Path
Name = $this.Name
Updated = $this.Updated
RemoteVersion = $this.RemoteVersion
}
}

static [xml] LoadNuspecFile( $NuspecPath ) {
Expand All @@ -37,6 +51,30 @@ class AUPackage {
[System.IO.File]::WriteAllText($this.NuspecPath, $this.NuspecXml.InnerXml, $Utf8NoBomEncoding)
}

static [System.Collections.Specialized.OrderedDictionary] LoadStreams( $streamsPath ) {
if (!(Test-Path $streamsPath)) { return $null }
$res = [ordered] @{}
$versions = Get-Content $streamsPath | ConvertFrom-Json
$versions.psobject.Properties | % {
$stream = $_.Name
$res.Add($stream, @{ NuspecVersion = $versions.$stream })
}
return $res
}

UpdateStream( $stream, $version ){
$s = $stream.ToString()
$v = $version.ToString()
if (!$this.Streams) { $this.Streams = [ordered] @{} }
if (!$this.Streams.Contains($s)) { $this.Streams.$s = @{} }
if ($this.Streams.$s -ne 'ignore') { $this.Streams.$s.NuspecVersion = $v }
$versions = [ordered] @{}
$this.Streams.Keys | % {
$versions.Add($_, $this.Streams.$_.NuspecVersion)
}
$versions | ConvertTo-Json | Set-Content $this.StreamsPath -Encoding UTF8
}

Backup() {
$d = "$Env:TEMP\au\" + $this.Name

Expand All @@ -54,4 +92,28 @@ class AUPackage {
return "$d\_output"
}

AUPackage( [hashtable] $obj ) {
if (!$obj) { throw 'Obj can not be empty' }
$obj.Keys | ? { $_ -ne 'Streams' } | % {
$this.$_ = $obj.$_
}
if ($obj.Streams) {
$this.Streams = [ordered] @{}
$obj.Streams.psobject.Properties | % {
$this.Streams.Add($_.Name, $_.Value)
}
}
}

[hashtable] Serialize() {
$res = @{}
$this | Get-Member -Type Properties | ? { $_.Name -ne 'Streams' } | % {
$property = $_.Name
$res.Add($property, $this.$property)
}
if ($this.Streams) {
$res.Add('Streams', [PSCustomObject] $this.Streams)
}
return $res
}
}
112 changes: 112 additions & 0 deletions AU/Private/AUVersion.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
class AUVersion : System.IComparable {
[version] $Version
[string] $Prerelease
[string] $BuildMetadata

AUVersion([version] $version, [string] $prerelease, [string] $buildMetadata) {
if (!$version) { throw 'Version cannot be null.' }
$this.Version = $version
$this.Prerelease = $prerelease
$this.BuildMetadata = $buildMetadata
}

AUVersion($input) {
if (!$input) { throw 'Input cannot be null.' }
$v = [AUVersion]::Parse($input -as [string])
$this.Version = $v.Version
$this.Prerelease = $v.Prerelease
$this.BuildMetadata = $v.BuildMetadata
}

static [AUVersion] Parse([string] $input) { return [AUVersion]::Parse($input, $true) }

static [AUVersion] Parse([string] $input, [bool] $strict) {
if (!$input) { throw 'Version cannot be null.' }
$reference = [ref] $null
if (![AUVersion]::TryParse($input, $reference, $strict)) { throw "Invalid version: $input." }
return $reference.Value
}

static [bool] TryParse([string] $input, [ref] $result) { return [AUVersion]::TryParse($input, $result, $true) }

static [bool] TryParse([string] $input, [ref] $result, [bool] $strict) {
$result.Value = [AUVersion] $null
if (!$input) { return $false }
$pattern = [AUVersion]::GetPattern($strict)
if ($input -notmatch $pattern) { return $false }
$reference = [ref] $null
if (![version]::TryParse($Matches['version'], $reference)) { return $false }
$result.Value = [AUVersion]::new($reference.Value, $Matches['prerelease'], $Matches['buildMetadata'])
return $true
}

hidden static [string] GetPattern([bool] $strict) {
$versionPattern = '(?<version>\d+(?:\.\d+){0,3})'
# for now, chocolatey does only support SemVer v1 (no dot separated identifiers in pre-release):
$identifierPattern = "[0-9A-Za-z-]+"
# here is the SemVer v2 equivalent:
#$identifierPattern = "[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*"
if ($strict) {
return "^$versionPattern(?:-(?<prerelease>$identifierPattern))?(?:\+(?<buildMetadata>$identifierPattern))?`$"
} else {
return "$versionPattern(?:-?(?<prerelease>$identifierPattern))?(?:\+(?<buildMetadata>$identifierPattern))?"
}
}

[AUVersion] WithVersion([version] $version) { return [AUVersion]::new($version, $this.Prerelease, $this.BuildMetadata) }

[int] CompareTo($obj) {
if ($obj -eq $null) { return 1 }
if ($obj -isnot [AUVersion]) { throw "AUVersion expected: $($obj.GetType())" }
$t = $this.GetParts()
$o = $obj.GetParts()
for ($i = 0; $i -lt $t.Length -and $i -lt $o.Length; $i++) {
if ($t[$i].GetType() -ne $o[$i].GetType()) {
$t[$i] = [string] $t[$i]
$o[$i] = [string] $o[$i]
}
if ($t[$i] -gt $o[$i]) { return 1 }
if ($t[$i] -lt $o[$i]) { return -1 }
}
if ($t.Length -eq 1 -and $o.Length -gt 1) { return 1 }
if ($o.Length -eq 1 -and $t.Length -gt 1) { return -1 }
if ($t.Length -gt $o.Length) { return 1 }
if ($t.Length -lt $o.Length) { return -1 }
return 0
}

[bool] Equals($obj) { return $this.CompareTo($obj) -eq 0 }

[int] GetHashCode() { return $this.GetParts().GetHashCode() }

[string] ToString() {
$result = $this.Version.ToString()
if ($this.Prerelease) { $result += "-$($this.Prerelease)" }
if ($this.BuildMetadata) { $result += "+$($this.BuildMetadata)" }
return $result
}

[string] ToString([int] $fieldCount) {
if ($fieldCount -eq -1) { return $this.Version.ToString() }
return $this.Version.ToString($fieldCount)
}

hidden [object[]] GetParts() {
$result = @($this.Version)
if ($this.Prerelease) {
$this.Prerelease -split '\.' | % {
# if identifier is exclusively numeric, cast it to an int
if ($_ -match '^[0-9]+$') {
$result += [int] $_
} else {
$result += $_
}
}
}
return $result
}
}

function ConvertTo-AUVersion($Version) {
return [AUVersion] $Version
}
6 changes: 1 addition & 5 deletions AU/Private/is_version.ps1
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
# Returns [bool]
function is_version( [string] $Version ) {
$re = '^(\d{1,16})\.(\d{1,16})\.*(\d{1,16})*\.*(\d{1,16})*(-[^.-]+)*$'
if ($Version -notmatch $re) { return $false }

$v = $Version -replace '-.+'
return [version]::TryParse($v, [ref]($__))
return [AUVersion]::TryParse($Version, [ref]($__))
}
24 changes: 24 additions & 0 deletions AU/Public/Get-Version.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Author: Thomas Démoulins <tdemoulins@gmail.com>

<#
.SYNOPSIS
Get a semver-like object from a given version string.
.DESCRIPTION
This function parses a string containing a semver-like version
and returns an object that represents both the version (with up to 4 parts)
and optionally a pre-release and a build metadata.
The parsing is quite flexible:
- the string can starts with a 'v'
- there can be no hyphen between the version and the pre-release
- extra spaces (between any parts of the semver-like version) are ignored
#>
function Get-Version {
[CmdletBinding()]
param(
# Version string to parse.
[string] $Version
)
return [AUVersion]::Parse($Version, $false)
}
Loading

0 comments on commit 3bd9e87

Please sign in to comment.