diff --git a/scripts/obtain/dotnet-install.ps1 b/scripts/obtain/dotnet-install.ps1 index 7f5f49ee6..975b93d0d 100644 --- a/scripts/obtain/dotnet-install.ps1 +++ b/scripts/obtain/dotnet-install.ps1 @@ -34,8 +34,17 @@ Architecture of dotnet binaries to be installed. Possible values are: , x64 and x86 .PARAMETER SharedRuntime + This parameter is obsolete and may be removed in a future version of this script. + The recommended alternative is '-Runtime dotnet'. + Default: false - Installs just the shared runtime bits, not the entire SDK + Installs just the shared runtime bits, not the entire SDK. + This is equivalent to specifying `-Runtime dotnet`. +.PARAMETER Runtime + Installs just a shared runtime, not the entire SDK. + Possible values: + - dotnet + - aspnetcore .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 @@ -71,6 +80,9 @@ param( [string]$Version="Latest", [string]$InstallDir="", [string]$Architecture="", + [ValidateSet("dotnet", "aspnetcore", 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, @@ -88,6 +100,10 @@ $ProgressPreference="SilentlyContinue" $BinFolderRelativePath="" +if ($SharedRuntime -and (-not $Runtime)) { + $Runtime = "dotnet" +} + # example path with regex: shared/1.0.0-beta-12345/somepath $VersionRegEx="/\d+\.\d+[^/]+/" $OverrideNonVersionedFiles = !$SkipNonVersionedFiles @@ -230,9 +246,12 @@ function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel, [bool]$Co Say-Invocation $MyInvocation $VersionFileUrl = $null - if ($SharedRuntime) { + if ($Runtime -eq "dotnet") { $VersionFileUrl = "$UncachedFeed/Runtime/$Channel/latest.version" } + elseif ($Runtime) { + $VersionFileUrl = "$UncachedFeed/Runtime/$Channel/latest.$Runtime.version" + } else { if ($Coherent) { $VersionFileUrl = "$UncachedFeed/Sdk/$Channel/latest.coherent.version" @@ -277,8 +296,8 @@ function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel, function Get-Download-Link([string]$AzureFeed, [string]$SpecificVersion, [string]$CLIArchitecture) { Say-Invocation $MyInvocation - if ($SharedRuntime) { - $PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/dotnet-runtime-$SpecificVersion-win-$CLIArchitecture.zip" + if ($Runtime) { + $PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/$Runtime-runtime-$SpecificVersion-win-$CLIArchitecture.zip" } else { $PayloadURL = "$AzureFeed/Sdk/$SpecificVersion/dotnet-sdk-$SpecificVersion-win-$CLIArchitecture.zip" @@ -292,11 +311,14 @@ 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" @@ -465,7 +487,9 @@ $LegacyDownloadLink = Get-LegacyDownload-Link -AzureFeed $AzureFeed -SpecificVer if ($DryRun) { Say "Payload URLs:" Say "Primary - $DownloadLink" - Say "Legacy - $LegacyDownloadLink" + if ($LegacyDownloadLink) { + Say "Legacy - $LegacyDownloadLink" + } Say "Repeatable invocation: .\$($MyInvocation.Line)" exit 0 } @@ -473,10 +497,22 @@ if ($DryRun) { $InstallRoot = Resolve-Installation-Path $InstallDir Say-Verbose "InstallRoot: $InstallRoot" -$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." +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.All" +} +else { + $assetName = ".NET Core SDK" + $dotnetPackageRelativePath = "sdk" +} + +$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 } @@ -498,11 +534,16 @@ try { } 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" + DownloadFile -Uri $DownloadLink -OutPath $ZipPath + } + else { + throw "Could not download $assetName version $SpecificVersion" + } } Say "Extracting zip from $DownloadLink" diff --git a/scripts/obtain/dotnet-install.sh b/scripts/obtain/dotnet-install.sh index 412f299c0..81a4de77e 100755 --- a/scripts/obtain/dotnet-install.sh +++ b/scripts/obtain/dotnet-install.sh @@ -39,6 +39,10 @@ if [ -t 1 ] && command -v tput > /dev/null; then fi fi +say_warning() { + printf "%b\n" "${yellow:-}dotnet_install: Warning: $1${normal:-}" +} + say_err() { printf "%b\n" "${red:-}dotnet_install: Error: $1${normal:-}" >&2 } @@ -134,7 +138,7 @@ get_linux_platform_name() { fi fi fi - + say_verbose "Linux specific platform name and version could not be detected: $ID.$VERSION_ID" return 1 } @@ -158,7 +162,7 @@ get_current_os_name() { return 0 fi fi - + say_err "OS name could not be detected: $ID.$VERSION_ID" return 1 } @@ -183,7 +187,7 @@ get_legacy_os_name() { fi fi fi - + say_verbose "Distribution specific OS name and version could not be detected: $ID.$VERSION_ID" return 1 } @@ -213,7 +217,7 @@ check_min_reqs() { check_pre_reqs() { eval $invocation - + local failing=false; if [ "${DOTNET_INSTALL_SKIP_PREREQS:-}" = "1" ]; then @@ -240,7 +244,7 @@ check_pre_reqs() { if [ "$failing" = true ]; then return 1 fi - + return 0 } @@ -248,7 +252,7 @@ check_pre_reqs() { # input - $1 to_lowercase() { #eval $invocation - + echo "$1" | tr '[:upper:]' '[:lower:]' return 0 } @@ -257,7 +261,7 @@ to_lowercase() { # input - $1 remove_trailing_slash() { #eval $invocation - + local input="${1:-}" echo "${input%/}" return 0 @@ -267,7 +271,7 @@ remove_trailing_slash() { # input - $1 remove_beginning_slash() { #eval $invocation - + local input="${1:-}" echo "${input#/}" return 0 @@ -278,13 +282,13 @@ remove_beginning_slash() { # child_path - $2 - this parameter can be empty combine_paths() { eval $invocation - + # TODO: Consider making it work with any number of paths. For now: if [ ! -z "${3:-}" ]; then say_err "combine_paths: Function takes two parameters." return 1 fi - + local root_path="$(remove_trailing_slash "$1")" local child_path="$(remove_beginning_slash "${2:-}")" say_verbose "combine_paths: root_path=$root_path" @@ -295,7 +299,7 @@ combine_paths() { get_machine_architecture() { eval $invocation - + # Currently the only one supported echo "x64" return 0 @@ -305,7 +309,7 @@ get_machine_architecture() { # architecture - $1 get_normalized_architecture_from_architecture() { eval $invocation - + local architecture="$(to_lowercase "$1")" case "$architecture" in \) @@ -321,7 +325,7 @@ get_normalized_architecture_from_architecture() { return 1 ;; esac - + say_err "Architecture \`$architecture\` not supported. If you think this is a bug, please report it at https://github.com/dotnet/cli/issues" return 1 } @@ -335,7 +339,7 @@ get_normalized_architecture_from_architecture() { # version_text - stdin get_version_from_version_info() { eval $invocation - + cat | tail -n 1 | sed 's/\r$//' return 0 } @@ -344,7 +348,7 @@ get_version_from_version_info() { # version_text - stdin get_commit_hash_from_version_info() { eval $invocation - + cat | head -n 1 | sed 's/\r$//' return 0 } @@ -355,14 +359,14 @@ get_commit_hash_from_version_info() { # specific_version - $3 is_dotnet_package_installed() { eval $invocation - + local install_root="$1" local relative_path_to_package="$2" local specific_version="${3//[$'\t\r\n']}" - + local dotnet_package_path="$(combine_paths "$(combine_paths "$install_root" "$relative_path_to_package")" "$specific_version")" say_verbose "is_dotnet_package_installed: dotnet_package_path=$dotnet_package_path" - + if [ -d "$dotnet_package_path" ]; then return 0 else @@ -377,15 +381,17 @@ is_dotnet_package_installed() { # coherent - $4 get_latest_version_info() { eval $invocation - + local azure_feed="$1" local channel="$2" local normalized_architecture="$3" local coherent="$4" local version_file_url=null - if [ "$shared_runtime" = true ]; then + if [[ "$runtime" == "dotnet" ]]; then version_file_url="$uncached_feed/Runtime/$channel/latest.version" + elif [ ! -z "$runtime" ]; then + version_file_url="$uncached_feed/Runtime/$channel/latest.$runtime.version" else if [ "$coherent" = true ]; then version_file_url="$uncached_feed/Sdk/$channel/latest.coherent.version" @@ -394,7 +400,7 @@ get_latest_version_info() { fi fi say_verbose "get_latest_version_info: latest url: $version_file_url" - + download "$version_file_url" return $? } @@ -406,7 +412,7 @@ get_latest_version_info() { # version - $4 get_specific_version_from_version() { eval $invocation - + local azure_feed="$1" local channel="$2" local normalized_architecture="$3" @@ -441,22 +447,22 @@ get_specific_version_from_version() { # specific_version - $4 construct_download_link() { eval $invocation - + local azure_feed="$1" local channel="$2" local normalized_architecture="$3" local specific_version="${4//[$'\t\r\n']}" - + local osname osname="$(get_current_os_name)" || return 1 local download_link=null - if [ "$shared_runtime" = true ]; then - download_link="$azure_feed/Runtime/$specific_version/dotnet-runtime-$specific_version-$osname-$normalized_architecture.tar.gz" + if [ ! -z "$runtime" ]; then + download_link="$azure_feed/Runtime/$specific_version/$runtime-runtime-$specific_version-$osname-$normalized_architecture.tar.gz" else download_link="$azure_feed/Sdk/$specific_version/dotnet-sdk-$specific_version-$osname-$normalized_architecture.tar.gz" fi - + echo "$download_link" return 0 } @@ -468,7 +474,7 @@ construct_download_link() { # specific_version - $4 construct_legacy_download_link() { eval $invocation - + local azure_feed="$1" local channel="$2" local normalized_architecture="$3" @@ -478,10 +484,12 @@ construct_legacy_download_link() { distro_specific_osname="$(get_legacy_os_name)" || return 1 local legacy_download_link=null - if [ "$shared_runtime" = true ]; then + if [[ "$runtime" == "dotnet" ]]; then legacy_download_link="$azure_feed/Runtime/$specific_version/dotnet-$distro_specific_osname-$normalized_architecture.$specific_version.tar.gz" - else + elif [ -z "$runtime" ]; then legacy_download_link="$azure_feed/Sdk/$specific_version/dotnet-dev-$distro_specific_osname-$normalized_architecture.$specific_version.tar.gz" + else + return 1 fi echo "$legacy_download_link" @@ -490,7 +498,7 @@ construct_legacy_download_link() { get_user_install_path() { eval $invocation - + if [ ! -z "${DOTNET_INSTALL_DIR:-}" ]; then echo "$DOTNET_INSTALL_DIR" else @@ -503,7 +511,7 @@ get_user_install_path() { # install_dir - $1 resolve_installation_path() { eval $invocation - + local install_dir=$1 if [ "$install_dir" = "" ]; then local user_install_path="$(get_user_install_path)" @@ -511,7 +519,7 @@ resolve_installation_path() { echo "$user_install_path" return 0 fi - + echo "$install_dir" return 0 } @@ -520,7 +528,7 @@ resolve_installation_path() { # install_root - $1 get_installed_version_info() { eval $invocation - + local install_root="$1" local version_file="$(combine_paths "$install_root" "$local_version_file_relative_path")" say_verbose "Local version file: $version_file" @@ -529,7 +537,7 @@ get_installed_version_info() { echo "$version_info" return 0 fi - + say_verbose "Local version file not found." return 0 } @@ -538,7 +546,7 @@ get_installed_version_info() { # relative_or_absolute_path - $1 get_absolute_path() { eval $invocation - + local relative_or_absolute_path=$1 echo "$(cd "$(dirname "$1")" && pwd -P)/$(basename "$1")" return 0 @@ -556,7 +564,7 @@ copy_files_or_dirs_from_list() { local out_path="$(remove_trailing_slash "$2")" local override="$3" local override_switch=$(if [ "$override" = false ]; then printf -- "-n"; fi) - + cat | uniq | while read -r file_path; do local path="$(remove_beginning_slash "${file_path#$root_path}")" local target="$out_path/$path" @@ -572,21 +580,21 @@ copy_files_or_dirs_from_list() { # out_path - $2 extract_dotnet_package() { eval $invocation - + local zip_path="$1" local out_path="$2" - + local temp_out_path="$(mktemp -d "$temporary_file_template")" - + local failed=false tar -xzf "$zip_path" -C "$temp_out_path" > /dev/null || failed=true - + local folders_with_version_regex='^.*/[0-9]+\.[0-9]+[^/]+/' find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files" - + rm -rf "$temp_out_path" - + if [ "$failed" = true ]; then say_err "Extraction failed" return 1 @@ -665,14 +673,14 @@ calculate_vars() { normalized_architecture="$(get_normalized_architecture_from_architecture "$architecture")" say_verbose "normalized_architecture=$normalized_architecture" - + specific_version="$(get_specific_version_from_version "$azure_feed" "$channel" "$normalized_architecture" "$version")" say_verbose "specific_version=$specific_version" if [ -z "$specific_version" ]; then say_err "Could not get version information." return 1 fi - + download_link="$(construct_download_link "$azure_feed" "$channel" "$normalized_architecture" "$specific_version")" say_verbose "download_link=$download_link" @@ -691,35 +699,57 @@ calculate_vars() { install_dotnet() { eval $invocation local download_failed=false + local asset_name='' + local asset_relative_path='' - if is_dotnet_package_installed "$install_root" "sdk" "$specific_version"; then - say ".NET SDK version $specific_version is already installed." + if [[ "$runtime" == "dotnet" ]]; then + asset_relative_path="shared/Microsoft.NETCore.App" + asset_name=".NET Core Runtime" + elif [[ "$runtime" == "aspnetcore" ]]; then + asset_relative_path="shared/Microsoft.AspNetCore.All" + asset_name="ASP.NET Core Runtime" + else + asset_relative_path="sdk" + asset_name=".NET Core SDK" + fi + + if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$specific_version"; then + say "$asset_name version $specific_version is already installed." return 0 fi - + mkdir -p "$install_root" zip_path="$(mktemp "$temporary_file_template")" say_verbose "Zip path: $zip_path" say "Downloading link: $download_link" - + # Failures are normal in the non-legacy case for ultimately legacy downloads. # Do not output to stderr, since output to stderr is considered an error. download "$download_link" "$zip_path" 2>&1 || download_failed=true # if the download fails, download the legacy_download_link - if [ "$download_failed" = true ] && [ "$valid_legacy_download_link" = true ]; then + if [ "$download_failed" = true ]; then say "Cannot download: $download_link" - download_link="$legacy_download_link" - zip_path="$(mktemp "$temporary_file_template")" - say_verbose "Legacy zip path: $zip_path" - say "Downloading legacy link: $download_link" - download "$download_link" "$zip_path" + + if [ "$valid_legacy_download_link" = true ]; then + download_failed=false + download_link="$legacy_download_link" + zip_path="$(mktemp "$temporary_file_template")" + say_verbose "Legacy zip path: $zip_path" + say "Downloading legacy link: $download_link" + download "$download_link" "$zip_path" 2>&1 || download_failed=true + fi fi - + + if [ "$download_failed" = true ]; then + say_err "Could not download $asset_name version $specific_version" + return 1 + fi + say "Extracting zip from $download_link" extract_dotnet_package "$zip_path" "$install_root" - + return 0 } @@ -737,7 +767,7 @@ azure_feed="https://dotnetcli.azureedge.net/dotnet" uncached_feed="https://dotnetcli.blob.core.windows.net/dotnet" feed_credential="" verbose=false -shared_runtime=false +runtime="" runtime_id="" override_non_versioned_files=true @@ -762,7 +792,18 @@ do architecture="$1" ;; --shared-runtime|-[Ss]hared[Rr]untime) - shared_runtime=true + say_warning "The --shared-runtime flag is obsolete and may be removed in a future version of this script. The recommended usage is to specify '--runtime dotnet'." + if [ -z "$runtime" ]; then + runtime="dotnet" + fi + ;; + --runtime|-[Rr]untime) + shift + runtime="$1" + if [[ "$runtime" != "dotnet" ]] && [[ "$runtime" != "aspnetcore" ]]; then + say_err "Unsupported value for --runtime: '$1'. Valid values are 'dotnet' and 'aspnetcore'." + exit 1 + fi ;; --dry-run|-[Dd]ry[Rr]un) dry_run=true @@ -790,7 +831,6 @@ do runtime_id="$1" ;; --skip-non-versioned-files|-[Ss]kip[Nn]on[Vv]ersioned[Ff]iles) - shift override_non_versioned_files=false ;; -?|--?|-h|--help|-[Hh]elp) @@ -823,8 +863,11 @@ do echo " -InstallDir" echo " --architecture Architecture of .NET Tools. Currently only x64 is supported." echo " --arch,-Architecture,-Arch" - echo " --shared-runtime Installs just the shared runtime bits, not the entire SDK." - echo " -SharedRuntime" + echo " --runtime Installs a shared runtime only, without the SDK." + echo " -Runtime" + echo " Possible values:" + echo " - dotnet - the Microsoft.NETCore.App shared framework" + echo " - aspnetcore - the Microsoft.AspNetCore.All shared framework" echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable." echo " -SkipNonVersionedFiles" echo " --dry-run,-DryRun Do not perform installation. Display download link." @@ -837,6 +880,10 @@ do echo " -RuntimeId" echo " -?,--?,-h,--help,-Help Shows this help message" echo "" + echo "Obsolete parameters:" + echo " --shared-runtime The recommended alternative is '--runtime dotnet'." + echo " -SharedRuntime Installs just the shared runtime bits, not the entire SDK." + echo "" echo "Install Location:" echo " Location is chosen in following order:" echo " - --install-dir option"