-Automated aspnetcore50 tests in build script

-Documentation
This commit is contained in:
James Newton-King
2014-10-19 15:51:56 +13:00
parent 103395618b
commit 15906f1f36
8 changed files with 845 additions and 41 deletions
+50 -21
View File
@@ -17,13 +17,14 @@
$releaseDir = "$baseDir\Release"
$workingDir = "$baseDir\Working"
$builds = @(
@{Name = "Newtonsoft.Json"; TestsName = "Newtonsoft.Json.Tests"; TestsFunction = ${function:NUnitTests}; Constants=""; FinalDir="Net45"; NuGetDir = "net45"; Framework="net-4.0"; Sign=$true},
@{Name = "Newtonsoft.Json.Portable"; TestsName = "Newtonsoft.Json.Tests.Portable"; TestsFunction = ${function:NUnitTests}; Constants="PORTABLE"; FinalDir="Portable"; NuGetDir = "portable-net45+wp80+win8+wpa81+aspnetcore50"; Framework="net-4.0"; Sign=$true},
@{Name = "Newtonsoft.Json.Portable40"; TestsName = "Newtonsoft.Json.Tests.Portable40"; TestsFunction = ${function:NUnitTests}; Constants="PORTABLE40"; FinalDir="Portable40"; NuGetDir = "portable-net40+sl5+wp80+win8+wpa81+xamarinios10"; Framework="net-4.0"; Sign=$true},
@{Name = "Newtonsoft.Json.WinRT"; TestsName = "Newtonsoft.Json.Tests.WinRT"; TestsFunction = ${function:WinRTTests}; Constants="NETFX_CORE"; FinalDir="WinRT"; NuGetDir = "netcore45"; Framework="net-4.5"; Sign=$true},
@{Name = "Newtonsoft.Json.Net40"; TestsName = "Newtonsoft.Json.Tests.Net40"; TestsFunction = ${function:NUnitTests}; Constants="NET40"; FinalDir="Net40"; NuGetDir = "net40"; Framework="net-4.0"; Sign=$true},
@{Name = "Newtonsoft.Json.Net35"; TestsName = "Newtonsoft.Json.Tests.Net35"; TestsFunction = ${function:NUnitTests}; Constants="NET35"; FinalDir="Net35"; NuGetDir = "net35"; Framework="net-2.0"; Sign=$true},
@{Name = "Newtonsoft.Json.Net20"; TestsName = "Newtonsoft.Json.Tests.Net20"; TestsFunction = ${function:NUnitTests}; Constants="NET20"; FinalDir="Net20"; NuGetDir = "net20"; Framework="net-2.0"; Sign=$true}
@{Name = "Newtonsoft.Json"; TestsName = "Newtonsoft.Json.Tests"; TestsFunction = "NUnitTests"; Constants=""; FinalDir="Net45"; NuGetDir = "net45"; Framework="net-4.0"; Sign=$true},
@{Name = "Newtonsoft.Json.Portable"; TestsName = "Newtonsoft.Json.Tests.Portable"; TestsFunction = "NUnitTests"; Constants="PORTABLE"; FinalDir="Portable"; NuGetDir = "portable-net45+wp80+win8+wpa81+aspnetcore50"; Framework="net-4.0"; Sign=$true},
@{Name = "Newtonsoft.Json.Portable40"; TestsName = "Newtonsoft.Json.Tests.Portable40"; TestsFunction = "NUnitTests"; Constants="PORTABLE40"; FinalDir="Portable40"; NuGetDir = "portable-net40+sl5+wp80+win8+wpa81+xamarinios10"; Framework="net-4.0"; Sign=$true},
@{Name = $null; TestsName = "Newtonsoft.Json.Tests.AspNetCore50"; TestsFunction = "CoreClrTests"; Constants="ASPNETCORE50"; FinalDir="ASPNETCORE50"; NuGetDir = $null; Framework=$null; Sign=$null},
@{Name = "Newtonsoft.Json.WinRT"; TestsName = "Newtonsoft.Json.Tests.WinRT"; TestsFunction = "WinRTTests"; Constants="NETFX_CORE"; FinalDir="WinRT"; NuGetDir = "netcore45"; Framework="net-4.5"; Sign=$true},
@{Name = "Newtonsoft.Json.Net40"; TestsName = "Newtonsoft.Json.Tests.Net40"; TestsFunction = "NUnitTests"; Constants="NET40"; FinalDir="Net40"; NuGetDir = "net40"; Framework="net-4.0"; Sign=$true},
@{Name = "Newtonsoft.Json.Net35"; TestsName = "Newtonsoft.Json.Tests.Net35"; TestsFunction = "NUnitTests"; Constants="NET35"; FinalDir="Net35"; NuGetDir = "net35"; Framework="net-2.0"; Sign=$true},
@{Name = "Newtonsoft.Json.Net20"; TestsName = "Newtonsoft.Json.Tests.Net20"; TestsFunction = "NUnitTests"; Constants="NET20"; FinalDir="Net20"; NuGetDir = "net20"; Framework="net-2.0"; Sign=$true}
)
}
@@ -54,19 +55,22 @@ task Build -depends Clean {
foreach ($build in $builds)
{
$name = $build.Name
$finalDir = $build.FinalDir
$sign = ($build.Sign -and $signAssemblies)
if ($name -ne $null)
{
$finalDir = $build.FinalDir
$sign = ($build.Sign -and $signAssemblies)
Write-Host -ForegroundColor Green "Building " $name
Write-Host -ForegroundColor Green "Signed " $sign
Write-Host -ForegroundColor Green "Building " $name
Write-Host -ForegroundColor Green "Signed " $sign
Write-Host
Write-Host "Restoring"
exec { .\Tools\NuGet\NuGet.exe restore ".\Src\$name.sln" | Out-Default } "Error restoring $name"
Write-Host
Write-Host "Restoring"
exec { .\Tools\NuGet\NuGet.exe restore ".\Src\$name.sln" | Out-Default } "Error restoring $name"
Write-Host
Write-Host "Building"
exec { msbuild "/t:Clean;Rebuild" /p:Configuration=Release "/p:Platform=Any CPU" /p:OutputPath=bin\Release\$finalDir\ /p:AssemblyOriginatorKeyFile=$signKeyPath "/p:SignAssembly=$sign" "/p:TreatWarningsAsErrors=$treatWarningsAsErrors" "/p:VisualStudioVersion=12.0" (GetConstants $build.Constants $sign) ".\Src\$name.sln" | Out-Default } "Error building $name"
Write-Host
Write-Host "Building"
exec { msbuild "/t:Clean;Rebuild" /p:Configuration=Release "/p:Platform=Any CPU" /p:OutputPath=bin\Release\$finalDir\ /p:AssemblyOriginatorKeyFile=$signKeyPath "/p:SignAssembly=$sign" "/p:TreatWarningsAsErrors=$treatWarningsAsErrors" "/p:VisualStudioVersion=12.0" (GetConstants $build.Constants $sign) ".\Src\$name.sln" | Out-Default } "Error building $name"
}
}
}
@@ -147,27 +151,52 @@ task Test -depends Deploy {
{
if ($build.TestsFunction -ne $null)
{
$build.TestsFunction.Invoke($build)
& $build.TestsFunction $build
}
}
}
function CoreClrTests($build)
{
$name = $build.TestsName
Write-Host -ForegroundColor Green "Ensuring latest CoreCLR is installed for $name"
Write-Host
#exec { & $toolsDir\Kvm\kvm.ps1 upgrade -r CoreCLR | Out-Default }
Write-Host -ForegroundColor Green "Restoring packages for $name"
Write-Host
exec { kpm restore "$sourceDir\Newtonsoft.Json.Tests\project.json" | Out-Default }
Write-Host -ForegroundColor Green "Ensuring test project builds for $name"
Write-Host
try
{
Set-Location "$sourceDir\Newtonsoft.Json.Tests"
$logPath = "$workingDir\$name.txt"
k --configuration Release test -parallel none | Tee-Object -file $logPath
}
finally
{
Set-Location $baseDir
}
}
function WinRTTests($build)
{
$name = $build.TestsName
$finalDir = $build.FinalDir
$testsName = $build.TestsName
$testCmd = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"
$outDir = "$workingDir\Deployed\Bin\$finalDir"
Write-Host -ForegroundColor Green "Packaging test assembly $name to deployed directory"
Write-Host
exec { msbuild "$sourceDir\Newtonsoft.Json.Tests\$testsName.csproj" /p:OutDir=$outDir | Out-Default }
exec { msbuild "$sourceDir\Newtonsoft.Json.Tests\$name.csproj" /p:OutDir=$outDir | Out-Default }
Write-Host -ForegroundColor Green "Running MSTest tests " $name
Write-Host
exec { &($testCmd) $outDir\$testsName\AppPackages\$($testsName)_1.0.0.0_AnyCPU_Debug_Test\$($testsName)_1.0.0.0_AnyCPU_Debug.appx /InIsolation /Logger:trx | Out-Default } "Error running $name tests"
exec { &($testCmd) $outDir\$name\AppPackages\$($name)_1.0.0.0_AnyCPU_Debug_Test\$($name)_1.0.0.0_AnyCPU_Debug.appx /InIsolation /Logger:trx | Out-Default } "Error running $name tests"
robocopy $baseDir\TestResults $workingDir /NP | Out-Default
del $baseDir\TestResults -Recurse -Force
+17 -14
View File
@@ -139,18 +139,18 @@
<autoOutline /> -->
<para>.NET types that don't fall into any other category listed below
(i.e. aren't lists, dictionaries, dynamic, implement ISerializable, etc)
are serialized as JSON objects.</para>
<para>By default types are serialized in opt-out mode. What that means is all public fields and properties with
getters are automatically serialized to JSON and members that shouldn't be serialized are opted-out by placing
JsonIgnoreAttribute on the unwanted properties. To serialize private members the JsonPropertyAttribute can be placed on private fields and
properties or the DefaultMembersSearchFlags can be changed on DefaultContractResolver to change how members are
serialized on all types.</para>
are serialized as JSON objects. You can also force a type to be serialized as a JSON object by placing the
JsonObjectAttribute on the type.</para>
<para>By default a type's properties are serialized in opt-out mode. What that means is all public fields and properties with
getters are automatically serialized to JSON, and fields and properties that shouldn't be serialized are opted-out by placing
JsonIgnoreAttribute on them. To serialize private members the JsonPropertyAttribute can be placed on private fields and
properties.</para>
<para>Types can also be serialized using opt-in mode. Only properties and fields that have a JsonPropertyAttribute
or DataMemberAttribute on them will be serialized. Opt-in mode for an object is specified using the JsonObjectAttribute
on the class.</para>
or DataMemberAttribute on them will be serialized. Opt-in mode for an object is specified by placing the JsonObjectAttribute
or DataContractAttribute on the type.</para>
<para>Finally types can be serialized using a fields mode. All fields, both public and private, are serialized
and properties are ignored. This can be specified by setting MemberSerialization.Fields on a type with the JsonObject
attribute or by the .NET <codeEntityReference>T:System.SerializableAttribute</codeEntityReference>
and properties are ignored. This can be specified by setting MemberSerialization.Fields on a type with the JsonObjectAttribute
or by the .NET <codeEntityReference>T:System.SerializableAttribute</codeEntity`Reference>
and setting IgnoreSerializableAttribute on DefaultContractResolver to false.</para>
</content>
</section>
@@ -162,8 +162,8 @@
<autoOutline /> -->
<para> .NET lists (types that inherit from IEnumerable) and .NET arrays are converted to JSON arrays. Because JSON
arrays only support a range of values and not properties, any additional properties and fields declared on .NET
collections are not serialized. In situations where a JSON array is not wanted the JsonObjectAttribute can be placed
on a .NET type that implements IEnumerable to force the type to be serialized as a JSON object instead.</para>
collections are not serialized. In situations where a type implements IEnumerable but a JSON array is not wanted then
the JsonObjectAttribute can be placed the type to force it to be serialized as a JSON object instead.</para>
<para>JsonArrayAttribute has options on it to customize the JsonConverter, type name handling and reference handling
that are applied to collection items.</para>
<para>Note that if TypeNameHandling or PreserveReferencesHandling has been enabled for JSON arrays on the serializer
@@ -229,13 +229,16 @@
the difference being that properties and methods can be called on a dynamic property without casting. In Json.NET
dynamic properties are serialized and deserialized exactly the same as untyped objects: because dynamic isn't an actual
type Json.NET falls back to deserializing the JSON as LINQ to JSON objects.</para>
<para>The second usage of dynamic in .NET are classes that implement
<para>The second usage of dynamic in .NET are types that implement
<codeEntityReference>T:System.Dynamic.IDynamicMetaObjectProvider</codeEntityReference>. This interface lets
the implementor create dynamic objects that intercept the property and method calls on an object and use them.
<codeEntityReference>T:System.Dynamic.ExpandoObject</codeEntityReference>
is a good example of a dynamic object.</para>
<para>Dynamic objects are serialized as JSON objects. A property is written for every member name returned by
<codeEntityReference qualifyHint="true">M:System.Dynamic.DynamicMetaObject.GetDynamicMemberNames</codeEntityReference>.</para>
<codeEntityReference qualifyHint="true">M:System.Dynamic.DynamicMetaObject.GetDynamicMemberNames</codeEntityReference>.
A dynamic object's normal properties aren't serialized by default but can be included by placing the
JsonPropertyAttribute on them.
</para>
<para>When deserializing dynamic objects the serializer first attempts to set JSON property values on a normal .NET
member with the matching name. If no .NET member is found with the property name then the serializer will call
SetMember on the dynamic object. Because there is no type information for dynamic members on a dynamic object the
@@ -33,4 +33,4 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("6.0.0.0")]
[assembly: AssemblyVersion("6.0.0.0")]
[assembly: AssemblyFileVersion("6.0.6.17818")]
[assembly: AssemblyFileVersion("6.0.6.17819")]
@@ -74,4 +74,4 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("6.0.0.0")]
[assembly: AssemblyFileVersion("6.0.6.17818")]
[assembly: AssemblyFileVersion("6.0.6.17819")]
+1 -3
View File
@@ -1,9 +1,7 @@
{
"version": "1.0.0-*",
"compilationOptions": {
"define": [
"NOINTERNALS"
]
"define": []
},
"exclude":[
"LinqToSql",
@@ -91,5 +91,5 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("6.0.0.0")]
[assembly: AssemblyFileVersion("6.0.6.17818")]
[assembly: AssemblyFileVersion("6.0.6.17819")]
[assembly: CLSCompliant(true)]
+8
View File
@@ -0,0 +1,8 @@
@Echo off
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0kvm.ps1' %*"
IF EXIST "%USERPROFILE%\.kre\run-once.cmd" (
CALL "%USERPROFILE%\.kre\run-once.cmd"
DEL "%USERPROFILE%\.kre\run-once.cmd"
)
+766
View File
@@ -0,0 +1,766 @@
param(
[parameter(Position=0)]
[string] $Command,
[string] $Proxy,
[switch] $Verbosity = $false,
[alias("g")][switch] $Global = $false,
[alias("p")][switch] $Persistent = $false,
[alias("f")][switch] $Force = $false,
[alias("r")][string] $Runtime,
[switch] $X86 = $false,
[switch] $Amd64 = $false,
#deprecated
[switch] $X64 = $false,
#deprecated
[switch] $Svr50 = $false,
#deprecated
[switch] $Svrc50 = $false,
[alias("w")][switch] $Wait = $false,
[alias("a")]
[string] $Alias = $null,
[switch] $NoNative = $false,
[parameter(Position=1, ValueFromRemainingArguments=$true)]
[string[]]$Args=@()
)
$selectedArch=$null;
$defaultArch="x86"
$selectedRuntime=$null
$defaultRuntime="CLR"
$userKrePath = $env:USERPROFILE + "\.kre"
$userKrePackages = $userKrePath + "\packages"
$globalKrePath = $env:ProgramFiles + "\KRE"
$globalKrePackages = $globalKrePath + "\packages"
$feed = $env:KRE_NUGET_API_URL
function String-IsEmptyOrWhitespace([string]$str) {
return [string]::IsNullOrEmpty($str) -or $str.Trim().length -eq 0
}
if (!$feed)
{
$feed = "https://www.myget.org/F/aspnetvnext/api/v2";
}
$scriptPath = $myInvocation.MyCommand.Definition
function Kvm-Help {
@"
K Runtime Environment Version Manager - Build {{BUILD_NUMBER}}
USAGE: kvm <command> [options]
kvm upgrade [-X86][-Amd64] [-r|-Runtime CLR|CoreCLR] [-g|-Global] [-f|-Force] [-Proxy <ADDRESS>] [-NoNative]
install latest KRE from feed
set 'default' alias to installed version
add KRE bin to user PATH environment variable
-g|-Global install to machine-wide location
-f|-Force upgrade even if latest is already installed
-Proxy <ADDRESS> use given address as proxy when accessing remote server
-NoNative Do not generate native images (Effective only for CoreCLR flavors)
kvm install <semver>|<alias>|<nupkg>|latest [-X86][-Amd64] [-r|-Runtime CLR|CoreCLR] [-a|-Alias <alias>] [-g|-Global] [-f|-Force] [-NoNative]
<semver>|<alias> install requested KRE from feed
<nupkg> install requested KRE from package on local filesystem
latest install latest KRE from feed
add KRE bin to path of current command line
-p|-Persistent add KRE bin to PATH environment variables persistently
-a|-Alias <alias> set alias <alias> for requested KRE on install
-g|-Global install to machine-wide location
-f|-Force install even if specified version is already installed
-NoNative Do not generate native images (Effective only for CoreCLR flavors)
kvm use <semver>|<alias>|none [-X86][-Amd64] [-r|-Runtime CLR|CoreCLR] [-p|-Persistent] [-g|-Global]
<semver>|<alias> add KRE bin to path of current command line
none remove KRE bin from path of current command line
-p|-Persistent add KRE bin to PATH environment variables persistently
-g|-Global combined with -p to change machine PATH instead of user PATH
kvm list
list KRE versions installed
kvm alias
list KRE aliases which have been defined
kvm alias <alias>
display value of the specified alias
kvm alias <alias> <semver>|<alias> [-X86][-Amd64] [-r|-Runtime CLR|CoreCLR]
<alias> The name of the alias to set
<semver>|<alias> The KRE version to set the alias to. Alternatively use the version of the specified alias
kvm unalias <alias>
remove the specified alias
"@ -replace "`n","`r`n" | Write-Host
}
function Kvm-Global-Setup {
$kvmBinPath = "$userKrePath\bin"
If (Needs-Elevation)
{
$arguments = "-ExecutionPolicy unrestricted & '$scriptPath' setup -global -wait"
Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait
Write-Host "Adding $kvmBinPath to process PATH"
Set-Path (Change-Path $env:Path $kvmBinPath ($kvmBinPath))
Write-Host "Adding $globalKrePath;%USERPROFILE%\.kre to process KRE_HOME"
$envKreHome = $env:KRE_HOME
$envKreHome = Change-Path $envKreHome "%USERPROFILE%\.kre" ("%USERPROFILE%\.kre")
$envKreHome = Change-Path $envKreHome $globalKrePath ($globalKrePath)
$env:KRE_HOME = $envKreHome
Write-Host "Setup complete"
break
}
$scriptFolder = [System.IO.Path]::GetDirectoryName($scriptPath)
Write-Host "Copying file $kvmBinPath\kvm.ps1"
md $kvmBinPath -Force | Out-Null
copy "$scriptFolder\kvm.ps1" "$kvmBinPath\kvm.ps1"
Write-Host "Copying file $kvmBinPath\kvm.cmd"
copy "$scriptFolder\kvm.cmd" "$kvmBinPath\kvm.cmd"
Write-Host "Adding $kvmBinPath to process PATH"
Set-Path (Change-Path $env:Path $kvmBinPath ($kvmBinPath))
Write-Host "Adding $kvmBinPath to user PATH"
$userPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User)
$userPath = Change-Path $userPath $kvmBinPath ($kvmBinPath)
[Environment]::SetEnvironmentVariable("Path", $userPath, [System.EnvironmentVariableTarget]::User)
Write-Host "Adding $globalKrePath;%USERPROFILE%\.kre to process KRE_HOME"
$envKreHome = $env:KRE_HOME
$envKreHome = Change-Path $envKreHome "%USERPROFILE%\.kre" ("%USERPROFILE%\.kre")
$envKreHome = Change-Path $envKreHome $globalKrePath ($globalKrePath)
$env:KRE_HOME = $envKreHome
Write-Host "Adding $globalKrePath;%USERPROFILE%\.kre to machine KRE_HOME"
$machineKreHome = [Environment]::GetEnvironmentVariable("KRE_HOME", [System.EnvironmentVariableTarget]::Machine)
$machineKreHome = Change-Path $machineKreHome "%USERPROFILE%\.kre" ("%USERPROFILE%\.kre")
$machineKreHome = Change-Path $machineKreHome $globalKrePath ($globalKrePath)
[Environment]::SetEnvironmentVariable("KRE_HOME", $machineKreHome, [System.EnvironmentVariableTarget]::Machine)
}
function Kvm-Global-Upgrade {
$Persistent = $true
$Alias="default"
$versionOrAlias = Kvm-Find-Latest $selectedRuntime $selectedArch
If (Needs-Elevation) {
$arguments = "-ExecutionPolicy unrestricted & '$scriptPath' install '$versionOrAlias' -global $(Requested-Switches) -wait"
Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait
Kvm-Set-Global-Process-Path $versionOrAlias
break
}
Kvm-Install $versionOrAlias $true
}
function Kvm-Upgrade {
$Persistent = $true
$Alias="default"
Kvm-Install "latest" $false
}
function Add-Proxy-If-Specified {
param(
[System.Net.WebClient] $wc
)
if (!$Proxy) {
$Proxy = $env:http_proxy
}
if ($Proxy) {
$wp = New-Object System.Net.WebProxy($Proxy)
$pb = New-Object UriBuilder($Proxy)
if (!$pb.UserName) {
$wp.Credentials = [System.Net.CredentialCache]::DefaultCredentials
} else {
$wp.Credentials = New-Object System.Net.NetworkCredential($pb.UserName, $pb.Password)
}
$wc.Proxy = $wp
}
}
function Kvm-Find-Latest {
param(
[string] $platform,
[string] $architecture
)
Write-Host "Determining latest version"
$url = "$feed/GetUpdates()?packageIds=%27KRE-$platform-$architecture%27&versions=%270.0%27&includePrerelease=true&includeAllVersions=false"
$wc = New-Object System.Net.WebClient
$wc.Credentials = new-object System.Net.NetworkCredential("aspnetreadonly", "4d8a2d9c-7b80-4162-9978-47e918c9658c")
Add-Proxy-If-Specified($wc)
[xml]$xml = $wc.DownloadString($url)
$version = Select-Xml "//d:Version" -Namespace @{d='http://schemas.microsoft.com/ado/2007/08/dataservices'} $xml
if (String-IsEmptyOrWhitespace($version)) {
throw "There are no packages for platform '$platform', architecture '$architecture' in the feed '$feed'"
}
return $version
}
function Do-Kvm-Download {
param(
[string] $kreFullName,
[string] $packagesFolder
)
$parts = $kreFullName.Split(".", 2)
$url = "$feed/package/" + $parts[0] + "/" + $parts[1]
$kreFolder = Join-Path $packagesFolder $kreFullName
$kreFile = Join-Path $kreFolder "$kreFullName.nupkg"
If (Test-Path $kreFolder) {
if($Force)
{
rm $kreFolder -Recurse -Force
} else {
Write-Host "$kreFullName already installed."
return;
}
}
Write-Host "Downloading" $kreFullName "from $feed"
#Downloading to temp location
$kreTempDownload = Join-Path $packagesFolder "temp"
$tempKreFile = Join-Path $kreTempDownload "$kreFullName.nupkg"
if(Test-Path $kreTempDownload) {
del "$kreTempDownload\*" -recurse
} else {
md $kreTempDownload -Force | Out-Null
}
$wc = New-Object System.Net.WebClient
$wc.Credentials = new-object System.Net.NetworkCredential("aspnetreadonly", "4d8a2d9c-7b80-4162-9978-47e918c9658c")
Add-Proxy-If-Specified($wc)
$wc.DownloadFile($url, $tempKreFile)
Do-Kvm-Unpack $tempKreFile $kreTempDownload
md $kreFolder -Force | Out-Null
Write-Host "Installing to $kreFolder"
mv "$kreTempDownload\*" $kreFolder
Remove-Item "$kreTempDownload" -Force | Out-Null
}
function Do-Kvm-Unpack {
param(
[string] $kreFile,
[string] $kreFolder
)
Write-Host "Unpacking to" $kreFolder
$compressionLib = [System.Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
if($compressionLib -eq $null) {
try {
# Shell will not recognize nupkg as a zip and throw, so rename it to zip
$kreZip = [System.IO.Path]::ChangeExtension($kreFile, "zip")
Rename-Item $kreFile $kreZip
# Use the shell to uncompress the nupkg
$shell_app=new-object -com shell.application
$zip_file = $shell_app.namespace($kreZip)
$destination = $shell_app.namespace($kreFolder)
$destination.Copyhere($zip_file.items(), 0x14) #0x4 = don't show UI, 0x10 = overwrite files
}
finally {
# make it a nupkg again
Rename-Item $kreZip $kreFile
}
} else {
[System.IO.Compression.ZipFile]::ExtractToDirectory($kreFile, $kreFolder)
}
If (Test-Path ($kreFolder + "\[Content_Types].xml")) {
Remove-Item ($kreFolder + "\[Content_Types].xml")
}
If (Test-Path ($kreFolder + "\_rels\")) {
Remove-Item ($kreFolder + "\_rels\") -Force -Recurse
}
If (Test-Path ($kreFolder + "\package\")) {
Remove-Item ($kreFolder + "\package\") -Force -Recurse
}
}
function Kvm-Install {
param(
[string] $versionOrAlias,
[boolean] $isGlobal
)
if ($versionOrAlias -eq "latest") {
$versionOrAlias = Kvm-Find-Latest (Requested-Platform $defaultRuntime) (Requested-Architecture $defaultArch)
}
if ($versionOrAlias.EndsWith(".nupkg")) {
$kreFullName = [System.IO.Path]::GetFileNameWithoutExtension($versionOrAlias)
} else {
$kreFullName = Requested-VersionOrAlias $versionOrAlias
}
if ($isGlobal) {
if (Needs-Elevation) {
$arguments = "-ExecutionPolicy unrestricted & '$scriptPath' install '$versionOrAlias' -global $(Requested-Switches) -wait"
Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait
Kvm-Set-Global-Process-Path $versionOrAlias
break
}
$packageFolder = $globalKrePackages
} else {
$packageFolder = $userKrePackages
}
if ($versionOrAlias.EndsWith(".nupkg")) {
Set-Variable -Name "selectedArch" -Value (Package-Arch $kreFullName) -Scope Script
Set-Variable -Name "selectedRuntime" -Value (Package-Platform $kreFullName) -Scope Script
$kreFolder = "$packageFolder\$kreFullName"
$folderExists = Test-Path $kreFolder
if ($folderExists -and $Force) {
del $kreFolder -Recurse -Force
$folderExists = $false;
}
if ($folderExists) {
Write-Host "Target folder '$kreFolder' already exists"
} else {
$tempUnpackFolder = Join-Path $packageFolder "temp"
$tempKreFile = Join-Path $tempUnpackFolder "$kreFullName.nupkg"
if(Test-Path $tempUnpackFolder) {
del "$tempUnpackFolder\*" -recurse
} else {
md $tempUnpackFolder -Force | Out-Null
}
copy $versionOrAlias $tempKreFile
Do-Kvm-Unpack $tempKreFile $tempUnpackFolder
md $kreFolder -Force | Out-Null
Write-Host "Installing to $kreFolder"
mv "$tempUnpackFolder\*" $kreFolder
Remove-Item "$tempUnpackFolder" -Force | Out-Null
}
$packageVersion = Package-Version $kreFullName
Kvm-Use $packageVersion
if (!$(String-IsEmptyOrWhitespace($Alias))) {
Kvm-Alias-Set $Alias $packageVersion
}
}
else
{
Do-Kvm-Download $kreFullName $packageFolder
Kvm-Use $versionOrAlias
if (!$(String-IsEmptyOrWhitespace($Alias))) {
Kvm-Alias-Set "$Alias" $versionOrAlias
}
}
if ($kreFullName.Contains("CoreCLR")) {
if ($NoNative) {
Write-Host "Native image generation is skipped"
}
else {
Write-Host "Compiling native images for $kreFullName to improve startup performance..."
Start-Process "K" -ArgumentList "crossgen" -Wait
Write-Host "Finished native image compilation."
}
}
}
function Kvm-List {
$kreHome = $env:KRE_HOME
if (!$kreHome) {
$kreHome = "$globalKrePath;$userKrePath"
}
md ($userKrePath + "\alias\") -Force | Out-Null
$aliases = Get-ChildItem ($userKrePath + "\alias\") | Select @{label='Alias';expression={$_.BaseName}}, @{label='Name';expression={Get-Content $_.FullName }}
$items = @()
foreach($portion in $kreHome.Split(';')) {
$path = [System.Environment]::ExpandEnvironmentVariables($portion)
if (Test-Path("$path\packages")) {
$items += Get-ChildItem ("$path\packages\KRE-*") | List-Parts $aliases
}
}
$items | Sort-Object Version, Runtime, Architecture, Alias | Format-Table -AutoSize -Property @{name="Active";expression={$_.Active};alignment="center"}, "Version", "Runtime", "Architecture", "Location", "Alias"
}
filter List-Parts {
param($aliases)
$hasBin = Test-Path($_.FullName+"\bin")
if (!$hasBin) {
return
}
$active = $false
foreach($portion in $env:Path.Split(';')) {
if ($portion.StartsWith($_.FullName)) {
$active = $true
}
}
$fullAlias=""
$delim=""
foreach($alias in $aliases){
if($_.Name.Split('\', 2) -contains $alias.Name){
$fullAlias += $delim + $alias.Alias
$delim = ", "
}
}
$parts1 = $_.Name.Split('.', 2)
$parts2 = $parts1[0].Split('-', 3)
return New-Object PSObject -Property @{
Active = if ($active) { "*" } else { "" }
Version = $parts1[1]
Runtime = $parts2[1]
Architecture = $parts2[2]
Location = $_.Parent.FullName
Alias = $fullAlias
}
}
function Kvm-Global-Use {
param(
[string] $versionOrAlias
)
If (Needs-Elevation) {
$arguments = "-ExecutionPolicy unrestricted & '$scriptPath' use '$versionOrAlias' -global $(Requested-Switches) -wait"
Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait
Kvm-Set-Global-Process-Path $versionOrAlias
break
}
Kvm-Set-Global-Process-Path "$versionOrAlias"
if ($versionOrAlias -eq "none") {
if ($Persistent) {
Write-Host "Removing KRE from machine PATH"
$machinePath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine)
$machinePath = Change-Path $machinePath "" ($globalKrePackages, $userKrePackages)
[Environment]::SetEnvironmentVariable("Path", $machinePath, [System.EnvironmentVariableTarget]::Machine)
}
return;
}
$kreFullName = Requested-VersionOrAlias "$versionOrAlias"
$kreBin = Locate-KreBinFromFullName $kreFullName
if ($kreBin -eq $null) {
Write-Host "Cannot find $kreFullName, do you need to run 'kvm install $versionOrAlias'?"
return
}
if ($Persistent) {
Write-Host "Adding $kreBin to machine PATH"
$machinePath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine)
$machinePath = Change-Path $machinePath $kreBin ($globalKrePackages, $userKrePackages)
[Environment]::SetEnvironmentVariable("Path", $machinePath, [System.EnvironmentVariableTarget]::Machine)
}
}
function Kvm-Set-Global-Process-Path {
param(
[string] $versionOrAlias
)
if ($versionOrAlias -eq "none") {
Write-Host "Removing KRE from process PATH"
Set-Path (Change-Path $env:Path "" ($globalKrePackages, $userKrePackages))
return
}
$kreFullName = Requested-VersionOrAlias $versionOrAlias
$kreBin = Locate-KreBinFromFullName $kreFullName
if ($kreBin -eq $null) {
Write-Host "Cannot find $kreFullName, do you need to run 'kvm install $versionOrAlias'?"
return
}
Write-Host "Adding" $kreBin "to process PATH"
Set-Path (Change-Path $env:Path $kreBin ($globalKrePackages, $userKrePackages))
}
function Kvm-Use {
param(
[string] $versionOrAlias
)
if ($versionOrAlias -eq "none") {
Write-Host "Removing KRE from process PATH"
Set-Path (Change-Path $env:Path "" ($globalKrePackages, $userKrePackages))
if ($Persistent) {
Write-Host "Removing KRE from user PATH"
$userPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User)
$userPath = Change-Path $userPath "" ($globalKrePackages, $userKrePackages)
[Environment]::SetEnvironmentVariable("Path", $userPath, [System.EnvironmentVariableTarget]::User)
}
return;
}
$kreFullName = Requested-VersionOrAlias $versionOrAlias
$kreBin = Locate-KreBinFromFullName $kreFullName
if ($kreBin -eq $null) {
Write-Host "Cannot find $kreFullName, do you need to run 'kvm install $versionOrAlias'?"
return
}
Write-Host "Adding" $kreBin "to process PATH"
Set-Path (Change-Path $env:Path $kreBin ($globalKrePackages, $userKrePackages))
if ($Persistent) {
Write-Host "Adding $kreBin to user PATH"
$userPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User)
$userPath = Change-Path $userPath $kreBin ($globalKrePackages, $userKrePackages)
[Environment]::SetEnvironmentVariable("Path", $userPath, [System.EnvironmentVariableTarget]::User)
}
}
function Kvm-Alias-List {
md ($userKrePath + "\alias\") -Force | Out-Null
Get-ChildItem ($userKrePath + "\alias\") | Select @{label='Alias';expression={$_.BaseName}}, @{label='Name';expression={Get-Content $_.FullName }} | Format-Table -AutoSize
}
function Kvm-Alias-Get {
param(
[string] $name
)
md ($userKrePath + "\alias\") -Force | Out-Null
$aliasFilePath=$userKrePath + "\alias\" + $name + ".txt"
if (!(Test-Path $aliasFilePath)) {
Write-Host "Alias '$name' does not exist"
} else {
Write-Host "Alias '$name' is set to" (Get-Content ($userKrePath + "\alias\" + $name + ".txt"))
}
}
function Kvm-Alias-Set {
param(
[string] $name,
[string] $value
)
$kreFullName = Requested-VersionOrAlias $value
$aliasFilePath = $userKrePath + "\alias\" + $name + ".txt"
$action = if (Test-Path $aliasFilePath) { "Updating" } else { "Setting" }
Write-Host "$action alias '$name' to '$kreFullName'"
md ($userKrePath + "\alias\") -Force | Out-Null
$kreFullName | Out-File ($aliasFilePath) ascii
}
function Kvm-Unalias {
param(
[string] $name
)
$aliasPath=$userKrePath + "\alias\" + $name + ".txt"
if (Test-Path -literalPath "$aliasPath") {
Write-Host "Removing alias $name"
Remove-Item -literalPath $aliasPath
} else {
Write-Host "Cannot remove alias, '$name' is not a valid alias name"
}
}
function Locate-KreBinFromFullName() {
param(
[string] $kreFullName
)
$kreHome = $env:KRE_HOME
if (!$kreHome) {
$kreHome = "$globalKrePath;$userKrePath"
}
foreach($portion in $kreHome.Split(';')) {
$path = [System.Environment]::ExpandEnvironmentVariables($portion)
$kreBin = "$path\packages\$kreFullName\bin"
if (Test-Path "$kreBin") {
return $kreBin
}
}
return $null
}
function Package-Version() {
param(
[string] $kreFullName
)
return $kreFullName -replace '[^.]*.(.*)', '$1'
}
function Package-Platform() {
param(
[string] $kreFullName
)
return $kreFullName -replace 'KRE-([^-]*).*', '$1'
}
function Package-Arch() {
param(
[string] $kreFullName
)
return $kreFullName -replace 'KRE-[^-]*-([^.]*).*', '$1'
}
function Requested-VersionOrAlias() {
param(
[string] $versionOrAlias
)
If (Test-Path ($userKrePath + "\alias\" + $versionOrAlias + ".txt")) {
$aliasValue = Get-Content ($userKrePath + "\alias\" + $versionOrAlias + ".txt")
$parts = $aliasValue.Split('.', 2)
$pkgVersion = $parts[1]
$parts =$parts[0].Split('-', 3)
$pkgPlatform = Requested-Platform $parts[1]
$pkgArchitecture = Requested-Architecture $parts[2]
} else {
$pkgVersion = $versionOrAlias
$pkgPlatform = Requested-Platform $defaultRuntime
$pkgArchitecture = Requested-Architecture $defaultArch
}
return "KRE-" + $pkgPlatform + "-" + $pkgArchitecture + "." + $pkgVersion
}
function Requested-Platform() {
param(
[string] $default
)
if (!(String-IsEmptyOrWhitespace($selectedRuntime))) {return $selectedRuntime}
return $default
}
function Requested-Architecture() {
param(
[string] $default
)
if (!(String-IsEmptyOrWhitespace($selectedArch))) {return $selectedArch}
return $default
}
function Change-Path() {
param(
[string] $existingPaths,
[string] $prependPath,
[string[]] $removePaths
)
$newPath = $prependPath
foreach($portion in $existingPaths.Split(';')) {
$skip = $portion -eq ""
foreach($removePath in $removePaths) {
if ($portion.StartsWith($removePath)) {
$skip = $true
}
}
if (!$skip) {
$newPath = $newPath + ";" + $portion
}
}
return $newPath
}
function Set-Path() {
param(
[string] $newPath
)
md $userKrePath -Force | Out-Null
$env:Path = $newPath
@"
SET "PATH=$newPath"
"@ | Out-File ($userKrePath + "\run-once.cmd") ascii
}
function Needs-Elevation() {
$user = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
$elevated = $user.IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
return -NOT $elevated
}
function Requested-Switches() {
$arguments = ""
if ($X86) {$arguments = "$arguments -x86"}
if ($Amd64) {$arguments = "$arguments -amd64"}
#deprecated
if ($X64) {$arguments = "$arguments -x64"}
if ($selectedRuntime) {$arguments = "$arguments -runtime $selectedRuntime"}
if ($Persistent) {$arguments = "$arguments -persistent"}
if ($Force) {$arguments = "$arguments -force"}
if (!$(String-IsEmptyOrWhitespace($Alias))) {$arguments = "$arguments -alias '$Alias'"}
return $arguments
}
function Validate-And-Santitise-Switches()
{
if ($Svr50 -and $Runtime) {throw "You cannot select both the -runtime switch and the -svr50 runtimes"}
if ($Svrc50 -and $Runtime) {throw "You cannot select both the -runtime switch and the -svrc50 runtimes"}
if ($X86 -and $Amd64) {throw "You cannot select both x86 and amd64 architectures"}
if ($X86 -and $X64) {throw "You cannot select both x86 and x64 architectures"}
if ($X64 -and $Amd64) {throw "You cannot select both x64 and amd64 architectures"}
if ($Runtime) {
$validRuntimes = "CoreCLR", "CLR", "svr50", "svrc50"
$match = $validRuntimes | ? { $_ -like $Runtime } | Select -First 1
if (!$match) {throw "'$runtime' is not a valid runtime"}
Set-Variable -Name "selectedRuntime" -Value $match -Scope Script
} elseif ($Svr50) {
Write-Host "Warning: -svr50 is deprecated, use -runtime CLR for new packages."
Set-Variable -Name "selectedRuntime" -Value "svr50" -Scope Script
} elseif ($Svrc50) {
Write-Host "Warning: -svrc50 is deprecated, use -runtime CoreCLR for new packages."
Set-Variable -Name "selectedRuntime" -Value "svrc50" -Scope Script
}
if ($X64) {
Write-Host "Warning: -x64 is deprecated, use -amd64 for new packages."
Set-Variable -Name "selectedArch" -Value "x64" -Scope Script
} elseif ($Amd64) {
Set-Variable -Name "selectedArch" -Value "amd64" -Scope Script
} elseif ($X86) {
Set-Variable -Name "selectedArch" -Value "x86" -Scope Script
}
}
try {
Validate-And-Santitise-Switches
if ($Global) {
switch -wildcard ($Command + " " + $Args.Count) {
"setup 0" {Kvm-Global-Setup}
"upgrade 0" {Kvm-Global-Upgrade}
"install 1" {Kvm-Install $Args[0] $true}
"use 1" {Kvm-Global-Use $Args[0]}
default {throw "Unknown command, or global switch not supported"};
}
} else {
switch -wildcard ($Command + " " + $Args.Count) {
"setup 0" {Kvm-Global-Setup}
"upgrade 0" {Kvm-Upgrade}
"install 1" {Kvm-Install $Args[0] $false}
"list 0" {Kvm-List}
"use 1" {Kvm-Use $Args[0]}
"alias 0" {Kvm-Alias-List}
"alias 1" {Kvm-Alias-Get $Args[0]}
"alias 2" {Kvm-Alias-Set $Args[0] $Args[1]}
"unalias 1" {Kvm-Unalias $Args[0]}
"help 0" {Kvm-Help}
" 0" {Kvm-Help}
default {throw "Unknown command"};
}
}
}
catch {
Write-Host $_ -ForegroundColor Red ;
Write-Host "Type 'kvm help' for help on how to use kvm."
}
if ($Wait) {
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,AllowCtrlC")
}