|
|
@@ -1,67 +1,177 @@
|
|
|
-$ErrorActionPreference = "Stop"
|
|
|
-
|
|
|
-function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries)
|
|
|
-{
|
|
|
- while($true)
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- Invoke-WebRequest $url -OutFile $downloadLocation
|
|
|
- break
|
|
|
- }
|
|
|
- catch
|
|
|
- {
|
|
|
- $exceptionMessage = $_.Exception.Message
|
|
|
- Write-Host "Failed to download '$url': $exceptionMessage"
|
|
|
- if ($retries -gt 0) {
|
|
|
- $retries--
|
|
|
- Write-Host "Waiting 10 seconds before retrying. Retries left: $retries"
|
|
|
- Start-Sleep -Seconds 10
|
|
|
+#!/usr/bin/env powershell
|
|
|
+#requires -version 4
|
|
|
+
|
|
|
+<#
|
|
|
+.SYNOPSIS
|
|
|
+Build this repository
|
|
|
+
|
|
|
+.DESCRIPTION
|
|
|
+Downloads korebuild if required. Then builds the repository.
|
|
|
+
|
|
|
+.PARAMETER Path
|
|
|
+The folder to build. Defaults to the folder containing this script.
|
|
|
+
|
|
|
+.PARAMETER Channel
|
|
|
+The channel of KoreBuild to download. Overrides the value from the config file.
|
|
|
+
|
|
|
+.PARAMETER DotNetHome
|
|
|
+The directory where .NET Core tools will be stored.
|
|
|
+
|
|
|
+.PARAMETER ToolsSource
|
|
|
+The base url where build tools can be downloaded. Overrides the value from the config file.
|
|
|
+
|
|
|
+.PARAMETER Update
|
|
|
+Updates KoreBuild to the latest version even if a lock file is present.
|
|
|
+
|
|
|
+.PARAMETER ConfigFile
|
|
|
+The path to the configuration file that stores values. Defaults to version.xml.
|
|
|
+
|
|
|
+.PARAMETER MSBuildArgs
|
|
|
+Arguments to be passed to MSBuild
|
|
|
+
|
|
|
+.NOTES
|
|
|
+This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be.
|
|
|
+When the lockfile is not present, KoreBuild will create one using latest available version from $Channel.
|
|
|
+
|
|
|
+The $ConfigFile is expected to be an XML file. It is optional, and the configuration values in it are optional as well.
|
|
|
+
|
|
|
+.EXAMPLE
|
|
|
+Example config file:
|
|
|
+```xml
|
|
|
+<!-- version.xml -->
|
|
|
+<Project>
|
|
|
+ <PropertyGroup>
|
|
|
+ <KoreBuildChannel>dev</KoreBuildChannel>
|
|
|
+ <KoreBuildToolsSource>https://aspnetcore.blob.core.windows.net/buildtools</KoreBuildToolsSource>
|
|
|
+ </PropertyGroup>
|
|
|
+</Project>
|
|
|
+```
|
|
|
+#>
|
|
|
+[CmdletBinding(PositionalBinding = $false)]
|
|
|
+param(
|
|
|
+ [string]$Path = $PSScriptRoot,
|
|
|
+ [Alias('c')]
|
|
|
+ [string]$Channel,
|
|
|
+ [Alias('d')]
|
|
|
+ [string]$DotNetHome,
|
|
|
+ [Alias('s')]
|
|
|
+ [string]$ToolsSource,
|
|
|
+ [Alias('u')]
|
|
|
+ [switch]$Update,
|
|
|
+ [string]$ConfigFile = (Join-Path $PSScriptRoot 'version.xml'),
|
|
|
+ [Parameter(ValueFromRemainingArguments = $true)]
|
|
|
+ [string[]]$MSBuildArgs
|
|
|
+)
|
|
|
+
|
|
|
+Set-StrictMode -Version 2
|
|
|
+$ErrorActionPreference = 'Stop'
|
|
|
+
|
|
|
+#
|
|
|
+# Functions
|
|
|
+#
|
|
|
+
|
|
|
+function Get-KoreBuild {
|
|
|
+
|
|
|
+ $lockFile = Join-Path $Path 'korebuild-lock.txt'
|
|
|
+
|
|
|
+ if (!(Test-Path $lockFile) -or $Update) {
|
|
|
+ Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile
|
|
|
+ }
|
|
|
+
|
|
|
+ $version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
|
|
|
+ if (!$version) {
|
|
|
+ Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'"
|
|
|
+ }
|
|
|
+ $version = $version.TrimStart('version:').Trim()
|
|
|
+ $korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version)
|
|
|
|
|
|
+ if (!(Test-Path $korebuildPath)) {
|
|
|
+ Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version"
|
|
|
+ New-Item -ItemType Directory -Path $korebuildPath | Out-Null
|
|
|
+ $remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip"
|
|
|
+
|
|
|
+ try {
|
|
|
+ $tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
|
|
|
+ Get-RemoteFile $remotePath $tmpfile
|
|
|
+ if (Get-Command -Name 'Expand-Archive' -ErrorAction Ignore) {
|
|
|
+ # Use built-in commands where possible as they are cross-plat compatible
|
|
|
+ Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- $exception = $_.Exception
|
|
|
- throw $exception
|
|
|
+ else {
|
|
|
+ # Fallback to old approach for old installations of PowerShell
|
|
|
+ Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
|
+ [System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath)
|
|
|
}
|
|
|
}
|
|
|
+ catch {
|
|
|
+ Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore
|
|
|
+ throw
|
|
|
+ }
|
|
|
+ finally {
|
|
|
+ Remove-Item $tmpfile -ErrorAction Ignore
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ return $korebuildPath
|
|
|
+}
|
|
|
+
|
|
|
+function Join-Paths([string]$path, [string[]]$childPaths) {
|
|
|
+ $childPaths | ForEach-Object { $path = Join-Path $path $_ }
|
|
|
+ return $path
|
|
|
}
|
|
|
|
|
|
-cd $PSScriptRoot
|
|
|
+function Get-RemoteFile([string]$RemotePath, [string]$LocalPath) {
|
|
|
+ if ($RemotePath -notlike 'http*') {
|
|
|
+ Copy-Item $RemotePath $LocalPath
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
-$repoFolder = $PSScriptRoot
|
|
|
-$env:REPO_FOLDER = $repoFolder
|
|
|
+ $retries = 10
|
|
|
+ while ($retries -gt 0) {
|
|
|
+ $retries -= 1
|
|
|
+ try {
|
|
|
+ Invoke-WebRequest -UseBasicParsing -Uri $RemotePath -OutFile $LocalPath
|
|
|
+ return
|
|
|
+ }
|
|
|
+ catch {
|
|
|
+ Write-Verbose "Request failed. $retries retries remaining"
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip"
|
|
|
-if ($env:KOREBUILD_ZIP)
|
|
|
-{
|
|
|
- $koreBuildZip=$env:KOREBUILD_ZIP
|
|
|
+ Write-Error "Download failed: '$RemotePath'."
|
|
|
}
|
|
|
|
|
|
-$buildFolder = ".build"
|
|
|
-$buildFile="$buildFolder\KoreBuild.ps1"
|
|
|
+#
|
|
|
+# Main
|
|
|
+#
|
|
|
|
|
|
-if (!(Test-Path $buildFolder)) {
|
|
|
- Write-Host "Downloading KoreBuild from $koreBuildZip"
|
|
|
+# Load configuration or set defaults
|
|
|
|
|
|
- $tempFolder=$env:TEMP + "\KoreBuild-" + [guid]::NewGuid()
|
|
|
- New-Item -Path "$tempFolder" -Type directory | Out-Null
|
|
|
+if (Test-Path $ConfigFile) {
|
|
|
+ [xml] $config = Get-Content $ConfigFile
|
|
|
+ if (!($Channel)) { [string] $Channel = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildChannel' }
|
|
|
+ if (!($ToolsSource)) { [string] $ToolsSource = Select-Xml -Xml $config -XPath '/Project/PropertyGroup/KoreBuildToolsSource' }
|
|
|
+}
|
|
|
|
|
|
- $localZipFile="$tempFolder\korebuild.zip"
|
|
|
+if (!$DotNetHome) {
|
|
|
+ $DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } `
|
|
|
+ elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} `
|
|
|
+ elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}`
|
|
|
+ else { Join-Path $PSScriptRoot '.dotnet'}
|
|
|
+}
|
|
|
|
|
|
- DownloadWithRetry -url $koreBuildZip -downloadLocation $localZipFile -retries 6
|
|
|
+if (!$Channel) { $Channel = 'dev' }
|
|
|
+if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' }
|
|
|
|
|
|
- Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
|
- [System.IO.Compression.ZipFile]::ExtractToDirectory($localZipFile, $tempFolder)
|
|
|
+# Execute
|
|
|
|
|
|
- New-Item -Path "$buildFolder" -Type directory | Out-Null
|
|
|
- copy-item "$tempFolder\**\build\*" $buildFolder -Recurse
|
|
|
+$korebuildPath = Get-KoreBuild
|
|
|
+Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1')
|
|
|
|
|
|
- # Cleanup
|
|
|
- if (Test-Path $tempFolder) {
|
|
|
- Remove-Item -Recurse -Force $tempFolder
|
|
|
- }
|
|
|
+try {
|
|
|
+ Install-Tools $ToolsSource $DotNetHome
|
|
|
+ Invoke-RepositoryBuild $Path @MSBuildArgs
|
|
|
+}
|
|
|
+finally {
|
|
|
+ Remove-Module 'KoreBuild' -ErrorAction Ignore
|
|
|
}
|
|
|
-
|
|
|
-&"$buildFile" @args
|