From 700254259e6a1f4c811107d611427ba8aa6f0a5c Mon Sep 17 00:00:00 2001 From: Gabriel Weyer Date: Sun, 29 Dec 2019 17:49:54 +1100 Subject: [PATCH] Upgrade to .NET Core 3.1 --- README.md | 6 +- appveyor.yml | 8 +- bootstrap.ps1 | 2 +- bootstrap.sh | 2 +- build.cake | 19 +- build.ps1 | 233 ------------ build/dotnet-install.ps1 | 336 +++++++++++++----- .../Configuration/LoggerConfigurator.cs | 1 - samples/SampleConsole/Program.cs | 3 +- samples/SampleConsole/SampleConsole.csproj | 22 +- ...TableStorage.UnsupportedTypes.Tests.csproj | 9 +- 11 files changed, 289 insertions(+), 352 deletions(-) delete mode 100644 build.ps1 diff --git a/README.md b/README.md index 6ade327..abe1d77 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ | CI | Status | Platform(s) | Framework(s) | Test Framework(s) | | --- | --- | --- | --- | --- | -| [AppVeyor][app-veyor] | [![Build Status][app-veyor-shield]][app-veyor] | `Windows` | `nestandard2.0` | `netcoreapp2.2.2` | +| [AppVeyor][app-veyor] | [![Build Status][app-veyor-shield]][app-veyor] | `Windows` | `nestandard2.0` | `netcoreapp3.1` | [Azure Table storage][table-storage] supports a [limited set of data types][supported-types] (namely `byte[]`, `bool`, `DateTime`, `double`, `Guid`, `int`, `long` and `string`). `Unsupported Types` allows to store unsupported data types with some limitations: @@ -62,11 +62,11 @@ Each read and write to `Azure Table storage` will trigger the use of `Reflection ### Pre-requisites -- [.NET Core SDK v2.2.104][dotnet-sdk] and higher +- [.NET Core SDK v3.1.100][dotnet-sdk] and higher ### Initial setup on Windows -```posh +```powershell .\bootstrap.ps1 ``` diff --git a/appveyor.yml b/appveyor.yml index 2f7d768..384bc52 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -image: Visual Studio 2017 +image: Visual Studio 2019 branches: only: - master @@ -74,8 +74,8 @@ environment: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true # `install` will run before `build_script` install: - # Cake build is targeting `.NET Core` `2.2.0`, so we can safely install the latest `SDK` + # Unsupported Types build is targeting `netstandard2.0`, so we can safely install the LTS `SDK` # The `SDK` is required to restore, build, publish... a `.NET Core` application # https://www.microsoft.com/net/download/windows - - ps: .\build\dotnet-install.ps1 -Channel 2.2 -Version 2.2.104 - - ps: dotnet tool install --global Cake.Tool --version 0.31.0 + - ps: .\build\dotnet-install.ps1 + - ps: dotnet tool install --global Cake.Tool --version 0.35.0 diff --git a/bootstrap.ps1 b/bootstrap.ps1 index a880ec0..8edd279 100644 --- a/bootstrap.ps1 +++ b/bootstrap.ps1 @@ -1,3 +1,3 @@ -dotnet tool install Cake.Tool --global --version 0.31.0 +dotnet tool install Cake.Tool --global --version 0.35.0 dotnet cake build.cake --bootstrap dotnet cake build.cake diff --git a/bootstrap.sh b/bootstrap.sh index a880ec0..8edd279 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,3 +1,3 @@ -dotnet tool install Cake.Tool --global --version 0.31.0 +dotnet tool install Cake.Tool --global --version 0.35.0 dotnet cake build.cake --bootstrap dotnet cake build.cake diff --git a/build.cake b/build.cake index ef06d09..826b45b 100644 --- a/build.cake +++ b/build.cake @@ -1,6 +1,6 @@ -#module nuget:?package=Cake.DotNetTool.Module&version=0.1.0 +#module nuget:?package=Cake.DotNetTool.Module&version=0.4.0 -#tool dotnet:?package=GitVersion.Tool&version=4.0.1-beta1-58 +#tool dotnet:?package=GitVersion.Tool&version=5.1.3 var target = Argument("target", "Default"); var configuration = Argument("configuration", "Release"); @@ -78,21 +78,20 @@ Task("Test") .IsDependentOn("Build") .Does(() => { - var settings = new DotNetCoreToolSettings(); - - var argumentsBuilder = new ProcessArgumentBuilder() - .Append("-configuration") - .Append(configuration) - .Append("-nobuild"); + var settings = new DotNetCoreTestSettings + { + Configuration = configuration, + NoBuild = true + }; var projectFiles = GetFiles("./tests/*/*.Tests.csproj"); foreach (var projectFile in projectFiles) { var testResultsFile = testsResultsDir.Combine($"{projectFile.GetFilenameWithoutExtension()}.xml"); - var arguments = $"{argumentsBuilder.Render()} -xml \"{testResultsFile}\""; + settings.Logger = $"\"xunit;LogFilePath={testResultsFile}\""; - DotNetCoreTool(projectFile, "xunit", arguments, settings); + DotNetCoreTest(projectFile.FullPath, settings); } }); diff --git a/build.ps1 b/build.ps1 deleted file mode 100644 index ef4e19f..0000000 --- a/build.ps1 +++ /dev/null @@ -1,233 +0,0 @@ -########################################################################## -# This is the Cake bootstrapper script for PowerShell. -# This file was downloaded from https://github.com/cake-build/resources -# Feel free to change this file to fit your needs. -########################################################################## - -<# - -.SYNOPSIS -This is a Powershell script to bootstrap a Cake build. - -.DESCRIPTION -This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) -and execute your Cake build script with the parameters you provide. - -.PARAMETER Script -The build script to execute. -.PARAMETER Target -The build script target to run. -.PARAMETER Configuration -The build configuration to use. -.PARAMETER Verbosity -Specifies the amount of information to be displayed. -.PARAMETER ShowDescription -Shows description about tasks. -.PARAMETER DryRun -Performs a dry run. -.PARAMETER Experimental -Uses the nightly builds of the Roslyn script engine. -.PARAMETER Mono -Uses the Mono Compiler rather than the Roslyn script engine. -.PARAMETER SkipToolPackageRestore -Skips restoring of packages. -.PARAMETER ScriptArgs -Remaining arguments are added here. - -.LINK -https://cakebuild.net - -#> - -[CmdletBinding()] -Param( - [string]$Script = "build.cake", - [string]$Target, - [string]$Configuration, - [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] - [string]$Verbosity, - [switch]$ShowDescription, - [Alias("WhatIf", "Noop")] - [switch]$DryRun, - [switch]$Experimental, - [switch]$Mono, - [switch]$SkipToolPackageRestore, - [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] - [string[]]$ScriptArgs -) - -[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null -function MD5HashFile([string] $filePath) -{ - if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf)) - { - return $null - } - - [System.IO.Stream] $file = $null; - [System.Security.Cryptography.MD5] $md5 = $null; - try - { - $md5 = [System.Security.Cryptography.MD5]::Create() - $file = [System.IO.File]::OpenRead($filePath) - return [System.BitConverter]::ToString($md5.ComputeHash($file)) - } - finally - { - if ($file -ne $null) - { - $file.Dispose() - } - } -} - -function GetProxyEnabledWebClient -{ - $wc = New-Object System.Net.WebClient - $proxy = [System.Net.WebRequest]::GetSystemWebProxy() - $proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials - $wc.Proxy = $proxy - return $wc -} - -Write-Host "Preparing to run build script..." - -if(!$PSScriptRoot){ - $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent -} - -$TOOLS_DIR = Join-Path $PSScriptRoot "tools" -$ADDINS_DIR = Join-Path $TOOLS_DIR "Addins" -$MODULES_DIR = Join-Path $TOOLS_DIR "Modules" -$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" -$CAKE_DLL = Join-Path $TOOLS_DIR "Cake.CoreCLR/Cake.dll" -$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" -$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" -$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config" -$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config" - -# Make sure tools folder exists -if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { - Write-Verbose -Message "Creating tools directory..." - New-Item -Path $TOOLS_DIR -Type directory | out-null -} - -# Make sure that packages.config exist. -if (!(Test-Path $PACKAGES_CONFIG)) { - Write-Verbose -Message "Downloading packages.config..." - try { - $wc = GetProxyEnabledWebClient - $wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { - Throw "Could not download packages.config." - } -} - -# Try find NuGet.exe in path if not exists -if (!(Test-Path $NUGET_EXE)) { - Write-Verbose -Message "Trying to find nuget.exe in PATH..." - $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) } - $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 - if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { - Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." - $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName - } -} - -# Try download NuGet.exe if not exists -if (!(Test-Path $NUGET_EXE)) { - Write-Verbose -Message "Downloading NuGet.exe..." - try { - $wc = GetProxyEnabledWebClient - $wc.DownloadFile($NUGET_URL, $NUGET_EXE) - } catch { - Throw "Could not download NuGet.exe." - } -} - -# Save nuget.exe path to environment to be available to child processed -$ENV:NUGET_EXE = $NUGET_EXE - -# Restore tools from NuGet? -if(-Not $SkipToolPackageRestore.IsPresent) { - Push-Location - Set-Location $TOOLS_DIR - - # Check for changes in packages.config and remove installed tools if true. - [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG) - if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or - ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) { - Write-Verbose -Message "Missing or changed package.config hash..." - Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery | - Remove-Item -Recurse - } - - Write-Verbose -Message "Restoring tools from NuGet..." - $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" - - if ($LASTEXITCODE -ne 0) { - Throw "An error occurred while restoring NuGet tools." - } - else - { - $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" - } - Write-Verbose -Message ($NuGetOutput | out-string) - - Pop-Location -} - -# Restore addins from NuGet -if (Test-Path $ADDINS_PACKAGES_CONFIG) { - Push-Location - Set-Location $ADDINS_DIR - - Write-Verbose -Message "Restoring addins from NuGet..." - $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`"" - - if ($LASTEXITCODE -ne 0) { - Throw "An error occurred while restoring NuGet addins." - } - - Write-Verbose -Message ($NuGetOutput | out-string) - - Pop-Location -} - -# Restore modules from NuGet -if (Test-Path $MODULES_PACKAGES_CONFIG) { - Push-Location - Set-Location $MODULES_DIR - - Write-Verbose -Message "Restoring modules from NuGet..." - $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`"" - - if ($LASTEXITCODE -ne 0) { - Throw "An error occurred while restoring NuGet modules." - } - - Write-Verbose -Message ($NuGetOutput | out-string) - - Pop-Location -} - -# Make sure that Cake has been installed. -if (!(Test-Path $CAKE_DLL)) { - Throw "Could not find Cake.dll at $CAKE_DLL" -} - -# Build Cake arguments -$cakeArguments = @("$Script"); -if ($Target) { $cakeArguments += "-target=$Target" } -if ($Configuration) { $cakeArguments += "-configuration=$Configuration" } -if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" } -if ($ShowDescription) { $cakeArguments += "-showdescription" } -if ($DryRun) { $cakeArguments += "-dryrun" } -if ($Experimental) { $cakeArguments += "-experimental" } -if ($Mono) { $cakeArguments += "-mono" } -$cakeArguments += $ScriptArgs - -# Start Cake -Write-Host "Running build script..." -&dotnet $CAKE_DLL $cakeArguments -exit $LASTEXITCODE diff --git a/build/dotnet-install.ps1 b/build/dotnet-install.ps1 index 89e6e74..16e9be8 100644 --- a/build/dotnet-install.ps1 +++ b/build/dotnet-install.ps1 @@ -15,9 +15,10 @@ - Current - most current release - LTS - most current supported release - 2-part version in a format A.B - represents a specific release - examples: 2.0; 1.0 + examples: 2.0, 1.0 - Branch name - examples: release/2.0.0; Master + examples: release/2.0.0, Master + Note: The version parameter overrides the channel parameter. .PARAMETER Version Default: latest Represents a build version on specific channel. Possible values: @@ -25,17 +26,24 @@ - coherent - most latest coherent build on specific channel coherent applies only to SDK downloads - 3-part version in a format A.B.C - represents specific version of build - examples: 2.0.0-preview2-006120; 1.1.0 + examples: 2.0.0-preview2-006120, 1.1.0 .PARAMETER InstallDir Default: %LocalAppData%\Microsoft\dotnet Path to where to install dotnet. Note that binaries will be placed directly in a given directory. .PARAMETER Architecture Default: - this value represents currently running OS architecture Architecture of dotnet binaries to be installed. - Possible values are: , x64 and x86 + Possible values are: , amd64, x64, x86, arm64, arm .PARAMETER SharedRuntime - Default: false - Installs just the shared runtime bits, not the entire SDK + This parameter is obsolete and may be removed in a future version of this script. + The recommended alternative is '-Runtime dotnet'. + Installs just the shared runtime bits, not the entire SDK. +.PARAMETER Runtime + Installs just a shared runtime, not the entire SDK. + Possible values: + - dotnet - the Microsoft.NETCore.App shared runtime + - aspnetcore - the Microsoft.AspNetCore.App shared runtime + - windowsdesktop - the Microsoft.WindowsDesktop.App shared runtime .PARAMETER DryRun If set it will not perform installation but instead display what command line to use to consistently install currently requested version of dotnet cli. In example if you specify version 'latest' it will display a link @@ -49,10 +57,13 @@ .PARAMETER AzureFeed Default: https://dotnetcli.azureedge.net/dotnet This parameter typically is not changed by the user. - It allows to change URL for the Azure feed used by this installer. + It allows changing the URL for the Azure feed used by this installer. .PARAMETER UncachedFeed This parameter typically is not changed by the user. - It allows to change URL for the Uncached feed used by this installer. + It allows changing the URL for the Uncached feed used by this installer. +.PARAMETER FeedCredential + Used as a query string to append to the Azure feed. + It allows changing the URL to use non-public blob storage accounts. .PARAMETER ProxyAddress If set, the installer will use the proxy when making web requests .PARAMETER ProxyUseDefaultCredentials @@ -61,29 +72,48 @@ .PARAMETER SkipNonVersionedFiles Default: false Skips installing non-versioned files if they already exist, such as dotnet.exe. +.PARAMETER NoCdn + Disable downloading from the Azure CDN, and use the uncached feed directly. +.PARAMETER JSonFile + Determines the SDK version from a user specified global.json file + Note: global.json must have a value for 'SDK:Version' #> [cmdletbinding()] param( [string]$Channel="LTS", [string]$Version="Latest", + [string]$JSonFile, [string]$InstallDir="", [string]$Architecture="", + [ValidateSet("dotnet", "aspnetcore", "windowsdesktop", IgnoreCase = $false)] + [string]$Runtime, + [Obsolete("This parameter may be removed in a future version of this script. The recommended alternative is '-Runtime dotnet'.")] [switch]$SharedRuntime, [switch]$DryRun, [switch]$NoPath, [string]$AzureFeed="https://dotnetcli.azureedge.net/dotnet", [string]$UncachedFeed="https://dotnetcli.blob.core.windows.net/dotnet", + [string]$FeedCredential, [string]$ProxyAddress, [switch]$ProxyUseDefaultCredentials, - [switch]$SkipNonVersionedFiles + [switch]$SkipNonVersionedFiles, + [switch]$NoCdn ) Set-StrictMode -Version Latest $ErrorActionPreference="Stop" $ProgressPreference="SilentlyContinue" +if ($NoCdn) { + $AzureFeed = $UncachedFeed +} + $BinFolderRelativePath="" +if ($SharedRuntime -and (-not $Runtime)) { + $Runtime = "dotnet" +} + # example path with regex: shared/1.0.0-beta-12345/somepath $VersionRegEx="/\d+\.\d+[^/]+/" $OverrideNonVersionedFiles = !$SkipNonVersionedFiles @@ -124,11 +154,10 @@ function Invoke-With-Retry([ScriptBlock]$ScriptBlock, [int]$MaxAttempts = 3, [in function Get-Machine-Architecture() { Say-Invocation $MyInvocation - # possible values: AMD64, IA64, x86 + # possible values: amd64, x64, x86, arm64, arm return $ENV:PROCESSOR_ARCHITECTURE } -# TODO: Architecture and CLIArchitecture should be unified function Get-CLIArchitecture-From-Architecture([string]$Architecture) { Say-Invocation $MyInvocation @@ -136,18 +165,27 @@ function Get-CLIArchitecture-From-Architecture([string]$Architecture) { { $_ -eq "" } { return Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture) } { ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" } { $_ -eq "x86" } { return "x86" } - default { throw "Architecture not supported. If you think this is a bug, please report it at https://github.com/dotnet/cli/issues" } + { $_ -eq "arm" } { return "arm" } + { $_ -eq "arm64" } { return "arm64" } + default { throw "Architecture not supported. If you think this is a bug, report it at https://github.com/dotnet/sdk/issues" } } } +# The version text returned from the feeds is a 1-line or 2-line string: +# For the SDK and the dotnet runtime (2 lines): +# Line 1: # commit_hash +# Line 2: # 4-part version +# For the aspnetcore runtime (1 line): +# Line 1: # 4-part version function Get-Version-Info-From-Version-Text([string]$VersionText) { Say-Invocation $MyInvocation - $Data = @($VersionText.Split([char[]]@(), [StringSplitOptions]::RemoveEmptyEntries)); + $Data = -split $VersionText - $VersionInfo = @{} - $VersionInfo.CommitHash = $Data[0].Trim() - $VersionInfo.Version = $Data[1].Trim() + $VersionInfo = @{ + CommitHash = $(if ($Data.Count -gt 1) { $Data[0] }) + Version = $Data[-1] # last line is always the version number. + } return $VersionInfo } @@ -194,13 +232,15 @@ function GetHTTPResponse([Uri] $Uri) $HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler } else { + $HttpClient = New-Object System.Net.Http.HttpClient } # Default timeout for HttpClient is 100s. For a 50 MB download this assumes 500 KB/s average, any less will time out - # 10 minutes allows it to work over much slower connections. - $HttpClient.Timeout = New-TimeSpan -Minutes 10 - $Response = $HttpClient.GetAsync($Uri).Result + # 20 minutes allows it to work over much slower connections. + $HttpClient.Timeout = New-TimeSpan -Minutes 20 + $Response = $HttpClient.GetAsync("${Uri}${FeedCredential}").Result if (($Response -eq $null) -or (-not ($Response.IsSuccessStatusCode))) { + # The feed credential is potentially sensitive info. Do not log FeedCredential to console output. $ErrorMsg = "Failed to download $Uri." if ($Response -ne $null) { $ErrorMsg += " $Response" @@ -219,15 +259,21 @@ function GetHTTPResponse([Uri] $Uri) }) } - function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel, [bool]$Coherent) { Say-Invocation $MyInvocation $VersionFileUrl = $null - if ($SharedRuntime) { + if ($Runtime -eq "dotnet") { $VersionFileUrl = "$UncachedFeed/Runtime/$Channel/latest.version" } - else { + elseif ($Runtime -eq "aspnetcore") { + $VersionFileUrl = "$UncachedFeed/aspnetcore/Runtime/$Channel/latest.version" + } + # Currently, the WindowsDesktop runtime is manufactured with the .Net core runtime + elseif ($Runtime -eq "windowsdesktop") { + $VersionFileUrl = "$UncachedFeed/Runtime/$Channel/latest.version" + } + elseif (-not $Runtime) { if ($Coherent) { $VersionFileUrl = "$UncachedFeed/Sdk/$Channel/latest.coherent.version" } @@ -235,8 +281,15 @@ function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel, [bool]$Co $VersionFileUrl = "$UncachedFeed/Sdk/$Channel/latest.version" } } - - $Response = GetHTTPResponse -Uri $VersionFileUrl + else { + throw "Invalid value for `$Runtime" + } + try { + $Response = GetHTTPResponse -Uri $VersionFileUrl + } + catch { + throw "Could not resolve version information." + } $StringContent = $Response.Content.ReadAsStringAsync().Result switch ($Response.Content.Headers.ContentType) { @@ -251,34 +304,82 @@ function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel, [bool]$Co return $VersionInfo } - -function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel, [string]$Version) { +function Parse-Jsonfile-For-Version([string]$JSonFile) { Say-Invocation $MyInvocation - switch ($Version.ToLower()) { - { $_ -eq "latest" } { - $LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $False - return $LatestVersionInfo.Version + If (-Not (Test-Path $JSonFile)) { + throw "Unable to find '$JSonFile'" + } + try { + $JSonContent = Get-Content($JSonFile) -Raw | ConvertFrom-Json | Select-Object -expand "sdk" -ErrorAction SilentlyContinue + } + catch { + throw "Json file unreadable: '$JSonFile'" + } + if ($JSonContent) { + try { + $JSonContent.PSObject.Properties | ForEach-Object { + $PropertyName = $_.Name + if ($PropertyName -eq "version") { + $Version = $_.Value + Say-Verbose "Version = $Version" + } + } + } + catch { + throw "Unable to parse the SDK node in '$JSonFile'" } - { $_ -eq "coherent" } { - $LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $True - return $LatestVersionInfo.Version + } + else { + throw "Unable to find the SDK node in '$JSonFile'" + } + If ($Version -eq $null) { + throw "Unable to find the SDK:version node in '$JSonFile'" + } + return $Version +} + +function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel, [string]$Version, [string]$JSonFile) { + Say-Invocation $MyInvocation + + if (-not $JSonFile) { + switch ($Version.ToLower()) { + { $_ -eq "latest" } { + $LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $False + return $LatestVersionInfo.Version + } + { $_ -eq "coherent" } { + $LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $True + return $LatestVersionInfo.Version + } + default { return $Version } } - default { return $Version } + } + else { + return Parse-Jsonfile-For-Version $JSonFile } } function Get-Download-Link([string]$AzureFeed, [string]$SpecificVersion, [string]$CLIArchitecture) { Say-Invocation $MyInvocation - if ($SharedRuntime) { + if ($Runtime -eq "dotnet") { $PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/dotnet-runtime-$SpecificVersion-win-$CLIArchitecture.zip" } - else { + elseif ($Runtime -eq "aspnetcore") { + $PayloadURL = "$AzureFeed/aspnetcore/Runtime/$SpecificVersion/aspnetcore-runtime-$SpecificVersion-win-$CLIArchitecture.zip" + } + elseif ($Runtime -eq "windowsdesktop") { + $PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/windowsdesktop-runtime-$SpecificVersion-win-$CLIArchitecture.zip" + } + elseif (-not $Runtime) { $PayloadURL = "$AzureFeed/Sdk/$SpecificVersion/dotnet-sdk-$SpecificVersion-win-$CLIArchitecture.zip" } + else { + throw "Invalid value for `$Runtime" + } - Say-Verbose "Constructed primary payload URL: $PayloadURL" + Say-Verbose "Constructed primary named payload URL: $PayloadURL" return $PayloadURL } @@ -286,14 +387,17 @@ function Get-Download-Link([string]$AzureFeed, [string]$SpecificVersion, [string function Get-LegacyDownload-Link([string]$AzureFeed, [string]$SpecificVersion, [string]$CLIArchitecture) { Say-Invocation $MyInvocation - if ($SharedRuntime) { + if (-not $Runtime) { + $PayloadURL = "$AzureFeed/Sdk/$SpecificVersion/dotnet-dev-win-$CLIArchitecture.$SpecificVersion.zip" + } + elseif ($Runtime -eq "dotnet") { $PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/dotnet-win-$CLIArchitecture.$SpecificVersion.zip" } else { - $PayloadURL = "$AzureFeed/Sdk/$SpecificVersion/dotnet-dev-win-$CLIArchitecture.$SpecificVersion.zip" + return $null } - Say-Verbose "Constructed legacy payload URL: $PayloadURL" + Say-Verbose "Constructed legacy named payload URL: $PayloadURL" return $PayloadURL } @@ -317,28 +421,11 @@ function Resolve-Installation-Path([string]$InstallDir) { return $InstallDir } -function Get-Version-Info-From-Version-File([string]$InstallRoot, [string]$RelativePathToVersionFile) { - Say-Invocation $MyInvocation - - $VersionFile = Join-Path -Path $InstallRoot -ChildPath $RelativePathToVersionFile - Say-Verbose "Local version file: $VersionFile" - - if (Test-Path $VersionFile) { - $VersionText = cat $VersionFile - Say-Verbose "Local version file text: $VersionText" - return Get-Version-Info-From-Version-Text $VersionText - } - - Say-Verbose "Local version file not found." - - return $null -} - function Is-Dotnet-Package-Installed([string]$InstallRoot, [string]$RelativePathToPackage, [string]$SpecificVersion) { Say-Invocation $MyInvocation $DotnetPackagePath = Join-Path -Path $InstallRoot -ChildPath $RelativePathToPackage | Join-Path -ChildPath $SpecificVersion - Say-Verbose "Is-Dotnet-Package-Installed: Path to a package: $DotnetPackagePath" + Say-Verbose "Is-Dotnet-Package-Installed: DotnetPackagePath=$DotnetPackagePath" return Test-Path $DotnetPackagePath -PathType Container } @@ -423,11 +510,23 @@ function Extract-Dotnet-Package([string]$ZipPath, [string]$OutPath) { } } -function DownloadFile([Uri]$Uri, [string]$OutPath) { +function DownloadFile($Source, [string]$OutPath) { + if ($Source -notlike "http*") { + # Using System.IO.Path.GetFullPath to get the current directory + # does not work in this context - $pwd gives the current directory + if (![System.IO.Path]::IsPathRooted($Source)) { + $Source = $(Join-Path -Path $pwd -ChildPath $Source) + } + $Source = Get-Absolute-Path $Source + Say "Copying file from $Source to $OutPath" + Copy-Item $Source $OutPath + return + } + $Stream = $null try { - $Response = GetHTTPResponse -Uri $Uri + $Response = GetHTTPResponse -Uri $Source $Stream = $Response.Content.ReadAsStreamAsync().Result $File = [System.IO.File]::Create($OutPath) $Stream.CopyTo($File) @@ -443,8 +542,13 @@ function DownloadFile([Uri]$Uri, [string]$OutPath) { function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot, [string]$BinFolderRelativePath) { $BinPath = Get-Absolute-Path $(Join-Path -Path $InstallRoot -ChildPath $BinFolderRelativePath) if (-Not $NoPath) { - Say "Adding to current process PATH: `"$BinPath`". Note: This change will not be visible if PowerShell was run as a child process." - $env:path = "$BinPath;" + $env:path + $SuffixedBinPath = "$BinPath;" + if (-Not $env:path.Contains($SuffixedBinPath)) { + Say "Adding to current process PATH: `"$BinPath`". Note: This change will not be visible if PowerShell was run as a child process." + $env:path = $SuffixedBinPath + $env:path + } else { + Say-Verbose "Current process PATH already contains `"$BinPath`"" + } } else { Say "Binaries of dotnet can be found in $BinPath" @@ -452,25 +556,60 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot, [string]$BinFolde } $CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture -$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version +$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version -JSonFile $JSonFile $DownloadLink = Get-Download-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture $LegacyDownloadLink = Get-LegacyDownload-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture +$InstallRoot = Resolve-Installation-Path $InstallDir +Say-Verbose "InstallRoot: $InstallRoot" +$ScriptName = $MyInvocation.MyCommand.Name + if ($DryRun) { Say "Payload URLs:" - Say "Primary - $DownloadLink" - Say "Legacy - $LegacyDownloadLink" - Say "Repeatable invocation: .\$($MyInvocation.Line)" + Say "Primary named payload URL: $DownloadLink" + if ($LegacyDownloadLink) { + Say "Legacy named payload URL: $LegacyDownloadLink" + } + $RepeatableCommand = ".\$ScriptName -Version `"$SpecificVersion`" -InstallDir `"$InstallRoot`" -Architecture `"$CLIArchitecture`"" + if ($Runtime -eq "dotnet") { + $RepeatableCommand+=" -Runtime `"dotnet`"" + } + elseif ($Runtime -eq "aspnetcore") { + $RepeatableCommand+=" -Runtime `"aspnetcore`"" + } + foreach ($key in $MyInvocation.BoundParameters.Keys) { + if (-not (@("Architecture","Channel","DryRun","InstallDir","Runtime","SharedRuntime","Version") -contains $key)) { + $RepeatableCommand+=" -$key `"$($MyInvocation.BoundParameters[$key])`"" + } + } + Say "Repeatable invocation: $RepeatableCommand" exit 0 } -$InstallRoot = Resolve-Installation-Path $InstallDir -Say-Verbose "InstallRoot: $InstallRoot" +if ($Runtime -eq "dotnet") { + $assetName = ".NET Core Runtime" + $dotnetPackageRelativePath = "shared\Microsoft.NETCore.App" +} +elseif ($Runtime -eq "aspnetcore") { + $assetName = "ASP.NET Core Runtime" + $dotnetPackageRelativePath = "shared\Microsoft.AspNetCore.App" +} +elseif ($Runtime -eq "windowsdesktop") { + $assetName = ".NET Core Windows Desktop Runtime" + $dotnetPackageRelativePath = "shared\Microsoft.WindowsDesktop.App" +} +elseif (-not $Runtime) { + $assetName = ".NET Core SDK" + $dotnetPackageRelativePath = "sdk" +} +else { + throw "Invalid value for `$Runtime" +} -$IsSdkInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage "sdk" -SpecificVersion $SpecificVersion -Say-Verbose ".NET SDK installed? $IsSdkInstalled" -if ($IsSdkInstalled) { - Say ".NET SDK version $SpecificVersion is already installed." +# Check if the SDK version is already installed. +$isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $SpecificVersion +if ($isAssetInstalled) { + Say "$assetName version $SpecificVersion is already installed." Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath exit 0 } @@ -478,30 +617,67 @@ if ($IsSdkInstalled) { New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null $installDrive = $((Get-Item $InstallRoot).PSDrive.Name); -$free = Get-CimInstance -Class win32_logicaldisk | where Deviceid -eq "${installDrive}:" -if ($free.Freespace / 1MB -le 100 ) { +$diskInfo = Get-PSDrive -Name $installDrive +if ($diskInfo.Free / 1MB -le 100) { Say "There is not enough disk space on drive ${installDrive}:" exit 0 } $ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()) Say-Verbose "Zip path: $ZipPath" + +$DownloadFailed = $false Say "Downloading link: $DownloadLink" try { - DownloadFile -Uri $DownloadLink -OutPath $ZipPath + DownloadFile -Source $DownloadLink -OutPath $ZipPath } catch { Say "Cannot download: $DownloadLink" - $DownloadLink = $LegacyDownloadLink - $ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()) - Say-Verbose "Legacy zip path: $ZipPath" - Say "Downloading legacy link: $DownloadLink" - DownloadFile -Uri $DownloadLink -OutPath $ZipPath + if ($LegacyDownloadLink) { + $DownloadLink = $LegacyDownloadLink + $ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()) + Say-Verbose "Legacy zip path: $ZipPath" + Say "Downloading legacy link: $DownloadLink" + try { + DownloadFile -Source $DownloadLink -OutPath $ZipPath + } + catch { + Say "Cannot download: $DownloadLink" + $DownloadFailed = $true + } + } + else { + $DownloadFailed = $true + } +} + +if ($DownloadFailed) { + throw "Could not find/download: `"$assetName`" with version = $SpecificVersion`nRefer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support" } Say "Extracting zip from $DownloadLink" Extract-Dotnet-Package -ZipPath $ZipPath -OutPath $InstallRoot +# Check if the SDK version is installed; if not, fail the installation. +$isAssetInstalled = $false + +# if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed. +if ($SpecificVersion -Match "rtm" -or $SpecificVersion -Match "servicing") { + $ReleaseVersion = $SpecificVersion.Split("-")[0] + Say-Verbose "Checking installation: version = $ReleaseVersion" + $isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $ReleaseVersion +} + +# Check if the SDK version is installed. +if (!$isAssetInstalled) { + Say-Verbose "Checking installation: version = $SpecificVersion" + $isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $SpecificVersion +} + +if (!$isAssetInstalled) { + throw "`"$assetName`" with version = $SpecificVersion failed to install with an unknown error." +} + Remove-Item $ZipPath Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath diff --git a/samples/SampleConsole/Configuration/LoggerConfigurator.cs b/samples/SampleConsole/Configuration/LoggerConfigurator.cs index 2ea7b1c..025a8bc 100644 --- a/samples/SampleConsole/Configuration/LoggerConfigurator.cs +++ b/samples/SampleConsole/Configuration/LoggerConfigurator.cs @@ -12,7 +12,6 @@ public static ILoggerFactory ConfigureSerilog(this IConfigurationRoot configurat var loggerConfiguration = new LoggerConfiguration() .MinimumLevel.Is(serilogLevel) - .Enrich.WithDemystifiedStackTraces() .WriteTo.Console(serilogLevel); var logger = loggerConfiguration.CreateLogger(); diff --git a/samples/SampleConsole/Program.cs b/samples/SampleConsole/Program.cs index c589581..24bfb30 100644 --- a/samples/SampleConsole/Program.cs +++ b/samples/SampleConsole/Program.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using TableStorage.UnsupportedTypes.SampleConsole.Configuration; @@ -48,7 +47,7 @@ private static void DisplayException(Exception e) Console.WriteLine("Exception: {0}", e.GetType()); Console.WriteLine("Message: {0}", e.Message); Console.WriteLine("StackTrace:"); - Console.WriteLine(e.Demystify().StackTrace); + Console.WriteLine(e.StackTrace); Console.WriteLine(); _innerExceptionCount++; diff --git a/samples/SampleConsole/SampleConsole.csproj b/samples/SampleConsole/SampleConsole.csproj index fc15da6..f734b59 100644 --- a/samples/SampleConsole/SampleConsole.csproj +++ b/samples/SampleConsole/SampleConsole.csproj @@ -1,8 +1,7 @@  Exe - netcoreapp2.2 - 2.2.2 + netcoreapp3.1 TableStorage.UnsupportedTypes.SampleConsole TableStorage.UnsupportedTypes.SampleConsole 7.1 @@ -16,16 +15,15 @@ - - - - - - - - - - + + + + + + + + + diff --git a/tests/TableStorage.UnsupportedTypes.Tests/TableStorage.UnsupportedTypes.Tests.csproj b/tests/TableStorage.UnsupportedTypes.Tests/TableStorage.UnsupportedTypes.Tests.csproj index 1e76c91..2278dca 100644 --- a/tests/TableStorage.UnsupportedTypes.Tests/TableStorage.UnsupportedTypes.Tests.csproj +++ b/tests/TableStorage.UnsupportedTypes.Tests/TableStorage.UnsupportedTypes.Tests.csproj @@ -1,16 +1,15 @@  - netcoreapp2.2 - 2.2.2 + netcoreapp3.1 false - - + + - +