Advertisement
S0kay3bota

bin bash

Jan 16th, 2024 (edited)
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 30.98 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. # We don't need return codes for "$(command)", only stdout is needed.
  4. # Allow `[[ -n "$(command)" ]]`, `func "$(command)"`, pipes, etc.
  5. # shellcheck disable=SC2312
  6.  
  7. set -u
  8.  
  9. abort() {
  10.   printf "%s\n" "$@" >&2
  11.   exit 1
  12. }
  13.  
  14. # Fail fast with a concise message when not using bash
  15. # Single brackets are needed here for POSIX compatibility
  16. # shellcheck disable=SC2292
  17. if [ -z "${BASH_VERSION:-}" ]
  18. then
  19.   abort "Bash is required to interpret this script."
  20. fi
  21.  
  22. # Check if script is run with force-interactive mode in CI
  23. if [[ -n "${CI-}" && -n "${INTERACTIVE-}" ]]
  24. then
  25.   abort "Cannot run force-interactive mode in CI."
  26. fi
  27.  
  28. # Check if both `INTERACTIVE` and `NONINTERACTIVE` are set
  29. # Always use single-quoted strings with `exp` expressions
  30. # shellcheck disable=SC2016
  31. if [[ -n "${INTERACTIVE-}" && -n "${NONINTERACTIVE-}" ]]
  32. then
  33.   abort 'Both `$INTERACTIVE` and `$NONINTERACTIVE` are set. Please unset at least one variable and try again.'
  34. fi
  35.  
  36. # Check if script is run in POSIX mode
  37. if [[ -n "${POSIXLY_CORRECT+1}" ]]
  38. then
  39.   abort 'Bash must not run in POSIX mode. Please unset POSIXLY_CORRECT and try again.'
  40. fi
  41.  
  42. usage() {
  43.   cat <<EOS
  44. Homebrew Installer
  45. Usage: [NONINTERACTIVE=1] [CI=1] install.sh [options]
  46.     -h, --help       Display this message.
  47.     NONINTERACTIVE   Install without prompting for user input
  48.     CI               Install in CI mode (e.g. do not prompt for user input)
  49. EOS
  50.   exit "${1:-0}"
  51. }
  52.  
  53. while [[ $# -gt 0 ]]
  54. do
  55.   case "$1" in
  56.     -h | --help) usage ;;
  57.     *)
  58.       warn "Unrecognized option: '$1'"
  59.       usage 1
  60.       ;;
  61.   esac
  62. done
  63.  
  64. # string formatters
  65. if [[ -t 1 ]]
  66. then
  67.   tty_escape() { printf "\033[%sm" "$1"; }
  68. else
  69.   tty_escape() { :; }
  70. fi
  71. tty_mkbold() { tty_escape "1;$1"; }
  72. tty_underline="$(tty_escape "4;39")"
  73. tty_blue="$(tty_mkbold 34)"
  74. tty_red="$(tty_mkbold 31)"
  75. tty_bold="$(tty_mkbold 39)"
  76. tty_reset="$(tty_escape 0)"
  77.  
  78. shell_join() {
  79.   local arg
  80.   printf "%s" "$1"
  81.   shift
  82.   for arg in "$@"
  83.   do
  84.     printf " "
  85.     printf "%s" "${arg// /\ }"
  86.   done
  87. }
  88.  
  89. chomp() {
  90.   printf "%s" "${1/"$'\n'"/}"
  91. }
  92.  
  93. ohai() {
  94.   printf "${tty_blue}==>${tty_bold} %s${tty_reset}\n" "$(shell_join "$@")"
  95. }
  96.  
  97. warn() {
  98.   printf "${tty_red}Warning${tty_reset}: %s\n" "$(chomp "$1")" >&2
  99. }
  100.  
  101. # Check if script is run non-interactively (e.g. CI)
  102. # If it is run non-interactively we should not prompt for passwords.
  103. # Always use single-quoted strings with `exp` expressions
  104. # shellcheck disable=SC2016
  105. if [[ -z "${NONINTERACTIVE-}" ]]
  106. then
  107.   if [[ -n "${CI-}" ]]
  108.   then
  109.     warn 'Running in non-interactive mode because `$CI` is set.'
  110.     NONINTERACTIVE=1
  111.   elif [[ ! -t 0 ]]
  112.   then
  113.     if [[ -z "${INTERACTIVE-}" ]]
  114.     then
  115.       warn 'Running in non-interactive mode because `stdin` is not a TTY.'
  116.       NONINTERACTIVE=1
  117.     else
  118.       warn 'Running in interactive mode despite `stdin` not being a TTY because `$INTERACTIVE` is set.'
  119.     fi
  120.   fi
  121. else
  122.   ohai 'Running in non-interactive mode because `$NONINTERACTIVE` is set.'
  123. fi
  124.  
  125. # USER isn't always set so provide a fall back for the installer and subprocesses.
  126. if [[ -z "${USER-}" ]]
  127. then
  128.   USER="$(chomp "$(id -un)")"
  129.  export USER
  130. fi
  131.  
  132. # First check OS.
  133. OS="$(uname)"
  134. if [[ "${OS}" == "Linux" ]]
  135. then
  136.  HOMEBREW_ON_LINUX=1
  137. elif [[ "${OS}" == "Darwin" ]]
  138. then
  139.  HOMEBREW_ON_MACOS=1
  140. else
  141.  abort "Homebrew is only supported on macOS and Linux."
  142. fi
  143.  
  144. # Required installation paths. To install elsewhere (which is unsupported)
  145. # you can untar https://github.com/Homebrew/brew/tarball/master
  146. # anywhere you like.
  147. if [[ -n "${HOMEBREW_ON_MACOS-}" ]]
  148. then
  149.  UNAME_MACHINE="$(/usr/bin/uname -m)"
  150.  
  151.  if [[ "${UNAME_MACHINE}" == "arm64" ]]
  152.  then
  153.    # On ARM macOS, this script installs to /opt/homebrew only
  154.    HOMEBREW_PREFIX="/opt/homebrew"
  155.    HOMEBREW_REPOSITORY="${HOMEBREW_PREFIX}"
  156.  else
  157.    # On Intel macOS, this script installs to /usr/local only
  158.    HOMEBREW_PREFIX="/usr/local"
  159.    HOMEBREW_REPOSITORY="${HOMEBREW_PREFIX}/Homebrew"
  160.  fi
  161.  HOMEBREW_CACHE="${HOME}/Library/Caches/Homebrew"
  162.  
  163.  STAT_PRINTF=("stat" "-f")
  164.  PERMISSION_FORMAT="%A"
  165.  CHOWN=("/usr/sbin/chown")
  166.  CHGRP=("/usr/bin/chgrp")
  167.  GROUP="admin"
  168.  TOUCH=("/usr/bin/touch")
  169.  INSTALL=("/usr/bin/install" -d -o "root" -g "wheel" -m "0755")
  170. else
  171.  UNAME_MACHINE="$(uname -m)"
  172.  
  173.  # On Linux, this script installs to /home/linuxbrew/.linuxbrew only
  174.  HOMEBREW_PREFIX="/home/linuxbrew/.linuxbrew"
  175.  HOMEBREW_REPOSITORY="${HOMEBREW_PREFIX}/Homebrew"
  176.  HOMEBREW_CACHE="${HOME}/.cache/Homebrew"
  177.  
  178.  STAT_PRINTF=("stat" "--printf")
  179.  PERMISSION_FORMAT="%a"
  180.  CHOWN=("/bin/chown")
  181.  CHGRP=("/bin/chgrp")
  182.  GROUP="$(id -gn)"
  183.  TOUCH=("/bin/touch")
  184.  INSTALL=("/usr/bin/install" -d -o "${USER}" -g "${GROUP}" -m "0755")
  185. fi
  186. CHMOD=("/bin/chmod")
  187. MKDIR=("/bin/mkdir" "-p")
  188. HOMEBREW_BREW_DEFAULT_GIT_REMOTE="https://github.com/Homebrew/brew"
  189. HOMEBREW_CORE_DEFAULT_GIT_REMOTE="https://github.com/Homebrew/homebrew-core"
  190.  
  191. # Use remote URLs of Homebrew repositories from environment if set.
  192. HOMEBREW_BREW_GIT_REMOTE="${HOMEBREW_BREW_GIT_REMOTE:-"${HOMEBREW_BREW_DEFAULT_GIT_REMOTE}"}"
  193. HOMEBREW_CORE_GIT_REMOTE="${HOMEBREW_CORE_GIT_REMOTE:-"${HOMEBREW_CORE_DEFAULT_GIT_REMOTE}"}"
  194. # The URLs with and without the '.git' suffix are the same Git remote. Do not prompt.
  195. if [[ "${HOMEBREW_BREW_GIT_REMOTE}" == "${HOMEBREW_BREW_DEFAULT_GIT_REMOTE}.git" ]]
  196. then
  197.  HOMEBREW_BREW_GIT_REMOTE="${HOMEBREW_BREW_DEFAULT_GIT_REMOTE}"
  198. fi
  199. if [[ "${HOMEBREW_CORE_GIT_REMOTE}" == "${HOMEBREW_CORE_DEFAULT_GIT_REMOTE}.git" ]]
  200. then
  201.  HOMEBREW_CORE_GIT_REMOTE="${HOMEBREW_CORE_DEFAULT_GIT_REMOTE}"
  202. fi
  203. export HOMEBREW_{BREW,CORE}_GIT_REMOTE
  204.  
  205. # TODO: bump version when new macOS is released or announced
  206. MACOS_NEWEST_UNSUPPORTED="15.0"
  207. # TODO: bump version when new macOS is released
  208. MACOS_OLDEST_SUPPORTED="12.0"
  209.  
  210. # For Homebrew on Linux
  211. REQUIRED_RUBY_VERSION=2.6    # https://github.com/Homebrew/brew/pull/6556
  212. REQUIRED_GLIBC_VERSION=2.13  # https://docs.brew.sh/Homebrew-on-Linux#requirements
  213. REQUIRED_CURL_VERSION=7.41.0 # HOMEBREW_MINIMUM_CURL_VERSION in brew.sh in Homebrew/brew
  214. REQUIRED_GIT_VERSION=2.7.0   # HOMEBREW_MINIMUM_GIT_VERSION in brew.sh in Homebrew/brew
  215.  
  216. # no analytics during installation
  217. export HOMEBREW_NO_ANALYTICS_THIS_RUN=1
  218. export HOMEBREW_NO_ANALYTICS_MESSAGE_OUTPUT=1
  219.  
  220. unset HAVE_SUDO_ACCESS # unset this from the environment
  221.  
  222. have_sudo_access() {
  223.  if [[ ! -x "/usr/bin/sudo" ]]
  224.  then
  225.    return 1
  226.  fi
  227.  
  228.  local -a SUDO=("/usr/bin/sudo")
  229.  if [[ -n "${SUDO_ASKPASS-}" ]]
  230.  then
  231.    SUDO+=("-A")
  232.  elif [[ -n "${NONINTERACTIVE-}" ]]
  233.  then
  234.    SUDO+=("-n")
  235.  fi
  236.  
  237.  if [[ -z "${HAVE_SUDO_ACCESS-}" ]]
  238.  then
  239.    if [[ -n "${NONINTERACTIVE-}" ]]
  240.    then
  241.      "${SUDO[@]}" -l mkdir &>/dev/null
  242.    else
  243.      "${SUDO[@]}" -v && "${SUDO[@]}" -l mkdir &>/dev/null
  244.    fi
  245.    HAVE_SUDO_ACCESS="$?"
  246.  fi
  247.  
  248.  if [[ -n "${HOMEBREW_ON_MACOS-}" ]] && [[ "${HAVE_SUDO_ACCESS}" -ne 0 ]]
  249.  then
  250.    abort "Need sudo access on macOS (e.g. the user ${USER} needs to be an Administrator)!"
  251.  fi
  252.  
  253.  return "${HAVE_SUDO_ACCESS}"
  254. }
  255.  
  256. execute() {
  257.  if ! "$@"
  258.  then
  259.    abort "$(printf "Failed during: %s" "$(shell_join "$@")")"
  260.  fi
  261. }
  262.  
  263. execute_sudo() {
  264.  local -a args=("$@")
  265.  if [[ "${EUID:-${UID}}" != "0" ]] && have_sudo_access
  266.  then
  267.    if [[ -n "${SUDO_ASKPASS-}" ]]
  268.    then
  269.      args=("-A" "${args[@]}")
  270.    fi
  271.    ohai "/usr/bin/sudo" "${args[@]}"
  272.    execute "/usr/bin/sudo" "${args[@]}"
  273.  else
  274.    ohai "${args[@]}"
  275.    execute "${args[@]}"
  276.  fi
  277. }
  278.  
  279. getc() {
  280.  local save_state
  281.  save_state="$(/bin/stty -g)"
  282.  /bin/stty raw -echo
  283.  IFS='' read -r -n 1 -d '' "$@"
  284.  /bin/stty "${save_state}"
  285. }
  286.  
  287. ring_bell() {
  288.  # Use the shell's audible bell.
  289.  if [[ -t 1 ]]
  290.  then
  291.    printf "\a"
  292.  fi
  293. }
  294.  
  295. wait_for_user() {
  296.  local c
  297.  echo
  298.  echo "Press ${tty_bold}RETURN${tty_reset}/${tty_bold}ENTER${tty_reset} to continue or any other key to abort:"
  299.  getc c
  300.  # we test for \r and \n because some stuff does \r instead
  301.  if ! [[ "${c}" == $'\r' || "${c}" == $'\n' ]]
  302.  then
  303.    exit 1
  304.  fi
  305. }
  306.  
  307. major_minor() {
  308.  echo "${1%%.*}.$(
  309.     x="${1#*.}"
  310.     echo "${x%%.*}"
  311.   )"
  312. }
  313.  
  314. version_gt() {
  315.  [[ "${1%.*}" -gt "${2%.*}" ]] || [[ "${1%.*}" -eq "${2%.*}" && "${1#*.}" -gt "${2#*.}" ]]
  316. }
  317. version_ge() {
  318.  [[ "${1%.*}" -gt "${2%.*}" ]] || [[ "${1%.*}" -eq "${2%.*}" && "${1#*.}" -ge "${2#*.}" ]]
  319. }
  320. version_lt() {
  321.  [[ "${1%.*}" -lt "${2%.*}" ]] || [[ "${1%.*}" -eq "${2%.*}" && "${1#*.}" -lt "${2#*.}" ]]
  322. }
  323.  
  324. check_run_command_as_root() {
  325.  [[ "${EUID:-${UID}}" == "0" ]] || return
  326.  
  327.  # Allow Azure Pipelines/GitHub Actions/Docker/Concourse/Kubernetes to do everything as root (as it's normal there)
  328.  [[ -f /.dockerenv ]] && return
  329.  [[ -f /run/.containerenv ]] && return
  330.  [[ -f /proc/1/cgroup ]] && grep -E "azpl_job|actions_job|docker|garden|kubepods" -q /proc/1/cgroup && return
  331.  
  332.  abort "Don't run this as root!"
  333. }
  334.  
  335. should_install_command_line_tools() {
  336.  if [[ -n "${HOMEBREW_ON_LINUX-}" ]]
  337.  then
  338.    return 1
  339.  fi
  340.  
  341.  if version_gt "${macos_version}" "10.13"
  342.  then
  343.    ! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]]
  344.  else
  345.    ! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]] ||
  346.      ! [[ -e "/usr/include/iconv.h" ]]
  347.  fi
  348. }
  349.  
  350. get_permission() {
  351.  "${STAT_PRINTF[@]}" "${PERMISSION_FORMAT}" "$1"
  352. }
  353.  
  354. user_only_chmod() {
  355.  [[ -d "$1" ]] && [[ "$(get_permission "$1")" != 75[0145] ]]
  356. }
  357.  
  358. exists_but_not_writable() {
  359.  [[ -e "$1" ]] && ! [[ -r "$1" && -w "$1" && -x "$1" ]]
  360. }
  361.  
  362. get_owner() {
  363.  "${STAT_PRINTF[@]}" "%u" "$1"
  364. }
  365.  
  366. file_not_owned() {
  367.  [[ "$(get_owner "$1")" != "$(id -u)" ]]
  368. }
  369.  
  370. get_group() {
  371.  "${STAT_PRINTF[@]}" "%g" "$1"
  372. }
  373.  
  374. file_not_grpowned() {
  375.  [[ " $(id -G "${USER}") " != *" $(get_group "$1") "* ]]
  376. }
  377.  
  378. # Please sync with 'test_ruby()' in 'Library/Homebrew/utils/ruby.sh' from the Homebrew/brew repository.
  379. test_ruby() {
  380.  if [[ ! -x "$1" ]]
  381.  then
  382.    return 1
  383.  fi
  384.  
  385.  "$1" --enable-frozen-string-literal --disable=gems,did_you_mean,rubyopt -rrubygems -e \
  386.    "abort if Gem::Version.new(RUBY_VERSION.to_s.dup).to_s.split('.').first(2) != \
  387.              Gem::Version.new('${REQUIRED_RUBY_VERSION}').to_s.split('.').first(2)" 2>/dev/null
  388. }
  389.  
  390. test_curl() {
  391.  if [[ ! -x "$1" ]]
  392.  then
  393.    return 1
  394.  fi
  395.  
  396.  local curl_version_output curl_name_and_version
  397.  curl_version_output="$("$1" --version 2>/dev/null)"
  398.  curl_name_and_version="${curl_version_output%% (*}"
  399.  version_ge "$(major_minor "${curl_name_and_version##* }")" "$(major_minor "${REQUIRED_CURL_VERSION}")"
  400. }
  401.  
  402. test_git() {
  403.  if [[ ! -x "$1" ]]
  404.  then
  405.    return 1
  406.  fi
  407.  
  408.  local git_version_output
  409.  git_version_output="$("$1" --version 2>/dev/null)"
  410.  if [[ "${git_version_output}" =~ "git version "([^ ]*).* ]]
  411.  then
  412.    version_ge "$(major_minor "${BASH_REMATCH[1]}")" "$(major_minor "${REQUIRED_GIT_VERSION}")"
  413.  else
  414.    abort "Unexpected Git version: '${git_version_output}'!"
  415.  fi
  416. }
  417.  
  418. # Search for the given executable in PATH (avoids a dependency on the `which` command)
  419. which() {
  420.  # Alias to Bash built-in command `type -P`
  421.  type -P "$@"
  422. }
  423.  
  424. # Search PATH for the specified program that satisfies Homebrew requirements
  425. # function which is set above
  426. # shellcheck disable=SC2230
  427. find_tool() {
  428.  if [[ $# -ne 1 ]]
  429.  then
  430.    return 1
  431.  fi
  432.  
  433.  local executable
  434.  while read -r executable
  435.  do
  436.    if [[ "${executable}" != /* ]]
  437.    then
  438.      warn "Ignoring ${executable} (relative paths don't work)"
  439.    elif "test_$1" "${executable}"
  440.    then
  441.      echo "${executable}"
  442.      break
  443.    fi
  444.  done < <(which -a "$1")
  445. }
  446.  
  447. no_usable_ruby() {
  448.  [[ -z "$(find_tool ruby)" ]]
  449. }
  450.  
  451. outdated_glibc() {
  452.  local glibc_version
  453.  glibc_version="$(ldd --version | head -n1 | grep -o '[0-9.]*$' | grep -o '^[0-9]\+\.[0-9]\+')"
  454.  version_lt "${glibc_version}" "${REQUIRED_GLIBC_VERSION}"
  455. }
  456.  
  457. if [[ -n "${HOMEBREW_ON_LINUX-}" ]] && no_usable_ruby && outdated_glibc
  458. then
  459.  abort "$(
  460.     cat <<EOABORT
  461. Homebrew requires Ruby ${REQUIRED_RUBY_VERSION} which was not found on your system.
  462. Homebrew portable Ruby requires Glibc version ${REQUIRED_GLIBC_VERSION} or newer,
  463. and your Glibc version is too old. See:
  464.   ${tty_underline}https://docs.brew.sh/Homebrew-on-Linux#requirements${tty_reset}
  465. Please install Ruby ${REQUIRED_RUBY_VERSION} and add its location to your PATH.
  466. EOABORT
  467.   )"
  468. fi
  469.  
  470. # Invalidate sudo timestamp before exiting (if it wasn't active before).
  471. if [[ -x /usr/bin/sudo ]] && ! /usr/bin/sudo -n -v 2>/dev/null
  472. then
  473.  trap '/usr/bin/sudo -k' EXIT
  474. fi
  475.  
  476. # Things can fail later if `pwd` doesn't exist.
  477. # Also sudo prints a warning message for no good reason
  478. cd "/usr" || exit 1
  479.  
  480. ####################################################################### script
  481.  
  482. # shellcheck disable=SC2016
  483. ohai 'Checking for `sudo` access (which may request your password)...'
  484.  
  485. if [[ -n "${HOMEBREW_ON_MACOS-}" ]]
  486. then
  487.  [[ "${EUID:-${UID}}" == "0" ]] || have_sudo_access
  488. elif ! [[ -w "${HOMEBREW_PREFIX}" ]] &&
  489.     ! [[ -w "/home/linuxbrew" ]] &&
  490.     ! [[ -w "/home" ]] &&
  491.     ! have_sudo_access
  492. then
  493.  abort "$(
  494.     cat <<EOABORT
  495. Insufficient permissions to install Homebrew to \"${HOMEBREW_PREFIX}\" (the default prefix).
  496.  
  497. Alternative (unsupported) installation methods are available at:
  498. https://docs.brew.sh/Installation#alternative-installs
  499.  
  500. Please note this will require most formula to build from source, a buggy, slow and energy-inefficient experience.
  501. We will close any issues without response for these unsupported configurations.
  502. EOABORT
  503.   )"
  504. fi
  505. HOMEBREW_CORE="${HOMEBREW_REPOSITORY}/Library/Taps/homebrew/homebrew-core"
  506.  
  507. check_run_command_as_root
  508.  
  509. if [[ -d "${HOMEBREW_PREFIX}" && ! -x "${HOMEBREW_PREFIX}" ]]
  510. then
  511.  abort "$(
  512.     cat <<EOABORT
  513. The Homebrew prefix ${tty_underline}${HOMEBREW_PREFIX}${tty_reset} exists but is not searchable.
  514. If this is not intentional, please restore the default permissions and
  515. try running the installer again:
  516.     sudo chmod 775 ${HOMEBREW_PREFIX}
  517. EOABORT
  518.   )"
  519. fi
  520.  
  521. if [[ -n "${HOMEBREW_ON_MACOS-}" ]]
  522. then
  523.  # On macOS, support 64-bit Intel and ARM
  524.  if [[ "${UNAME_MACHINE}" != "arm64" ]] && [[ "${UNAME_MACHINE}" != "x86_64" ]]
  525.  then
  526.    abort "Homebrew is only supported on Intel and ARM processors!"
  527.  fi
  528. else
  529.  # On Linux, support only 64-bit Intel
  530.  if [[ "${UNAME_MACHINE}" == "aarch64" ]]
  531.  then
  532.    abort "$(
  533.       cat <<EOABORT
  534. Homebrew on Linux is not supported on ARM processors.
  535.   ${tty_underline}https://docs.brew.sh/Homebrew-on-Linux#arm-unsupported${tty_reset}
  536. EOABORT
  537.     )"
  538.  elif [[ "${UNAME_MACHINE}" != "x86_64" ]]
  539.  then
  540.    abort "Homebrew on Linux is only supported on Intel processors!"
  541.  fi
  542. fi
  543.  
  544. if [[ -n "${HOMEBREW_ON_MACOS-}" ]]
  545. then
  546.  macos_version="$(major_minor "$(/usr/bin/sw_vers -productVersion)")"
  547.  if version_lt "${macos_version}" "10.7"
  548.  then
  549.    abort "$(
  550.       cat <<EOABORT
  551. Your Mac OS X version is too old. See:
  552.   ${tty_underline}https://github.com/mistydemeo/tigerbrew${tty_reset}
  553. EOABORT
  554.     )"
  555.  elif version_lt "${macos_version}" "10.11"
  556.  then
  557.    abort "Your OS X version is too old."
  558.  elif version_ge "${macos_version}" "${MACOS_NEWEST_UNSUPPORTED}" ||
  559.       version_lt "${macos_version}" "${MACOS_OLDEST_SUPPORTED}"
  560.  then
  561.    who="We"
  562.    what=""
  563.    if version_ge "${macos_version}" "${MACOS_NEWEST_UNSUPPORTED}"
  564.    then
  565.      what="pre-release version"
  566.    else
  567.      who+=" (and Apple)"
  568.      what="old version"
  569.    fi
  570.    ohai "You are using macOS ${macos_version}."
  571.    ohai "${who} do not provide support for this ${what}."
  572.  
  573.    echo "$(
  574.       cat <<EOS
  575. This installation may not succeed.
  576. After installation, you will encounter build failures with some formulae.
  577. Please create pull requests instead of asking for help on Homebrew\'s GitHub,
  578. Twitter or any other official channels. You are responsible for resolving any
  579. issues you experience while you are running this ${what}.
  580. EOS
  581.     )
  582. " | tr -d "\\"
  583.   fi
  584. fi
  585.  
  586. ohai "This script will install:"
  587. echo "${HOMEBREW_PREFIX}/bin/brew"
  588. echo "${HOMEBREW_PREFIX}/share/doc/homebrew"
  589. echo "${HOMEBREW_PREFIX}/share/man/man1/brew.1"
  590. echo "${HOMEBREW_PREFIX}/share/zsh/site-functions/_brew"
  591. echo "${HOMEBREW_PREFIX}/etc/bash_completion.d/brew"
  592. echo "${HOMEBREW_REPOSITORY}"
  593.  
  594. # Keep relatively in sync with
  595. # https://github.com/Homebrew/brew/blob/master/Library/Homebrew/keg.rb
  596. directories=(
  597.   bin etc include lib sbin share opt var
  598.   Frameworks
  599.   etc/bash_completion.d lib/pkgconfig
  600.   share/aclocal share/doc share/info share/locale share/man
  601.   share/man/man1 share/man/man2 share/man/man3 share/man/man4
  602.   share/man/man5 share/man/man6 share/man/man7 share/man/man8
  603.   var/log var/homebrew var/homebrew/linked
  604.   bin/brew
  605. )
  606. group_chmods=()
  607. for dir in "${directories[@]}"
  608. do
  609.   if exists_but_not_writable "${HOMEBREW_PREFIX}/${dir}"
  610.   then
  611.     group_chmods+=("${HOMEBREW_PREFIX}/${dir}")
  612.   fi
  613. done
  614.  
  615. # zsh refuses to read from these directories if group writable
  616. directories=(share/zsh share/zsh/site-functions)
  617. zsh_dirs=()
  618. for dir in "${directories[@]}"
  619. do
  620.   zsh_dirs+=("${HOMEBREW_PREFIX}/${dir}")
  621. done
  622.  
  623. directories=(
  624.   bin etc include lib sbin share var opt
  625.   share/zsh share/zsh/site-functions
  626.   var/homebrew var/homebrew/linked
  627.   Cellar Caskroom Frameworks
  628. )
  629. mkdirs=()
  630. for dir in "${directories[@]}"
  631. do
  632.   if ! [[ -d "${HOMEBREW_PREFIX}/${dir}" ]]
  633.   then
  634.     mkdirs+=("${HOMEBREW_PREFIX}/${dir}")
  635.   fi
  636. done
  637.  
  638. user_chmods=()
  639. mkdirs_user_only=()
  640. if [[ "${#zsh_dirs[@]}" -gt 0 ]]
  641. then
  642.   for dir in "${zsh_dirs[@]}"
  643.   do
  644.     if [[ ! -d "${dir}" ]]
  645.     then
  646.       mkdirs_user_only+=("${dir}")
  647.     elif user_only_chmod "${dir}"
  648.     then
  649.       user_chmods+=("${dir}")
  650.     fi
  651.   done
  652. fi
  653.  
  654. chmods=()
  655. if [[ "${#group_chmods[@]}" -gt 0 ]]
  656. then
  657.   chmods+=("${group_chmods[@]}")
  658. fi
  659. if [[ "${#user_chmods[@]}" -gt 0 ]]
  660. then
  661.   chmods+=("${user_chmods[@]}")
  662. fi
  663.  
  664. chowns=()
  665. chgrps=()
  666. if [[ "${#chmods[@]}" -gt 0 ]]
  667. then
  668.   for dir in "${chmods[@]}"
  669.   do
  670.     if file_not_owned "${dir}"
  671.     then
  672.       chowns+=("${dir}")
  673.     fi
  674.     if file_not_grpowned "${dir}"
  675.     then
  676.       chgrps+=("${dir}")
  677.     fi
  678.   done
  679. fi
  680.  
  681. if [[ "${#group_chmods[@]}" -gt 0 ]]
  682. then
  683.   ohai "The following existing directories will be made group writable:"
  684.   printf "%s\n" "${group_chmods[@]}"
  685. fi
  686. if [[ "${#user_chmods[@]}" -gt 0 ]]
  687. then
  688.   ohai "The following existing directories will be made writable by user only:"
  689.   printf "%s\n" "${user_chmods[@]}"
  690. fi
  691. if [[ "${#chowns[@]}" -gt 0 ]]
  692. then
  693.   ohai "The following existing directories will have their owner set to ${tty_underline}${USER}${tty_reset}:"
  694.   printf "%s\n" "${chowns[@]}"
  695. fi
  696. if [[ "${#chgrps[@]}" -gt 0 ]]
  697. then
  698.   ohai "The following existing directories will have their group set to ${tty_underline}${GROUP}${tty_reset}:"
  699.   printf "%s\n" "${chgrps[@]}"
  700. fi
  701. if [[ "${#mkdirs[@]}" -gt 0 ]]
  702. then
  703.   ohai "The following new directories will be created:"
  704.   printf "%s\n" "${mkdirs[@]}"
  705. fi
  706.  
  707. if should_install_command_line_tools
  708. then
  709.   ohai "The Xcode Command Line Tools will be installed."
  710. fi
  711.  
  712. non_default_repos=""
  713. additional_shellenv_commands=()
  714. if [[ "${HOMEBREW_BREW_DEFAULT_GIT_REMOTE}" != "${HOMEBREW_BREW_GIT_REMOTE}" ]]
  715. then
  716.   ohai "HOMEBREW_BREW_GIT_REMOTE is set to a non-default URL:"
  717.   echo "${tty_underline}${HOMEBREW_BREW_GIT_REMOTE}${tty_reset} will be used as the Homebrew/brew Git remote."
  718.   non_default_repos="Homebrew/brew"
  719.   additional_shellenv_commands+=("export HOMEBREW_BREW_GIT_REMOTE=\"${HOMEBREW_BREW_GIT_REMOTE}\"")
  720. fi
  721.  
  722. if [[ "${HOMEBREW_CORE_DEFAULT_GIT_REMOTE}" != "${HOMEBREW_CORE_GIT_REMOTE}" ]]
  723. then
  724.   ohai "HOMEBREW_CORE_GIT_REMOTE is set to a non-default URL:"
  725.   echo "${tty_underline}${HOMEBREW_CORE_GIT_REMOTE}${tty_reset} will be used as the Homebrew/homebrew-core Git remote."
  726.   non_default_repos="${non_default_repos:-}${non_default_repos:+ and }Homebrew/homebrew-core"
  727.   additional_shellenv_commands+=("export HOMEBREW_CORE_GIT_REMOTE=\"${HOMEBREW_CORE_GIT_REMOTE}\"")
  728. fi
  729.  
  730. if [[ -n "${HOMEBREW_NO_INSTALL_FROM_API-}" ]]
  731. then
  732.   ohai "HOMEBREW_NO_INSTALL_FROM_API is set."
  733.   echo "Homebrew/homebrew-core will be tapped during this ${tty_bold}install${tty_reset} run."
  734. fi
  735.  
  736. if [[ -z "${NONINTERACTIVE-}" ]]
  737. then
  738.   ring_bell
  739.   wait_for_user
  740. fi
  741.  
  742. if [[ -d "${HOMEBREW_PREFIX}" ]]
  743. then
  744.   if [[ "${#chmods[@]}" -gt 0 ]]
  745.   then
  746.     execute_sudo "${CHMOD[@]}" "u+rwx" "${chmods[@]}"
  747.   fi
  748.   if [[ "${#group_chmods[@]}" -gt 0 ]]
  749.   then
  750.     execute_sudo "${CHMOD[@]}" "g+rwx" "${group_chmods[@]}"
  751.   fi
  752.   if [[ "${#user_chmods[@]}" -gt 0 ]]
  753.   then
  754.     execute_sudo "${CHMOD[@]}" "go-w" "${user_chmods[@]}"
  755.   fi
  756.   if [[ "${#chowns[@]}" -gt 0 ]]
  757.   then
  758.     execute_sudo "${CHOWN[@]}" "${USER}" "${chowns[@]}"
  759.   fi
  760.   if [[ "${#chgrps[@]}" -gt 0 ]]
  761.   then
  762.     execute_sudo "${CHGRP[@]}" "${GROUP}" "${chgrps[@]}"
  763.   fi
  764. else
  765.   execute_sudo "${INSTALL[@]}" "${HOMEBREW_PREFIX}"
  766. fi
  767.  
  768. if [[ "${#mkdirs[@]}" -gt 0 ]]
  769. then
  770.   execute_sudo "${MKDIR[@]}" "${mkdirs[@]}"
  771.   execute_sudo "${CHMOD[@]}" "ug=rwx" "${mkdirs[@]}"
  772.   if [[ "${#mkdirs_user_only[@]}" -gt 0 ]]
  773.   then
  774.     execute_sudo "${CHMOD[@]}" "go-w" "${mkdirs_user_only[@]}"
  775.   fi
  776.   execute_sudo "${CHOWN[@]}" "${USER}" "${mkdirs[@]}"
  777.   execute_sudo "${CHGRP[@]}" "${GROUP}" "${mkdirs[@]}"
  778. fi
  779.  
  780. if ! [[ -d "${HOMEBREW_REPOSITORY}" ]]
  781. then
  782.   execute_sudo "${MKDIR[@]}" "${HOMEBREW_REPOSITORY}"
  783. fi
  784. execute_sudo "${CHOWN[@]}" "-R" "${USER}:${GROUP}" "${HOMEBREW_REPOSITORY}"
  785.  
  786. if ! [[ -d "${HOMEBREW_CACHE}" ]]
  787. then
  788.   if [[ -n "${HOMEBREW_ON_MACOS-}" ]]
  789.   then
  790.     execute_sudo "${MKDIR[@]}" "${HOMEBREW_CACHE}"
  791.   else
  792.     execute "${MKDIR[@]}" "${HOMEBREW_CACHE}"
  793.   fi
  794. fi
  795. if exists_but_not_writable "${HOMEBREW_CACHE}"
  796. then
  797.   execute_sudo "${CHMOD[@]}" "g+rwx" "${HOMEBREW_CACHE}"
  798. fi
  799. if file_not_owned "${HOMEBREW_CACHE}"
  800. then
  801.   execute_sudo "${CHOWN[@]}" "-R" "${USER}" "${HOMEBREW_CACHE}"
  802. fi
  803. if file_not_grpowned "${HOMEBREW_CACHE}"
  804. then
  805.   execute_sudo "${CHGRP[@]}" "-R" "${GROUP}" "${HOMEBREW_CACHE}"
  806. fi
  807. if [[ -d "${HOMEBREW_CACHE}" ]]
  808. then
  809.   execute "${TOUCH[@]}" "${HOMEBREW_CACHE}/.cleaned"
  810. fi
  811.  
  812. if should_install_command_line_tools && version_ge "${macos_version}" "10.13"
  813. then
  814.   ohai "Searching online for the Command Line Tools"
  815.   # This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools
  816.   clt_placeholder="/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress"
  817.   execute_sudo "${TOUCH[@]}" "${clt_placeholder}"
  818.  
  819.   clt_label_command="/usr/sbin/softwareupdate -l |
  820.                      grep -B 1 -E 'Command Line Tools' |
  821.                      awk -F'*' '/^ *\\*/ {print \$2}' |
  822.                      sed -e 's/^ *Label: //' -e 's/^ *//' |
  823.                      sort -V |
  824.                      tail -n1"
  825.   clt_label="$(chomp "$(/bin/bash -c "${clt_label_command}")")"
  826.  
  827.  if [[ -n "${clt_label}" ]]
  828.  then
  829.    ohai "Installing ${clt_label}"
  830.    execute_sudo "/usr/sbin/softwareupdate" "-i" "${clt_label}"
  831.    execute_sudo "/usr/bin/xcode-select" "--switch" "/Library/Developer/CommandLineTools"
  832.  fi
  833.  execute_sudo "/bin/rm" "-f" "${clt_placeholder}"
  834. fi
  835.  
  836. # Headless install may have failed, so fallback to original 'xcode-select' method
  837. if should_install_command_line_tools && test -t 0
  838. then
  839.  ohai "Installing the Command Line Tools (expect a GUI popup):"
  840.  execute "/usr/bin/xcode-select" "--install"
  841.  echo "Press any key when the installation has completed."
  842.  getc
  843.  execute_sudo "/usr/bin/xcode-select" "--switch" "/Library/Developer/CommandLineTools"
  844. fi
  845.  
  846. if [[ -n "${HOMEBREW_ON_MACOS-}" ]] && ! output="$(/usr/bin/xcrun clang 2>&1)" && [[ "${output}" == *"license"* ]]
  847. then
  848.  abort "$(
  849.     cat <<EOABORT
  850. You have not agreed to the Xcode license.
  851. Before running the installer again please agree to the license by opening
  852. Xcode.app or running:
  853.     sudo xcodebuild -license
  854. EOABORT
  855.   )"
  856. fi
  857.  
  858. USABLE_GIT=/usr/bin/git
  859. if [[ -n "${HOMEBREW_ON_LINUX-}" ]]
  860. then
  861.  USABLE_GIT="$(find_tool git)"
  862.  if [[ -z "$(command -v git)" ]]
  863.  then
  864.    abort "$(
  865.       cat <<EOABORT
  866.   You must install Git before installing Homebrew. See:
  867.     ${tty_underline}https://docs.brew.sh/Installation${tty_reset}
  868. EOABORT
  869.     )"
  870.  fi
  871.  if [[ -z "${USABLE_GIT}" ]]
  872.  then
  873.    abort "$(
  874.       cat <<EOABORT
  875.   The version of Git that was found does not satisfy requirements for Homebrew.
  876.   Please install Git ${REQUIRED_GIT_VERSION} or newer and add it to your PATH.
  877. EOABORT
  878.     )"
  879.  fi
  880.  if [[ "${USABLE_GIT}" != /usr/bin/git ]]
  881.  then
  882.    export HOMEBREW_GIT_PATH="${USABLE_GIT}"
  883.    ohai "Found Git: ${HOMEBREW_GIT_PATH}"
  884.  fi
  885. fi
  886.  
  887. if ! command -v curl >/dev/null
  888. then
  889.  abort "$(
  890.     cat <<EOABORT
  891. You must install cURL before installing Homebrew. See:
  892.   ${tty_underline}https://docs.brew.sh/Installation${tty_reset}
  893. EOABORT
  894.   )"
  895. elif [[ -n "${HOMEBREW_ON_LINUX-}" ]]
  896. then
  897.  USABLE_CURL="$(find_tool curl)"
  898.  if [[ -z "${USABLE_CURL}" ]]
  899.  then
  900.    abort "$(
  901.       cat <<EOABORT
  902. The version of cURL that was found does not satisfy requirements for Homebrew.
  903. Please install cURL ${REQUIRED_CURL_VERSION} or newer and add it to your PATH.
  904. EOABORT
  905.     )"
  906.  elif [[ "${USABLE_CURL}" != /usr/bin/curl ]]
  907.  then
  908.    export HOMEBREW_CURL_PATH="${USABLE_CURL}"
  909.    ohai "Found cURL: ${HOMEBREW_CURL_PATH}"
  910.  fi
  911. fi
  912.  
  913. ohai "Downloading and installing Homebrew..."
  914. (
  915.  cd "${HOMEBREW_REPOSITORY}" >/dev/null || return
  916.  
  917.  # we do it in four steps to avoid merge errors when reinstalling
  918.  execute "${USABLE_GIT}" "-c" "init.defaultBranch=master" "init" "--quiet"
  919.  
  920.  # "git remote add" will fail if the remote is defined in the global config
  921.  execute "${USABLE_GIT}" "config" "remote.origin.url" "${HOMEBREW_BREW_GIT_REMOTE}"
  922.  execute "${USABLE_GIT}" "config" "remote.origin.fetch" "+refs/heads/*:refs/remotes/origin/*"
  923.  
  924.  # ensure we don't munge line endings on checkout
  925.  execute "${USABLE_GIT}" "config" "--bool" "core.autocrlf" "false"
  926.  
  927.  # make sure symlinks are saved as-is
  928.  execute "${USABLE_GIT}" "config" "--bool" "core.symlinks" "true"
  929.  
  930.  execute "${USABLE_GIT}" "fetch" "--force" "origin"
  931.  execute "${USABLE_GIT}" "fetch" "--force" "--tags" "origin"
  932.  
  933.  execute "${USABLE_GIT}" "reset" "--hard" "origin/master"
  934.  
  935.  if [[ "${HOMEBREW_REPOSITORY}" != "${HOMEBREW_PREFIX}" ]]
  936.  then
  937.    if [[ "${HOMEBREW_REPOSITORY}" == "${HOMEBREW_PREFIX}/Homebrew" ]]
  938.    then
  939.      execute "ln" "-sf" "../Homebrew/bin/brew" "${HOMEBREW_PREFIX}/bin/brew"
  940.    else
  941.      abort "The Homebrew/brew repository should be placed in the Homebrew prefix directory."
  942.    fi
  943.  fi
  944.  
  945.  if [[ -n "${HOMEBREW_NO_INSTALL_FROM_API-}" && ! -d "${HOMEBREW_CORE}" ]]
  946.  then
  947.    # Always use single-quoted strings with `exp` expressions
  948.    # shellcheck disable=SC2016
  949.    ohai 'Tapping homebrew/core because `$HOMEBREW_NO_INSTALL_FROM_API` is set.'
  950.    (
  951.      execute "${MKDIR[@]}" "${HOMEBREW_CORE}"
  952.      cd "${HOMEBREW_CORE}" >/dev/null || return
  953.  
  954.      execute "${USABLE_GIT}" "-c" "init.defaultBranch=master" "init" "--quiet"
  955.      execute "${USABLE_GIT}" "config" "remote.origin.url" "${HOMEBREW_CORE_GIT_REMOTE}"
  956.      execute "${USABLE_GIT}" "config" "remote.origin.fetch" "+refs/heads/*:refs/remotes/origin/*"
  957.      execute "${USABLE_GIT}" "config" "--bool" "core.autocrlf" "false"
  958.      execute "${USABLE_GIT}" "config" "--bool" "core.symlinks" "true"
  959.      execute "${USABLE_GIT}" "fetch" "--force" "origin" "refs/heads/master:refs/remotes/origin/master"
  960.      execute "${USABLE_GIT}" "remote" "set-head" "origin" "--auto" >/dev/null
  961.      execute "${USABLE_GIT}" "reset" "--hard" "origin/master"
  962.  
  963.      cd "${HOMEBREW_REPOSITORY}" >/dev/null || return
  964.    ) || exit 1
  965.  fi
  966.  
  967.  execute "${HOMEBREW_PREFIX}/bin/brew" "update" "--force" "--quiet"
  968. ) || exit 1
  969.  
  970. if [[ ":${PATH}:" != *":${HOMEBREW_PREFIX}/bin:"* ]]
  971. then
  972.  warn "${HOMEBREW_PREFIX}/bin is not in your PATH.
  973.   Instructions on how to configure your shell for Homebrew
  974.   can be found in the 'Next steps' section below."
  975. fi
  976.  
  977. ohai "Installation successful!"
  978. echo
  979.  
  980. ring_bell
  981.  
  982. # Use an extra newline and bold to avoid this being missed.
  983. ohai "Homebrew has enabled anonymous aggregate formulae and cask analytics."
  984. echo "$(
  985.   cat <<EOS
  986. ${tty_bold}Read the analytics documentation (and how to opt-out) here:
  987.   ${tty_underline}https://docs.brew.sh/Analytics${tty_reset}
  988. No analytics data has been sent yet (nor will any be during this ${tty_bold}install${tty_reset} run).
  989. EOS
  990. )
  991. "
  992.  
  993. ohai "Homebrew is run entirely by unpaid volunteers. Please consider donating:"
  994. echo "$(
  995.   cat <<EOS
  996.   ${tty_underline}https://github.com/Homebrew/brew#donations${tty_reset}
  997. EOS
  998. )
  999. "
  1000.  
  1001. (
  1002.  cd "${HOMEBREW_REPOSITORY}" >/dev/null || return
  1003.  execute "${USABLE_GIT}" "config" "--replace-all" "homebrew.analyticsmessage" "true"
  1004.  execute "${USABLE_GIT}" "config" "--replace-all" "homebrew.caskanalyticsmessage" "true"
  1005. ) || exit 1
  1006.  
  1007. ohai "Next steps:"
  1008. case "${SHELL}" in
  1009.  */bash*)
  1010.    if [[ -n "${HOMEBREW_ON_LINUX-}" ]]
  1011.    then
  1012.      shell_rcfile="${HOME}/.bashrc"
  1013.    else
  1014.      shell_rcfile="${HOME}/.bash_profile"
  1015.    fi
  1016.    ;;
  1017.  */zsh*)
  1018.    if [[ -n "${HOMEBREW_ON_LINUX-}" ]]
  1019.    then
  1020.      shell_rcfile="${ZDOTDIR:-"${HOME}"}/.zshrc"
  1021.     else
  1022.       shell_rcfile="${ZDOTDIR:-"${HOME}"}/.zprofile"
  1023.    fi
  1024.    ;;
  1025.  */fish*)
  1026.    shell_rcfile="${HOME}/.config/fish/config.fish"
  1027.    ;;
  1028.  *)
  1029.    shell_rcfile="${ENV:-"${HOME}/.profile"}"
  1030.     ;;
  1031. esac
  1032.  
  1033. if grep -qs "eval \"\$(${HOMEBREW_PREFIX}/bin/brew shellenv)\"" "${shell_rcfile}"
  1034. then
  1035.   if ! [[ -x "$(command -v brew)" ]]
  1036.   then
  1037.     cat <<EOS
  1038. - Run this command in your terminal to add Homebrew to your ${tty_bold}PATH${tty_reset}:
  1039.     eval "\$(${HOMEBREW_PREFIX}/bin/brew shellenv)"
  1040. EOS
  1041.   fi
  1042. else
  1043.   cat <<EOS
  1044. - Run these two commands in your terminal to add Homebrew to your ${tty_bold}PATH${tty_reset}:
  1045.     (echo; echo 'eval "\$(${HOMEBREW_PREFIX}/bin/brew shellenv)"') >> ${shell_rcfile}
  1046.     eval "\$(${HOMEBREW_PREFIX}/bin/brew shellenv)"
  1047. EOS
  1048. fi
  1049.  
  1050. if [[ -n "${non_default_repos}" ]]
  1051. then
  1052.   plural=""
  1053.   if [[ "${#additional_shellenv_commands[@]}" -gt 1 ]]
  1054.   then
  1055.     plural="s"
  1056.   fi
  1057.   printf -- "- Run these commands in your terminal to add the non-default Git remote%s for %s:\n" "${plural}" "${non_default_repos}"
  1058.   printf "    echo '# Set PATH, MANPATH, etc., for Homebrew.' >> %s\n" "${shell_rcfile}"
  1059.   printf "    echo '%s' >> ${shell_rcfile}\n" "${additional_shellenv_commands[@]}"
  1060.   printf "    %s\n" "${additional_shellenv_commands[@]}"
  1061. fi
  1062.  
  1063. if [[ -n "${HOMEBREW_ON_LINUX-}" ]]
  1064. then
  1065.   echo "- Install Homebrew's dependencies if you have sudo access:"
  1066.  
  1067.   if [[ -x "$(command -v apt-get)" ]]
  1068.   then
  1069.     echo "    sudo apt-get install build-essential"
  1070.   elif [[ -x "$(command -v yum)" ]]
  1071.   then
  1072.     echo "    sudo yum groupinstall 'Development Tools'"
  1073.   elif [[ -x "$(command -v pacman)" ]]
  1074.   then
  1075.     echo "    sudo pacman -S base-devel"
  1076.   elif [[ -x "$(command -v apk)" ]]
  1077.   then
  1078.     echo "    sudo apk add build-base"
  1079.   fi
  1080.  
  1081.   cat <<EOS
  1082.   For more information, see:
  1083.     ${tty_underline}https://docs.brew.sh/Homebrew-on-Linux${tty_reset}
  1084. - We recommend that you install GCC:
  1085.     brew install gcc
  1086. EOS
  1087. fi
  1088.  
  1089. cat <<EOS
  1090. - Run ${tty_bold}brew help${tty_reset} to get started
  1091. - Further documentation:
  1092.     ${tty_underline}https://docs.brew.sh${tty_reset}
  1093.  
  1094. EOS
  1095.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement