2025-01-09 12:48:48 +00:00
|
|
|
#!/bin/bash -pu
|
2022-11-28 19:31:28 +01:00
|
|
|
set -u
|
2016-02-25 11:22:02 +00:00
|
|
|
|
2021-09-16 21:18:48 +08:00
|
|
|
# Fail fast with concise message when not using bash
|
|
|
|
# Single brackets is needed here for POSIX compatibility
|
2021-11-07 21:21:42 +08:00
|
|
|
# shellcheck disable=SC2292
|
2021-09-16 21:18:48 +08:00
|
|
|
if [ -z "${BASH_VERSION:-}" ]
|
2021-09-16 01:04:06 +08:00
|
|
|
then
|
2021-09-16 21:18:48 +08:00
|
|
|
echo "Error: Bash is required to run brew." >&2
|
2018-05-26 05:30:35 -04:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2021-09-16 21:18:48 +08:00
|
|
|
set +o posix # as we are using bash now
|
|
|
|
|
2024-01-10 17:21:57 +00:00
|
|
|
# Fail fast with concise messages when PWD has issues
|
|
|
|
if [[ -z "${PWD-}" ]]
|
|
|
|
then
|
|
|
|
echo "Error: \$PWD must be set to run brew." >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
2021-09-16 21:18:48 +08:00
|
|
|
if ! [[ -d "${PWD}" ]]
|
2021-09-16 01:04:06 +08:00
|
|
|
then
|
2024-01-10 17:21:57 +00:00
|
|
|
echo "Error: The current working directory must exist to run brew." >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
if ! [[ -r "${PWD}" ]]
|
|
|
|
then
|
2024-01-11 12:24:04 +00:00
|
|
|
echo "Error: The current working directory must be readable to ${USER} to run brew." >&2
|
2021-09-15 17:10:05 +08:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2023-08-05 13:41:50 +01:00
|
|
|
# Fail fast with concise message when HOME is unset
|
|
|
|
if [[ -z "${HOME:-}" ]]
|
|
|
|
then
|
|
|
|
echo "Error: \$HOME must be set to run brew." >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2016-06-28 21:32:45 +02:00
|
|
|
quiet_cd() {
|
2023-11-04 16:10:21 -07:00
|
|
|
CDPATH='' cd -- "$@" &>/dev/null || return
|
2014-11-25 22:27:03 -05:00
|
|
|
}
|
|
|
|
|
2016-08-24 10:55:46 +01:00
|
|
|
symlink_target_directory() {
|
2018-10-04 09:31:37 +01:00
|
|
|
local target target_dirname
|
|
|
|
target="$(readlink "$1")"
|
2021-04-16 00:02:13 +09:00
|
|
|
target_dirname="$(dirname "${target}")"
|
2016-08-24 10:55:46 +01:00
|
|
|
local directory="$2"
|
2021-04-16 00:02:13 +09:00
|
|
|
quiet_cd "${directory}" && quiet_cd "${target_dirname}" && pwd -P
|
2016-08-24 10:55:46 +01:00
|
|
|
}
|
|
|
|
|
2019-11-04 10:40:53 -06:00
|
|
|
# Enable and use default Bash builtins rather than user-defined functions
|
2019-11-04 11:21:13 -06:00
|
|
|
builtin enable compgen unset
|
|
|
|
for cmd in $(builtin compgen -A builtin)
|
2019-11-04 09:56:03 -06:00
|
|
|
do
|
2021-04-16 00:02:13 +09:00
|
|
|
builtin unset -f "${cmd}"
|
|
|
|
builtin enable "${cmd}"
|
2019-11-04 09:56:03 -06:00
|
|
|
done
|
|
|
|
unset cmd
|
|
|
|
|
2024-06-04 03:47:31 +01:00
|
|
|
# Take the HOMEBREW_PATH if we are running brew within brew, otherwise we would lose the original path.
|
|
|
|
if [[ -n "${HOMEBREW_BREW_FILE:-}" && -n "${HOMEBREW_PATH:-}" ]]
|
|
|
|
then
|
|
|
|
PATH="${HOMEBREW_PATH}"
|
|
|
|
fi
|
|
|
|
|
2016-06-29 16:20:47 +02:00
|
|
|
BREW_FILE_DIRECTORY="$(quiet_cd "${0%/*}/" && pwd -P)"
|
|
|
|
HOMEBREW_BREW_FILE="${BREW_FILE_DIRECTORY%/}/${0##*/}"
|
2016-02-13 11:31:00 -08:00
|
|
|
HOMEBREW_PREFIX="${HOMEBREW_BREW_FILE%/*/*}"
|
2016-08-24 10:55:19 +01:00
|
|
|
|
|
|
|
# Default to / prefix if unset or the bin/brew file.
|
2021-04-16 00:02:13 +09:00
|
|
|
if [[ -z "${HOMEBREW_PREFIX}" || "${HOMEBREW_PREFIX}" = "${HOMEBREW_BREW_FILE}" ]]
|
2016-08-24 10:55:19 +01:00
|
|
|
then
|
|
|
|
HOMEBREW_PREFIX="/"
|
|
|
|
fi
|
2016-06-29 16:20:47 +02:00
|
|
|
|
2021-04-16 00:02:13 +09:00
|
|
|
HOMEBREW_REPOSITORY="${HOMEBREW_PREFIX}"
|
2016-02-13 11:31:00 -08:00
|
|
|
|
2016-08-24 10:55:46 +01:00
|
|
|
# Resolve the bin/brew symlink to find Homebrew's repository
|
2021-04-16 00:02:13 +09:00
|
|
|
if [[ -L "${HOMEBREW_BREW_FILE}" ]]
|
2013-02-08 08:55:42 -08:00
|
|
|
then
|
2021-04-16 00:02:13 +09:00
|
|
|
BREW_FILE_DIRECTORY="$(symlink_target_directory "${HOMEBREW_BREW_FILE}" "${BREW_FILE_DIRECTORY}")"
|
2016-02-13 11:31:00 -08:00
|
|
|
HOMEBREW_REPOSITORY="${BREW_FILE_DIRECTORY%/*}"
|
2013-02-08 08:55:42 -08:00
|
|
|
fi
|
|
|
|
|
2024-05-14 00:20:30 +01:00
|
|
|
# Try to find a /usr/local HOMEBREW_PREFIX where possible (for macOS x86_64 bottles)
|
2021-04-16 00:02:13 +09:00
|
|
|
if [[ -L "/usr/local/bin/brew" && ! -L "${HOMEBREW_PREFIX}/Cellar" ]]
|
2016-08-24 10:56:23 +01:00
|
|
|
then
|
|
|
|
USR_LOCAL_BREW_FILE_DIRECTORY="$(symlink_target_directory "/usr/local/bin/brew" "/usr/local/bin")"
|
|
|
|
USR_LOCAL_HOMEBREW_REPOSITORY="${USR_LOCAL_BREW_FILE_DIRECTORY%/*}"
|
2021-04-16 00:02:13 +09:00
|
|
|
if [[ "${HOMEBREW_REPOSITORY}" = "${USR_LOCAL_HOMEBREW_REPOSITORY}" ]]
|
2016-08-24 10:56:23 +01:00
|
|
|
then
|
|
|
|
HOMEBREW_PREFIX="/usr/local"
|
|
|
|
fi
|
2023-07-28 17:17:14 +01:00
|
|
|
unset USR_LOCAL_BREW_FILE_DIRECTORY USR_LOCAL_HOMEBREW_REPOSITORY
|
2016-08-24 10:56:23 +01:00
|
|
|
fi
|
|
|
|
|
2023-07-28 17:17:14 +01:00
|
|
|
unset BREW_FILE_DIRECTORY
|
|
|
|
|
2020-12-16 14:03:10 -08:00
|
|
|
# If the location of HOMEBREW_LIBRARY changes
|
|
|
|
# keg_relocate.rb, formula_cellar_checks.rb, and test/global_spec.rb need to change.
|
2021-04-16 00:02:13 +09:00
|
|
|
HOMEBREW_LIBRARY="${HOMEBREW_REPOSITORY}/Library"
|
2015-12-25 22:42:00 +00:00
|
|
|
|
2025-01-07 17:40:18 +00:00
|
|
|
# These variables are exported in this file and are not allowed to be overridden by the user.
|
|
|
|
BIN_BREW_EXPORTED_VARS=(
|
|
|
|
HOMEBREW_BREW_FILE
|
|
|
|
HOMEBREW_PREFIX
|
|
|
|
HOMEBREW_REPOSITORY
|
|
|
|
HOMEBREW_LIBRARY
|
|
|
|
HOMEBREW_USER_CONFIG_HOME
|
|
|
|
HOMEBREW_ORIGINAL_BREW_FILE
|
|
|
|
)
|
|
|
|
|
2023-07-28 17:17:14 +01:00
|
|
|
# Load Homebrew's variable configuration files from disk.
|
2023-08-04 21:54:26 +08:00
|
|
|
export_homebrew_env_file() {
|
2024-08-21 09:46:49 +01:00
|
|
|
local env_file
|
2023-08-04 21:54:26 +08:00
|
|
|
|
2024-08-21 09:46:49 +01:00
|
|
|
env_file="${1}"
|
2023-08-04 21:54:26 +08:00
|
|
|
[[ -r "${env_file}" ]] || return 0
|
|
|
|
while read -r line
|
|
|
|
do
|
2025-08-18 03:24:36 +01:00
|
|
|
# only load variables defined in env_config.rb
|
|
|
|
[[ "${line}" =~ ^(HOMEBREW_|SUDO_ASKPASS=|(all|no|ftp|https?)_proxy=) ]] || continue
|
2025-01-07 17:40:18 +00:00
|
|
|
|
|
|
|
# forbid overriding variables that are set in this file
|
|
|
|
local invalid_variable
|
|
|
|
for VAR in "${BIN_BREW_EXPORTED_VARS[@]}"
|
|
|
|
do
|
|
|
|
[[ "${line}" = "${VAR}"* ]] && invalid_variable="${VAR}"
|
|
|
|
done
|
2025-01-09 12:25:10 +00:00
|
|
|
[[ -n "${invalid_variable:-}" ]] && continue
|
2025-01-07 17:40:18 +00:00
|
|
|
|
2023-08-04 21:54:26 +08:00
|
|
|
export "${line?}"
|
|
|
|
done <"${env_file}"
|
|
|
|
}
|
|
|
|
|
2025-08-13 14:37:11 +08:00
|
|
|
# We only want to be able to set this in `brew.env` files.
|
|
|
|
unset HOMEBREW_DISABLE_NO_FORCE_BREW_WRAPPER
|
|
|
|
|
2023-07-28 17:17:14 +01:00
|
|
|
# First, load the system-wide configuration.
|
2024-12-13 06:19:16 +08:00
|
|
|
export_homebrew_env_file "/etc/homebrew/brew.env"
|
|
|
|
|
2023-08-04 21:54:26 +08:00
|
|
|
unset SYSTEM_ENV_TAKES_PRIORITY
|
|
|
|
if [[ -n "${HOMEBREW_SYSTEM_ENV_TAKES_PRIORITY-}" ]]
|
2023-07-28 17:17:14 +01:00
|
|
|
then
|
2023-08-04 21:54:26 +08:00
|
|
|
SYSTEM_ENV_TAKES_PRIORITY="1"
|
2023-07-28 17:17:14 +01:00
|
|
|
fi
|
|
|
|
|
|
|
|
# Next, load the prefix configuration
|
2023-08-04 21:54:26 +08:00
|
|
|
export_homebrew_env_file "${HOMEBREW_PREFIX}/etc/homebrew/brew.env"
|
2023-07-28 17:17:14 +01:00
|
|
|
|
|
|
|
# Finally, load the user configuration
|
|
|
|
if [[ -n "${XDG_CONFIG_HOME-}" ]]
|
|
|
|
then
|
|
|
|
HOMEBREW_USER_CONFIG_HOME="${XDG_CONFIG_HOME}/homebrew"
|
2023-08-04 08:30:37 +01:00
|
|
|
else
|
2023-08-05 13:41:50 +01:00
|
|
|
HOMEBREW_USER_CONFIG_HOME="${HOME}/.homebrew"
|
2023-07-28 17:17:14 +01:00
|
|
|
fi
|
2023-08-04 08:30:37 +01:00
|
|
|
|
2023-08-04 21:54:26 +08:00
|
|
|
export_homebrew_env_file "${HOMEBREW_USER_CONFIG_HOME}/brew.env"
|
2023-07-28 17:17:14 +01:00
|
|
|
|
2024-12-13 06:19:16 +08:00
|
|
|
# If the system configuration takes priority, load it again to override any previous settings.
|
2023-07-28 17:17:14 +01:00
|
|
|
if [[ -n "${SYSTEM_ENV_TAKES_PRIORITY-}" ]]
|
|
|
|
then
|
2023-08-04 21:54:26 +08:00
|
|
|
export_homebrew_env_file "/etc/homebrew/brew.env"
|
2023-07-28 17:17:14 +01:00
|
|
|
fi
|
|
|
|
|
2025-08-09 03:15:53 +08:00
|
|
|
# Use HOMEBREW_FORCE_BREW_WRAPPER if set.
|
|
|
|
export HOMEBREW_ORIGINAL_BREW_FILE="${HOMEBREW_BREW_FILE}"
|
|
|
|
if [[ -n "${HOMEBREW_FORCE_BREW_WRAPPER:-}" ]]
|
|
|
|
then
|
|
|
|
HOMEBREW_BREW_FILE="${HOMEBREW_FORCE_BREW_WRAPPER}"
|
|
|
|
fi
|
|
|
|
|
2020-09-09 11:49:26 -07:00
|
|
|
# Copy and export all HOMEBREW_* variables previously mentioned in
|
2017-05-13 11:42:01 +01:00
|
|
|
# manpage or used elsewhere by Homebrew.
|
2023-02-15 13:27:02 +08:00
|
|
|
|
|
|
|
# These variables are allowed to be set by the user as, e.g., `HOMEBREW_BROWSER`.
|
|
|
|
MANPAGE_VARS=(
|
|
|
|
BAT_CONFIG_PATH
|
|
|
|
BAT_THEME
|
|
|
|
BROWSER
|
2024-05-18 00:08:42 +09:00
|
|
|
BUNDLE_USER_CACHE
|
2023-02-15 13:27:02 +08:00
|
|
|
DISPLAY
|
|
|
|
EDITOR
|
|
|
|
NO_COLOR
|
|
|
|
)
|
|
|
|
for VAR in "${MANPAGE_VARS[@]}"
|
2017-04-19 10:49:20 +01:00
|
|
|
do
|
2025-06-05 08:33:08 +01:00
|
|
|
# Skip if variable value is empty or set to 0.
|
|
|
|
[[ -z "${!VAR:-}" || "${!VAR:-}" = "0" ]] && continue
|
2017-05-14 20:05:26 +01:00
|
|
|
|
2017-04-19 10:49:20 +01:00
|
|
|
VAR_NEW="HOMEBREW_${VAR}"
|
2017-05-14 20:05:26 +01:00
|
|
|
# Skip if existing HOMEBREW_* variable is set.
|
2022-11-28 19:31:28 +01:00
|
|
|
[[ -n "${!VAR_NEW:-}" ]] && continue
|
2021-04-16 00:02:13 +09:00
|
|
|
export "${VAR_NEW}"="${!VAR}"
|
2017-04-19 10:49:20 +01:00
|
|
|
done
|
2023-02-15 13:27:02 +08:00
|
|
|
|
|
|
|
# We don't want to take the user's value for, e.g., `HOMEBREW_PATH` here!
|
|
|
|
USED_BY_HOMEBREW_VARS=(
|
|
|
|
CODESPACES
|
2023-10-30 00:01:51 +03:00
|
|
|
COLORTERM
|
2023-02-15 13:27:02 +08:00
|
|
|
DBUS_SESSION_BUS_ADDRESS
|
2024-01-09 10:13:33 +00:00
|
|
|
NODENV_ROOT
|
2023-02-15 13:27:02 +08:00
|
|
|
PATH
|
2024-01-09 10:13:33 +00:00
|
|
|
PYENV_ROOT
|
|
|
|
RBENV_ROOT
|
2023-09-27 11:55:31 +01:00
|
|
|
SSH_TTY
|
|
|
|
SUDO_USER
|
2024-09-05 15:49:11 +08:00
|
|
|
TMPDIR
|
2023-02-15 13:27:02 +08:00
|
|
|
TMUX
|
2023-10-28 18:29:16 -07:00
|
|
|
XDG_CACHE_HOME
|
2024-08-03 11:29:04 +08:00
|
|
|
XDG_DATA_DIRS
|
2023-02-15 13:27:02 +08:00
|
|
|
XDG_RUNTIME_DIR
|
2024-06-12 16:24:45 +02:00
|
|
|
ZDOTDIR
|
2023-02-15 13:27:02 +08:00
|
|
|
)
|
|
|
|
for VAR in "${USED_BY_HOMEBREW_VARS[@]}"
|
|
|
|
do
|
|
|
|
# Skip if variable value is empty.
|
|
|
|
[[ -z "${!VAR:-}" ]] && continue
|
|
|
|
|
|
|
|
# We unconditionally override `HOMEBREW_*` here.
|
|
|
|
VAR_NEW="HOMEBREW_${VAR}"
|
|
|
|
export "${VAR_NEW}"="${!VAR}"
|
|
|
|
done
|
|
|
|
|
|
|
|
unset VAR VAR_NEW MANPAGE_VARS USED_BY_HOMEBREW_VARS
|
2017-04-19 10:49:20 +01:00
|
|
|
|
2025-01-07 17:40:18 +00:00
|
|
|
for VAR in "${BIN_BREW_EXPORTED_VARS[@]}"
|
|
|
|
do
|
|
|
|
export "${VAR?}"
|
|
|
|
done
|
2021-03-02 16:59:57 +00:00
|
|
|
|
2021-04-15 17:24:17 +01:00
|
|
|
# set from user environment
|
2021-04-16 00:02:13 +09:00
|
|
|
# shellcheck disable=SC2154
|
2020-04-05 15:44:50 +01:00
|
|
|
# Use VISUAL if HOMEBREW_EDITOR and EDITOR are unset.
|
2022-11-28 19:36:03 +01:00
|
|
|
if [[ -z "${HOMEBREW_EDITOR:-}" && -n "${VISUAL:-}" ]]
|
2020-04-05 15:44:50 +01:00
|
|
|
then
|
2021-04-16 00:02:13 +09:00
|
|
|
export HOMEBREW_EDITOR="${VISUAL}"
|
2020-04-05 15:44:50 +01:00
|
|
|
fi
|
|
|
|
|
2021-04-15 17:24:17 +01:00
|
|
|
# set from user environment
|
2021-04-16 00:02:13 +09:00
|
|
|
# shellcheck disable=SC2154
|
2020-08-07 12:47:04 +01:00
|
|
|
# Set CI variable for Azure Pipelines and Jenkins
|
2021-04-12 22:47:33 +09:00
|
|
|
# (Set by default on GitHub Actions, Circle and Travis CI)
|
2022-11-28 19:31:28 +01:00
|
|
|
if [[ -z "${CI:-}" ]] && [[ -n "${TF_BUILD:-}" || -n "${JENKINS_HOME:-}" ]]
|
2019-01-17 09:22:50 +00:00
|
|
|
then
|
|
|
|
export CI="1"
|
|
|
|
fi
|
|
|
|
|
2023-07-06 17:33:49 +01:00
|
|
|
if [[ -n "${GITHUB_ACTIONS:-}" && -n "${ImageOS:-}" && -n "${ImageVersion:-}" ]]
|
|
|
|
then
|
|
|
|
export HOMEBREW_GITHUB_HOSTED_RUNNER=1
|
|
|
|
fi
|
|
|
|
|
2025-03-24 13:37:25 +00:00
|
|
|
# don't filter the environment for `brew bundle (exec|env|sh)`
|
|
|
|
if [[ "${1:-}" == "bundle" ]]
|
|
|
|
then
|
|
|
|
if [[ "${2:-}" == "exec" || "${2:-}" == "env" || "${2:-}" == "sh" ]]
|
|
|
|
then
|
|
|
|
exec /bin/bash -p "${HOMEBREW_LIBRARY}/Homebrew/brew.sh" "$@"
|
|
|
|
exit $?
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
2022-07-22 14:39:21 +01:00
|
|
|
# filter the user environment
|
|
|
|
PATH="/usr/bin:/bin:/usr/sbin:/sbin"
|
|
|
|
|
|
|
|
FILTERED_ENV=()
|
|
|
|
ENV_VAR_NAMES=(
|
|
|
|
HOME SHELL PATH TERM TERMINFO TERMINFO_DIRS COLUMNS DISPLAY LOGNAME USER CI SSH_AUTH_SOCK SUDO_ASKPASS
|
|
|
|
http_proxy https_proxy ftp_proxy no_proxy all_proxy HTTPS_PROXY FTP_PROXY ALL_PROXY
|
|
|
|
)
|
|
|
|
# Filter all but the specific variables.
|
|
|
|
for VAR in "${ENV_VAR_NAMES[@]}" "${!HOMEBREW_@}"
|
|
|
|
do
|
|
|
|
# Skip if variable value is empty.
|
2022-11-28 19:31:28 +01:00
|
|
|
[[ -z "${!VAR:-}" ]] && continue
|
2022-07-22 14:39:21 +01:00
|
|
|
|
|
|
|
FILTERED_ENV+=("${VAR}=${!VAR}")
|
|
|
|
done
|
2023-05-17 15:58:27 +08:00
|
|
|
|
2023-05-24 12:49:27 +01:00
|
|
|
if [[ -n "${CI:-}" ]]
|
2023-05-17 15:58:27 +08:00
|
|
|
then
|
|
|
|
for VAR in "${!GITHUB_@}"
|
|
|
|
do
|
|
|
|
# Skip if variable value is empty.
|
|
|
|
[[ -z "${!VAR:-}" ]] && continue
|
|
|
|
# Skip variables that look like tokens.
|
|
|
|
[[ "${VAR}" = *TOKEN* ]] && continue
|
|
|
|
|
|
|
|
FILTERED_ENV+=("${VAR}=${!VAR}")
|
|
|
|
done
|
|
|
|
fi
|
2024-08-15 11:40:36 -04:00
|
|
|
|
|
|
|
if [[ -n "${HOMEBREW_RDBG:-}" ]]
|
|
|
|
then
|
|
|
|
for VAR in "${!RUBY_DEBUG_@}"
|
|
|
|
do
|
|
|
|
# Skip if variable value is empty.
|
|
|
|
[[ -z "${!VAR:-}" ]] && continue
|
|
|
|
|
|
|
|
FILTERED_ENV+=("${VAR}=${!VAR}")
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
2022-07-22 14:39:21 +01:00
|
|
|
unset VAR ENV_VAR_NAMES
|
|
|
|
|
2024-03-21 03:25:49 +00:00
|
|
|
exec /usr/bin/env -i "${FILTERED_ENV[@]}" /bin/bash -p "${HOMEBREW_LIBRARY}/Homebrew/brew.sh" "$@"
|