2017-04-03 02:22:57 +00:00
#!/usr/bin/env bash
2016-04-07 17:32:52 +00:00
# Copyright (c) .NET Foundation and contributors. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
#
# Stop script on NZEC
set -e
# Stop script if unbound variable found (use ${var:-} if intentional)
set -u
# By default cmd1 | cmd2 returns exit code of cmd2 regardless of cmd1 success
# This is causing it to fail
set -o pipefail
# Use in the the functions: eval $invocation
invocation = 'say_verbose "Calling: ${yellow:-}${FUNCNAME[0]} ${green:-}$*${normal:-}"'
# standard output may be used as a return value in the functions
# we need a way to write text on the screen in the functions so that
# it won't interfere with the return value.
# Exposing stream 3 as a pipe to standard output of the script itself
exec 3>& 1
# Setup some colors to use. These need to work in fairly limited shells, like the Ubuntu Docker container where there are only 8 colors.
# See if stdout is a terminal
2018-01-02 21:04:56 +00:00
if [ -t 1 ] && command -v tput > /dev/null; then
2016-04-07 17:32:52 +00:00
# see if it supports colors
ncolors = $( tput colors)
if [ -n " $ncolors " ] && [ $ncolors -ge 8 ] ; then
2016-07-08 08:01:42 +00:00
bold = " $( tput bold || echo ) "
normal = " $( tput sgr0 || echo ) "
black = " $( tput setaf 0 || echo ) "
red = " $( tput setaf 1 || echo ) "
green = " $( tput setaf 2 || echo ) "
yellow = " $( tput setaf 3 || echo ) "
blue = " $( tput setaf 4 || echo ) "
magenta = " $( tput setaf 5 || echo ) "
cyan = " $( tput setaf 6 || echo ) "
white = " $( tput setaf 7 || echo ) "
2016-04-07 17:32:52 +00:00
fi
fi
2018-01-05 17:24:10 +00:00
say_warning( ) {
printf "%b\n" " ${ yellow :- } dotnet_install: Warning: $1 ${ normal :- } "
}
2016-04-07 17:32:52 +00:00
say_err( ) {
printf "%b\n" " ${ red :- } dotnet_install: Error: $1 ${ normal :- } " >& 2
}
say( ) {
# using stream 3 (defined in the beginning) to not interfere with stdout of functions
# which may be used as return value
printf "%b\n" " ${ cyan :- } dotnet-install: ${ normal :- } $1 " >& 3
}
say_verbose( ) {
if [ " $verbose " = true ] ; then
say " $1 "
fi
}
2017-09-22 18:25:15 +00:00
# This platform list is finite - if the SDK/Runtime has supported Linux distribution-specific assets,
# then and only then should the Linux distribution appear in this list.
# Adding a Linux distribution to this list does not imply distribution-specific support.
2017-10-13 16:43:04 +00:00
get_legacy_os_name_from_platform( ) {
2017-03-14 15:46:17 +00:00
eval $invocation
platform = " $1 "
case " $platform " in
"centos.7" )
echo "centos"
return 0
; ;
"debian.8" )
echo "debian"
return 0
; ;
"fedora.23" )
echo "fedora.23"
return 0
; ;
2018-03-26 18:28:06 +00:00
"fedora.27" )
echo "fedora.27"
return 0
; ;
2017-03-14 15:46:17 +00:00
"fedora.24" )
echo "fedora.24"
return 0
; ;
"opensuse.13.2" )
echo "opensuse.13.2"
return 0
; ;
"opensuse.42.1" )
echo "opensuse.42.1"
return 0
; ;
2018-03-26 18:28:06 +00:00
"opensuse.42.3" )
echo "opensuse.42.3"
return 0
; ;
2017-03-14 15:46:17 +00:00
"rhel.7" *)
echo "rhel"
return 0
; ;
"ubuntu.14.04" )
echo "ubuntu"
return 0
; ;
"ubuntu.16.04" )
echo "ubuntu.16.04"
return 0
; ;
"ubuntu.16.10" )
echo "ubuntu.16.10"
return 0
; ;
2018-03-26 18:28:06 +00:00
"ubuntu.18.04" )
echo "ubuntu.18.04"
return 0
; ;
2017-03-14 15:46:17 +00:00
"alpine.3.4.3" )
echo "alpine"
return 0
; ;
esac
return 1
}
2017-10-13 16:43:04 +00:00
get_linux_platform_name( ) {
eval $invocation
if [ -n " $runtime_id " ] ; then
echo " ${ runtime_id %-* } "
return 0
else
if [ -e /etc/os-release ] ; then
. /etc/os-release
2017-11-29 16:03:48 +00:00
if [ [ $ID = = "alpine" ] ] ; then
# remove the last version digit
VERSION_ID = ${ VERSION_ID %.* }
fi
2017-10-13 16:43:04 +00:00
echo " $ID . $VERSION_ID "
return 0
elif [ -e /etc/redhat-release ] ; then
local redhatRelease = $( </etc/redhat-release)
if [ [ $redhatRelease = = "CentOS release 6." * || $redhatRelease = = "Red Hat Enterprise Linux Server release 6." * ] ] ; then
echo "rhel.6"
return 0
fi
fi
fi
2018-01-05 17:24:10 +00:00
2018-03-16 23:26:56 +00:00
say_verbose " Linux specific platform name and version could not be detected: UName = $uname "
2017-10-13 16:43:04 +00:00
return 1
}
2016-04-07 17:32:52 +00:00
get_current_os_name( ) {
eval $invocation
2018-03-16 23:26:56 +00:00
linux_platform_name = "unknown"
2016-04-07 17:32:52 +00:00
2017-05-22 19:53:52 +00:00
local uname = $( uname)
if [ " $uname " = "Darwin" ] ; then
echo "osx"
return 0
2017-09-22 18:25:15 +00:00
elif [ " $uname " = "Linux" ] ; then
2017-10-13 16:43:04 +00:00
linux_platform_name = " $( get_linux_platform_name) " || { echo "linux" && return 0 ; }
2017-09-22 18:25:15 +00:00
2017-11-29 16:03:48 +00:00
if [ [ $linux_platform_name = = "rhel.6" || $linux_platform_name = = "alpine.3.6" ] ] ; then
echo $linux_platform_name
2017-09-22 18:25:15 +00:00
return 0
else
2017-05-22 21:15:43 +00:00
echo "linux"
return 0
fi
2017-05-22 19:53:52 +00:00
fi
2018-01-05 17:24:10 +00:00
2018-03-16 23:26:56 +00:00
say_err " OS name could not be detected: UName = $uname "
2017-05-22 19:53:52 +00:00
return 1
}
2017-10-13 16:43:04 +00:00
get_legacy_os_name( ) {
2017-05-22 19:53:52 +00:00
eval $invocation
2016-04-07 17:32:52 +00:00
local uname = $( uname)
2017-03-18 00:27:02 +00:00
if [ " $uname " = "Darwin" ] ; then
2016-04-07 17:32:52 +00:00
echo "osx"
return 0
2017-03-14 15:46:17 +00:00
elif [ -n " $runtime_id " ] ; then
2017-10-13 16:43:04 +00:00
echo $( get_legacy_os_name_from_platform " ${ runtime_id %-* } " || echo " ${ runtime_id %-* } " )
2017-03-14 15:46:17 +00:00
return 0
2016-04-07 17:32:52 +00:00
else
2016-09-22 21:15:03 +00:00
if [ -e /etc/os-release ] ; then
. /etc/os-release
2017-10-13 16:43:04 +00:00
os = $( get_legacy_os_name_from_platform " $ID . $VERSION_ID " || echo "" )
2017-03-14 15:46:17 +00:00
if [ -n " $os " ] ; then
echo " $os "
return 0
fi
2016-04-07 17:32:52 +00:00
fi
fi
2018-01-05 17:24:10 +00:00
2018-03-16 23:26:56 +00:00
say_verbose " Distribution specific OS name and version could not be detected: UName = $uname "
2016-04-07 17:32:52 +00:00
return 1
}
machine_has( ) {
eval $invocation
2017-02-25 23:10:10 +00:00
hash " $1 " > /dev/null 2>& 1
2016-04-07 17:32:52 +00:00
return $?
}
2017-05-22 19:53:52 +00:00
2016-04-07 17:32:52 +00:00
check_min_reqs( ) {
2017-05-22 19:53:52 +00:00
local hasMinimum = false
if machine_has "curl" ; then
2017-05-22 21:15:43 +00:00
hasMinimum = true
elif machine_has "wget" ; then
hasMinimum = true
2017-05-22 19:53:52 +00:00
fi
2017-05-22 21:15:43 +00:00
2017-05-22 19:53:52 +00:00
if [ " $hasMinimum " = "false" ] ; then
say_err "curl (recommended) or wget are required to download dotnet. Install missing prerequisite to proceed."
2016-04-07 17:32:52 +00:00
return 1
fi
return 0
}
check_pre_reqs( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
local failing = false;
if [ " ${ DOTNET_INSTALL_SKIP_PREREQS :- } " = "1" ] ; then
return 0
fi
if [ " $( uname) " = "Linux" ] ; then
2017-10-13 16:43:04 +00:00
if [ ! -x " $( command -v ldconfig) " ] ; then
2016-04-07 17:32:52 +00:00
echo "ldconfig is not in PATH, trying /sbin/ldconfig."
LDCONFIG_COMMAND = "/sbin/ldconfig"
else
LDCONFIG_COMMAND = "ldconfig"
fi
2017-09-22 18:25:15 +00:00
local librarypath = ${ LD_LIBRARY_PATH :- }
2017-09-22 21:16:08 +00:00
LDCONFIG_COMMAND = " $LDCONFIG_COMMAND -NXv ${ librarypath // : / } "
2017-09-22 18:25:15 +00:00
2017-11-28 18:47:59 +00:00
[ -z " $( $LDCONFIG_COMMAND 2>/dev/null | grep libunwind) " ] && say_err "Unable to locate libunwind. Install libunwind to continue" && failing = true
[ -z " $( $LDCONFIG_COMMAND 2>/dev/null | grep libssl) " ] && say_err "Unable to locate libssl. Install libssl to continue" && failing = true
[ -z " $( $LDCONFIG_COMMAND 2>/dev/null | grep libicu) " ] && say_err "Unable to locate libicu. Install libicu to continue" && failing = true
[ -z " $( $LDCONFIG_COMMAND 2>/dev/null | grep -F libcurl.so) " ] && say_err "Unable to locate libcurl. Install libcurl to continue" && failing = true
2016-04-07 17:32:52 +00:00
fi
if [ " $failing " = true ] ; then
return 1
fi
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
return 0
}
# args:
# input - $1
to_lowercase( ) {
#eval $invocation
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
echo " $1 " | tr '[:upper:]' '[:lower:]'
return 0
}
# args:
# input - $1
remove_trailing_slash( ) {
#eval $invocation
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local input = " ${ 1 :- } "
2016-04-07 17:32:52 +00:00
echo " ${ input %/ } "
return 0
}
# args:
# input - $1
remove_beginning_slash( ) {
#eval $invocation
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local input = " ${ 1 :- } "
2016-04-07 17:32:52 +00:00
echo " ${ input #/ } "
return 0
}
# args:
# root_path - $1
# child_path - $2 - this parameter can be empty
combine_paths( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
# 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
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local root_path = " $( remove_trailing_slash " $1 " ) "
local child_path = " $( remove_beginning_slash " ${ 2 :- } " ) "
2016-04-07 17:32:52 +00:00
say_verbose " combine_paths: root_path= $root_path "
say_verbose " combine_paths: child_path= $child_path "
echo " $root_path / $child_path "
return 0
}
get_machine_architecture( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
# Currently the only one supported
echo "x64"
return 0
}
# args:
# architecture - $1
get_normalized_architecture_from_architecture( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local architecture = " $( to_lowercase " $1 " ) "
case " $architecture " in
2016-04-07 17:32:52 +00:00
\< auto\> )
2017-10-11 17:53:53 +00:00
echo " $( get_normalized_architecture_from_architecture " $( get_machine_architecture) " ) "
2016-04-07 17:32:52 +00:00
return 0
; ;
amd64| x64)
echo "x64"
return 0
; ;
x86)
2017-05-23 17:45:15 +00:00
say_err "Architecture \`x86\` currently not supported"
2016-04-07 17:32:52 +00:00
return 1
; ;
esac
2018-01-05 17:24:10 +00:00
2017-05-23 17:45:15 +00:00
say_err " Architecture \` $architecture \` not supported. If you think this is a bug, please report it at https://github.com/dotnet/cli/issues "
2016-04-07 17:32:52 +00:00
return 1
}
# version_info is a conceptual two line string representing commit hash and 4-part version
# format:
# Line 1: # commit_hash
# Line 2: # 4-part version
# args:
# version_text - stdin
get_version_from_version_info( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2017-09-26 15:32:11 +00:00
cat | tail -n 1 | sed 's/\r$//'
2016-04-07 17:32:52 +00:00
return 0
}
# args:
# version_text - stdin
get_commit_hash_from_version_info( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2017-09-26 15:32:11 +00:00
cat | head -n 1 | sed 's/\r$//'
2016-04-07 17:32:52 +00:00
return 0
}
# args:
# install_root - $1
# relative_path_to_package - $2
# specific_version - $3
is_dotnet_package_installed( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local install_root = " $1 "
local relative_path_to_package = " $2 "
local specific_version = " ${ 3 //[ $'\t\r\n' ] } "
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local dotnet_package_path = " $( combine_paths " $( combine_paths " $install_root " " $relative_path_to_package " ) " " $specific_version " ) "
2016-04-07 17:32:52 +00:00
say_verbose " is_dotnet_package_installed: dotnet_package_path= $dotnet_package_path "
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
if [ -d " $dotnet_package_path " ] ; then
return 0
else
return 1
fi
}
# args:
# azure_feed - $1
2017-05-22 19:53:52 +00:00
# channel - $2
2016-04-07 17:32:52 +00:00
# normalized_architecture - $3
2017-09-22 18:25:15 +00:00
# coherent - $4
2016-04-07 17:32:52 +00:00
get_latest_version_info( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local azure_feed = " $1 "
local channel = " $2 "
local normalized_architecture = " $3 "
local coherent = " $4 "
2016-09-21 17:08:46 +00:00
2016-05-27 19:19:53 +00:00
local version_file_url = null
2018-01-05 17:24:10 +00:00
if [ [ " $runtime " = = "dotnet" ] ] ; then
2017-05-22 19:53:52 +00:00
version_file_url = " $uncached_feed /Runtime/ $channel /latest.version "
2018-02-14 19:50:14 +00:00
elif [ [ " $runtime " = = "aspnetcore" ] ] ; then
version_file_url = " $uncached_feed /aspnetcore/Runtime/ $channel /latest.version "
elif [ -z " $runtime " ] ; then
2017-06-13 23:45:29 +00:00
if [ " $coherent " = true ] ; then
2017-06-15 22:25:41 +00:00
version_file_url = " $uncached_feed /Sdk/ $channel /latest.coherent.version "
2017-06-13 23:45:29 +00:00
else
version_file_url = " $uncached_feed /Sdk/ $channel /latest.version "
fi
2018-02-14 19:50:14 +00:00
else
say_err "Invalid value for \$runtime"
return 1
2016-05-27 19:19:53 +00:00
fi
2016-04-07 17:32:52 +00:00
say_verbose " get_latest_version_info: latest url: $version_file_url "
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
download " $version_file_url "
2016-04-07 17:32:52 +00:00
return $?
}
# args:
# azure_feed - $1
2017-05-22 19:53:52 +00:00
# channel - $2
2016-04-07 17:32:52 +00:00
# normalized_architecture - $3
# version - $4
get_specific_version_from_version( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local azure_feed = " $1 "
local channel = " $2 "
local normalized_architecture = " $3 "
local version = " $( to_lowercase " $4 " ) "
2016-09-21 17:08:46 +00:00
2017-10-11 17:53:53 +00:00
case " $version " in
2016-04-07 17:32:52 +00:00
latest)
2016-09-21 17:08:46 +00:00
local version_info
2017-10-11 17:53:53 +00:00
version_info = " $( get_latest_version_info " $azure_feed " " $channel " " $normalized_architecture " false ) " || return 1
2017-06-13 23:45:29 +00:00
say_verbose " get_specific_version_from_version: version_info= $version_info "
echo " $version_info " | get_version_from_version_info
return 0
; ;
coherent)
local version_info
2017-10-11 17:53:53 +00:00
version_info = " $( get_latest_version_info " $azure_feed " " $channel " " $normalized_architecture " true ) " || return 1
2016-04-07 17:32:52 +00:00
say_verbose " get_specific_version_from_version: version_info= $version_info "
echo " $version_info " | get_version_from_version_info
return 0
; ;
*)
2017-10-11 17:53:53 +00:00
echo " $version "
2016-04-07 17:32:52 +00:00
return 0
; ;
esac
}
# args:
# azure_feed - $1
2017-05-22 19:53:52 +00:00
# channel - $2
2016-04-07 17:32:52 +00:00
# normalized_architecture - $3
# specific_version - $4
construct_download_link( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local azure_feed = " $1 "
local channel = " $2 "
local normalized_architecture = " $3 "
local specific_version = " ${ 4 //[ $'\t\r\n' ] } "
2018-01-05 17:24:10 +00:00
2016-09-21 17:08:46 +00:00
local osname
2017-10-11 17:53:53 +00:00
osname = " $( get_current_os_name) " || return 1
2017-05-22 19:53:52 +00:00
2016-05-27 19:19:53 +00:00
local download_link = null
2018-02-14 19:50:14 +00:00
if [ [ " $runtime " = = "dotnet" ] ] ; then
download_link = " $azure_feed /Runtime/ $specific_version /dotnet-runtime- $specific_version - $osname - $normalized_architecture .tar.gz "
elif [ [ " $runtime " = = "aspnetcore" ] ] ; then
download_link = " $azure_feed /aspnetcore/Runtime/ $specific_version /aspnetcore-runtime- $specific_version - $osname - $normalized_architecture .tar.gz "
elif [ -z " $runtime " ] ; then
2017-06-07 17:18:05 +00:00
download_link = " $azure_feed /Sdk/ $specific_version /dotnet-sdk- $specific_version - $osname - $normalized_architecture .tar.gz "
2018-02-14 19:50:14 +00:00
else
return 1
2016-05-27 19:19:53 +00:00
fi
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
echo " $download_link "
return 0
}
2017-05-22 19:53:52 +00:00
# args:
# azure_feed - $1
# channel - $2
# normalized_architecture - $3
# specific_version - $4
2017-06-09 19:00:29 +00:00
construct_legacy_download_link( ) {
2017-05-22 19:53:52 +00:00
eval $invocation
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local azure_feed = " $1 "
local channel = " $2 "
local normalized_architecture = " $3 "
local specific_version = " ${ 4 //[ $'\t\r\n' ] } "
2017-05-30 18:37:34 +00:00
2017-05-22 19:53:52 +00:00
local distro_specific_osname
2017-10-13 16:43:04 +00:00
distro_specific_osname = " $( get_legacy_os_name) " || return 1
2017-05-22 19:53:52 +00:00
2017-06-09 19:00:29 +00:00
local legacy_download_link = null
2018-01-05 17:24:10 +00:00
if [ [ " $runtime " = = "dotnet" ] ] ; then
2017-06-09 19:00:29 +00:00
legacy_download_link = " $azure_feed /Runtime/ $specific_version /dotnet- $distro_specific_osname - $normalized_architecture . $specific_version .tar.gz "
2018-01-05 17:24:10 +00:00
elif [ -z " $runtime " ] ; then
2017-06-09 19:00:29 +00:00
legacy_download_link = " $azure_feed /Sdk/ $specific_version /dotnet-dev- $distro_specific_osname - $normalized_architecture . $specific_version .tar.gz "
2018-01-05 17:24:10 +00:00
else
return 1
2017-05-22 19:53:52 +00:00
fi
2017-05-26 22:46:56 +00:00
2017-06-09 19:00:29 +00:00
echo " $legacy_download_link "
2017-05-22 19:53:52 +00:00
return 0
}
2017-03-18 02:04:24 +00:00
get_user_install_path( ) {
2016-04-07 17:32:52 +00:00
eval $invocation
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
if [ ! -z " ${ DOTNET_INSTALL_DIR :- } " ] ; then
2017-10-11 17:53:53 +00:00
echo " $DOTNET_INSTALL_DIR "
2016-04-07 17:32:52 +00:00
else
2016-05-04 18:55:06 +00:00
echo " $HOME /.dotnet "
2016-04-07 17:32:52 +00:00
fi
return 0
}
# args:
# install_dir - $1
resolve_installation_path( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
local install_dir = $1
if [ " $install_dir " = "<auto>" ] ; then
2017-10-11 17:53:53 +00:00
local user_install_path = " $( get_user_install_path) "
2017-03-18 02:04:24 +00:00
say_verbose " resolve_installation_path: user_install_path= $user_install_path "
echo " $user_install_path "
2016-04-07 17:32:52 +00:00
return 0
fi
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
echo " $install_dir "
return 0
}
# args:
# install_root - $1
get_installed_version_info( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local install_root = " $1 "
local version_file = " $( combine_paths " $install_root " " $local_version_file_relative_path " ) "
2016-04-07 17:32:52 +00:00
say_verbose " Local version file: $version_file "
if [ ! -z " $version_file " ] | [ -r " $version_file " ] ; then
2017-10-11 17:53:53 +00:00
local version_info = " $( cat " $version_file " ) "
2016-04-07 17:32:52 +00:00
echo " $version_info "
return 0
fi
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
say_verbose "Local version file not found."
return 0
}
# args:
# relative_or_absolute_path - $1
get_absolute_path( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
local relative_or_absolute_path = $1
2017-10-11 17:53:53 +00:00
echo " $( cd " $( dirname " $1 " ) " && pwd -P) / $( basename " $1 " ) "
2016-04-07 17:32:52 +00:00
return 0
}
# args:
# input_files - stdin
# root_path - $1
# out_path - $2
# override - $3
copy_files_or_dirs_from_list( ) {
eval $invocation
2017-10-11 17:53:53 +00:00
local root_path = " $( remove_trailing_slash " $1 " ) "
local out_path = " $( remove_trailing_slash " $2 " ) "
local override = " $3 "
2018-03-16 23:26:56 +00:00
local override_switch = $(
if [ " $override " = false ] ; then
if [ [ $linux_platform_name = = 'alpine' * ] ] ; then
printf -- "-u" ;
else
printf -- "-n" ;
fi
fi )
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
cat | uniq | while read -r file_path; do
2017-10-11 17:53:53 +00:00
local path = " $( remove_beginning_slash " ${ file_path # $root_path } " ) "
local target = " $out_path / $path "
2016-04-07 17:32:52 +00:00
if [ " $override " = true ] || ( ! ( [ -d " $target " ] || [ -e " $target " ] ) ) ; then
2017-10-11 17:53:53 +00:00
mkdir -p " $out_path / $( dirname " $path " ) "
cp -R $override_switch " $root_path / $path " " $target "
2016-04-07 17:32:52 +00:00
fi
done
}
# args:
# zip_path - $1
# out_path - $2
extract_dotnet_package( ) {
eval $invocation
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local zip_path = " $1 "
local out_path = " $2 "
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
local temp_out_path = " $( mktemp -d " $temporary_file_template " ) "
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
local failed = false
tar -xzf " $zip_path " -C " $temp_out_path " > /dev/null || failed = true
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
local folders_with_version_regex = '^.*/[0-9]+\.[0-9]+[^/]+/'
2017-10-11 17:53:53 +00:00
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 "
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
rm -rf " $temp_out_path "
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
if [ " $failed " = true ] ; then
say_err "Extraction failed"
return 1
fi
}
# args:
# remote_path - $1
# [out_path] - $2 - stdout if not provided
download( ) {
eval $invocation
2017-05-22 19:53:52 +00:00
2017-10-11 17:53:53 +00:00
local remote_path = " $1 "
local out_path = " ${ 2 :- } "
2016-04-07 17:32:52 +00:00
local failed = false
2017-05-22 19:53:52 +00:00
if machine_has "curl" ; then
2017-10-11 17:53:53 +00:00
downloadcurl " $remote_path " " $out_path " || failed = true
2017-05-22 19:53:52 +00:00
elif machine_has "wget" ; then
2017-10-11 17:53:53 +00:00
downloadwget " $remote_path " " $out_path " || failed = true
2017-05-23 17:45:15 +00:00
else
failed = true
2016-04-07 17:32:52 +00:00
fi
if [ " $failed " = true ] ; then
2017-05-23 17:45:15 +00:00
say_verbose " Download failed: $remote_path "
2016-04-07 17:32:52 +00:00
return 1
fi
2017-05-23 17:45:15 +00:00
return 0
2016-04-07 17:32:52 +00:00
}
2017-05-22 19:53:52 +00:00
downloadcurl( ) {
eval $invocation
2017-10-11 17:53:53 +00:00
local remote_path = " $1 "
local out_path = " ${ 2 :- } "
2017-05-22 19:53:52 +00:00
2017-11-28 18:11:22 +00:00
# Append feed_credential as late as possible before calling curl to avoid logging feed_credential
2017-11-28 22:23:30 +00:00
remote_path = " ${ remote_path } ${ feed_credential } "
2017-11-28 18:11:22 +00:00
2017-05-22 19:53:52 +00:00
local failed = false
if [ -z " $out_path " ] ; then
2017-10-11 17:53:53 +00:00
curl --retry 10 -sSL -f --create-dirs " $remote_path " || failed = true
2017-05-22 19:53:52 +00:00
else
2017-10-11 17:53:53 +00:00
curl --retry 10 -sSL -f --create-dirs -o " $out_path " " $remote_path " || failed = true
2017-05-22 19:53:52 +00:00
fi
2017-05-23 17:45:15 +00:00
if [ " $failed " = true ] ; then
say_verbose "Curl download failed"
return 1
fi
return 0
2017-05-22 19:53:52 +00:00
}
downloadwget( ) {
eval $invocation
2017-10-11 17:53:53 +00:00
local remote_path = " $1 "
local out_path = " ${ 2 :- } "
2017-05-22 19:53:52 +00:00
2017-11-28 18:11:22 +00:00
# Append feed_credential as late as possible before calling wget to avoid logging feed_credential
2017-11-28 22:23:30 +00:00
remote_path = " ${ remote_path } ${ feed_credential } "
2017-11-28 18:11:22 +00:00
2017-05-22 19:53:52 +00:00
local failed = false
if [ -z " $out_path " ] ; then
2017-10-11 17:53:53 +00:00
wget -q --tries 10 -O - " $remote_path " || failed = true
2017-05-22 19:53:52 +00:00
else
2017-11-29 16:03:48 +00:00
wget --tries 10 -O " $out_path " " $remote_path " || failed = true
2017-05-22 19:53:52 +00:00
fi
2017-05-23 17:45:15 +00:00
if [ " $failed " = true ] ; then
say_verbose "Wget download failed"
return 1
fi
return 0
2017-05-22 19:53:52 +00:00
}
2016-04-07 17:32:52 +00:00
calculate_vars( ) {
eval $invocation
2017-06-12 16:31:09 +00:00
valid_legacy_download_link = true
2017-06-09 19:00:29 +00:00
2017-10-11 17:53:53 +00:00
normalized_architecture = " $( get_normalized_architecture_from_architecture " $architecture " ) "
2016-04-07 17:32:52 +00:00
say_verbose " normalized_architecture= $normalized_architecture "
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
specific_version = " $( get_specific_version_from_version " $azure_feed " " $channel " " $normalized_architecture " " $version " ) "
2016-04-07 17:32:52 +00:00
say_verbose " specific_version= $specific_version "
if [ -z " $specific_version " ] ; then
say_err "Could not get version information."
return 1
fi
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
download_link = " $( construct_download_link " $azure_feed " " $channel " " $normalized_architecture " " $specific_version " ) "
2016-04-07 17:32:52 +00:00
say_verbose " download_link= $download_link "
2017-05-22 19:53:52 +00:00
2017-10-11 17:53:53 +00:00
legacy_download_link = " $( construct_legacy_download_link " $azure_feed " " $channel " " $normalized_architecture " " $specific_version " ) " || valid_legacy_download_link = false
2017-06-12 16:31:09 +00:00
if [ " $valid_legacy_download_link " = true ] ; then
2017-06-09 19:00:29 +00:00
say_verbose " legacy_download_link= $legacy_download_link "
else
say_verbose "Cound not construct a legacy_download_link; omitting..."
fi
2017-05-22 19:53:52 +00:00
2017-10-11 17:53:53 +00:00
install_root = " $( resolve_installation_path " $install_dir " ) "
2016-04-07 17:32:52 +00:00
say_verbose " install_root= $install_root "
}
install_dotnet( ) {
eval $invocation
2017-05-23 17:45:15 +00:00
local download_failed = false
2018-01-05 17:24:10 +00:00
local asset_name = ''
local asset_relative_path = ''
if [ [ " $runtime " = = "dotnet" ] ] ; then
asset_relative_path = "shared/Microsoft.NETCore.App"
asset_name = ".NET Core Runtime"
elif [ [ " $runtime " = = "aspnetcore" ] ] ; then
2018-02-14 19:50:14 +00:00
asset_relative_path = "shared/Microsoft.AspNetCore.App"
2018-01-05 17:24:10 +00:00
asset_name = "ASP.NET Core Runtime"
2018-02-14 19:50:14 +00:00
elif [ -z " $runtime " ] ; then
2018-01-05 17:24:10 +00:00
asset_relative_path = "sdk"
asset_name = ".NET Core SDK"
2018-02-14 19:50:14 +00:00
else
say_err "Invalid value for \$runtime"
return 1
2018-01-05 17:24:10 +00:00
fi
2017-05-23 17:45:15 +00:00
2018-01-05 17:24:10 +00:00
if is_dotnet_package_installed " $install_root " " $asset_relative_path " " $specific_version " ; then
say " $asset_name version $specific_version is already installed. "
2016-04-07 17:32:52 +00:00
return 0
fi
2018-01-05 17:24:10 +00:00
2017-10-11 17:53:53 +00:00
mkdir -p " $install_root "
zip_path = " $( mktemp " $temporary_file_template " ) "
2016-04-07 17:32:52 +00:00
say_verbose " Zip path: $zip_path "
2017-05-23 17:45:15 +00:00
2017-05-23 18:28:38 +00:00
say " Downloading link: $download_link "
2018-01-05 17:24:10 +00:00
2017-09-22 18:25:15 +00:00
# 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.
2017-10-11 17:53:53 +00:00
download " $download_link " " $zip_path " 2>& 1 || download_failed = true
2017-05-22 19:53:52 +00:00
2017-06-09 19:00:29 +00:00
# if the download fails, download the legacy_download_link
2018-01-05 17:24:10 +00:00
if [ " $download_failed " = true ] ; then
2017-05-23 18:28:38 +00:00
say " Cannot download: $download_link "
2018-01-05 17:24:10 +00:00
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
2017-05-22 19:53:52 +00:00
fi
2018-01-05 17:24:10 +00:00
2017-06-13 23:45:29 +00:00
say " Extracting zip from $download_link "
2017-10-11 17:53:53 +00:00
extract_dotnet_package " $zip_path " " $install_root "
2018-01-05 17:24:10 +00:00
2016-04-07 17:32:52 +00:00
return 0
}
local_version_file_relative_path = "/.version"
bin_folder_relative_path = ""
temporary_file_template = " ${ TMPDIR :- /tmp } /dotnet.XXXXXXXXX "
2017-06-09 19:00:29 +00:00
channel = "LTS"
2016-04-07 17:32:52 +00:00
version = "Latest"
install_dir = "<auto>"
architecture = "<auto>"
dry_run = false
no_path = false
2016-07-15 19:36:01 +00:00
azure_feed = "https://dotnetcli.azureedge.net/dotnet"
2016-08-09 09:41:12 +00:00
uncached_feed = "https://dotnetcli.blob.core.windows.net/dotnet"
2017-11-28 18:11:22 +00:00
feed_credential = ""
2016-04-07 17:32:52 +00:00
verbose = false
2018-01-05 17:24:10 +00:00
runtime = ""
2017-03-14 15:46:17 +00:00
runtime_id = ""
2017-09-22 18:25:15 +00:00
override_non_versioned_files = true
2016-04-07 17:32:52 +00:00
while [ $# -ne 0 ]
do
2017-10-11 17:53:53 +00:00
name = " $1 "
case " $name " in
2016-04-07 17:32:52 +00:00
-c| --channel| -[ Cc] hannel)
shift
2017-10-11 17:53:53 +00:00
channel = " $1 "
2016-04-07 17:32:52 +00:00
; ;
-v| --version| -[ Vv] ersion)
shift
version = " $1 "
; ;
-i| --install-dir| -[ Ii] nstall[ Dd] ir)
shift
install_dir = " $1 "
; ;
--arch| --architecture| -[ Aa] rch| -[ Aa] rchitecture)
shift
architecture = " $1 "
; ;
2016-05-27 19:19:53 +00:00
--shared-runtime| -[ Ss] hared[ Rr] untime)
2018-01-05 17:24:10 +00:00
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
2016-05-27 19:19:53 +00:00
; ;
2016-04-07 17:32:52 +00:00
--dry-run| -[ Dd] ry[ Rr] un)
dry_run = true
; ;
--no-path| -[ Nn] o[ Pp] ath)
no_path = true
; ;
--verbose| -[ Vv] erbose)
verbose = true
; ;
--azure-feed| -[ Aa] zure[ Ff] eed)
shift
azure_feed = " $1 "
; ;
2017-05-22 19:53:52 +00:00
--uncached-feed| -[ Uu] ncached[ Ff] eed)
shift
uncached_feed = " $1 "
; ;
2017-11-28 18:11:22 +00:00
--feed-credential| -[ Ff] eed[ Cc] redential)
shift
feed_credential = " $1 "
; ;
2017-03-14 15:46:17 +00:00
--runtime-id| -[ Rr] untime[ Ii] d)
shift
runtime_id = " $1 "
; ;
2017-09-22 18:25:15 +00:00
--skip-non-versioned-files| -[ Ss] kip[ Nn] on[ Vv] ersioned[ Ff] iles)
override_non_versioned_files = false
; ;
2016-04-07 17:32:52 +00:00
-?| --?| -h| --help| -[ Hh] elp)
2017-10-11 17:53:53 +00:00
script_name = " $( basename " $0 " ) "
2016-04-07 17:32:52 +00:00
echo ".NET Tools Installer"
echo " Usage: $script_name [-c|--channel <CHANNEL>] [-v|--version <VERSION>] [-p|--prefix <DESTINATION>] "
echo " $script_name -h|-?|--help "
echo ""
echo " $script_name is a simple command line interface for obtaining dotnet cli. "
echo ""
echo "Options:"
2017-06-13 23:45:29 +00:00
echo " -c,--channel <CHANNEL> Download from the CHANNEL specified, Defaults to \` $channel \`. "
2016-04-07 17:32:52 +00:00
echo " -Channel"
2017-06-13 23:45:29 +00:00
echo " Possible values:"
echo " - Current - most current release"
echo " - LTS - most current supported release"
echo " - 2-part version in a format A.B - represents a specific release"
echo " examples: 2.0; 1.0"
echo " - Branch name"
echo " examples: release/2.0.0; Master"
echo " -v,--version <VERSION> Use specific VERSION, Defaults to \` $version \`. "
2016-04-07 17:32:52 +00:00
echo " -Version"
2017-06-13 23:45:29 +00:00
echo " Possible values:"
echo " - latest - most latest build on specific channel"
echo " - coherent - most latest coherent build on specific channel"
echo " coherent applies only to SDK downloads"
echo " - 3-part version in a format A.B.C - represents specific version of build"
echo " examples: 2.0.0-preview2-006120; 1.1.0"
2017-11-28 18:11:22 +00:00
echo " -i,--install-dir <DIR> Install under specified location (see Install Location below)"
2016-04-07 17:32:52 +00:00
echo " -InstallDir"
2017-11-28 18:11:22 +00:00
echo " --architecture <ARCHITECTURE> Architecture of .NET Tools. Currently only x64 is supported."
2016-04-07 17:32:52 +00:00
echo " --arch,-Architecture,-Arch"
2018-01-05 17:24:10 +00:00
echo " --runtime <RUNTIME> Installs a shared runtime only, without the SDK."
echo " -Runtime"
echo " Possible values:"
2018-02-14 19:50:14 +00:00
echo " - dotnet - the Microsoft.NETCore.App shared runtime"
echo " - aspnetcore - the Microsoft.AspNetCore.App shared runtime"
2017-11-28 18:11:22 +00:00
echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable."
2017-09-22 18:25:15 +00:00
echo " -SkipNonVersionedFiles"
2017-11-28 18:11:22 +00:00
echo " --dry-run,-DryRun Do not perform installation. Display download link."
echo " --no-path, -NoPath Do not set PATH for the current process."
echo " --verbose,-Verbose Display diagnostics information."
echo " --azure-feed,-AzureFeed Azure feed location. Defaults to $azure_feed , This parameter typically is not changed by the user. "
echo " --uncached-feed,-UncachedFeed Uncached feed location. This parameter typically is not changed by the user."
echo " --feed-credential,-FeedCredential Azure feed shared access token. This parameter typically is not specified."
echo " --runtime-id Installs the .NET Tools for the given platform (use linux-x64 for portable linux)."
2017-03-14 15:46:17 +00:00
echo " -RuntimeId"
2017-11-28 18:11:22 +00:00
echo " -?,--?,-h,--help,-Help Shows this help message"
2016-04-07 17:32:52 +00:00
echo ""
2018-01-05 17:24:10 +00:00
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 ""
2016-04-07 17:32:52 +00:00
echo "Install Location:"
echo " Location is chosen in following order:"
echo " - --install-dir option"
echo " - Environmental variable DOTNET_INSTALL_DIR"
2017-03-18 02:04:24 +00:00
echo " - $HOME /.dotnet "
2016-04-07 17:32:52 +00:00
exit 0
; ;
*)
say_err " Unknown argument \` $name \` "
exit 1
; ;
esac
shift
done
check_min_reqs
calculate_vars
2017-06-09 19:00:29 +00:00
2016-04-07 17:32:52 +00:00
if [ " $dry_run " = true ] ; then
say " Payload URL: $download_link "
2017-06-09 19:00:29 +00:00
if [ " $valid_legacy_download_link " = true ] ; then
say " Legacy payload URL: $legacy_download_link "
fi
2017-10-11 17:53:53 +00:00
say " Repeatable invocation: ./ $( basename " $0 " ) --version $specific_version --channel $channel --install-dir $install_dir "
2016-05-04 18:55:06 +00:00
exit 0
2016-04-07 17:32:52 +00:00
fi
check_pre_reqs
install_dotnet
2017-10-11 17:53:53 +00:00
bin_path = " $( get_absolute_path " $( combine_paths " $install_root " " $bin_folder_relative_path " ) " ) "
2016-04-07 17:32:52 +00:00
if [ " $no_path " = false ] ; then
2017-05-23 17:45:15 +00:00
say " Adding to current process PATH: \` $bin_path \`. Note: This change will be visible only when sourcing script. "
2017-10-11 17:53:53 +00:00
export PATH = " $bin_path " :" $PATH "
2016-04-07 17:32:52 +00:00
else
say " Binaries of dotnet can be found in $bin_path "
fi
2016-06-22 22:17:54 +00:00
say "Installation finished successfully."