
We inherit some variables from the user's environment but prefix them with `HOMEBREW_`. This is the case for (1) variables documented in the manpage and also for some (2) variables used internally by `brew`. We currently treat both types identically, but we should not. In particular, we allow users to override type (1), but we don't want to do this for type (2). This was partially fixed in f4103e5d61526cfbf7f31540ba45ec171adc452e, but that fix did not go far enough. Some variables that the user should not be allowed to override can still be overridden. This change completes the partial fix and refactors the code so that we're less likely to mistakenly conflate the two types of variables in the future.
172 lines
4.9 KiB
Bash
Executable File
172 lines
4.9 KiB
Bash
Executable File
#!/bin/bash
|
|
set -u
|
|
|
|
# Fail fast with concise message when not using bash
|
|
# Single brackets is needed here for POSIX compatibility
|
|
# shellcheck disable=SC2292
|
|
if [ -z "${BASH_VERSION:-}" ]
|
|
then
|
|
echo "Error: Bash is required to run brew." >&2
|
|
exit 1
|
|
fi
|
|
|
|
set +o posix # as we are using bash now
|
|
|
|
# Fail fast with concise message when cwd does not exist
|
|
if ! [[ -d "${PWD}" ]]
|
|
then
|
|
echo "Error: The current working directory doesn't exist, cannot proceed." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Fail fast with concise message when requesting unfiltered environment.
|
|
# This is basically odisabled so can be removed at any major release afterwards
|
|
# and definitely if this is still here in 2023.
|
|
if [[ -n "${HOMEBREW_NO_ENV_FILTERING:-}" ]]
|
|
then
|
|
echo "Error: HOMEBREW_NO_ENV_FILTERING was deprecated for over a year and has now been removed (because it breaks many things)!" >&2
|
|
exit 1
|
|
fi
|
|
|
|
quiet_cd() {
|
|
cd "$@" &>/dev/null || return
|
|
}
|
|
|
|
symlink_target_directory() {
|
|
local target target_dirname
|
|
target="$(readlink "$1")"
|
|
target_dirname="$(dirname "${target}")"
|
|
local directory="$2"
|
|
quiet_cd "${directory}" && quiet_cd "${target_dirname}" && pwd -P
|
|
}
|
|
|
|
# Enable and use default Bash builtins rather than user-defined functions
|
|
builtin enable compgen unset
|
|
for cmd in $(builtin compgen -A builtin)
|
|
do
|
|
builtin unset -f "${cmd}"
|
|
builtin enable "${cmd}"
|
|
done
|
|
unset cmd
|
|
|
|
BREW_FILE_DIRECTORY="$(quiet_cd "${0%/*}/" && pwd -P)"
|
|
HOMEBREW_BREW_FILE="${BREW_FILE_DIRECTORY%/}/${0##*/}"
|
|
HOMEBREW_PREFIX="${HOMEBREW_BREW_FILE%/*/*}"
|
|
|
|
# Default to / prefix if unset or the bin/brew file.
|
|
if [[ -z "${HOMEBREW_PREFIX}" || "${HOMEBREW_PREFIX}" = "${HOMEBREW_BREW_FILE}" ]]
|
|
then
|
|
HOMEBREW_PREFIX="/"
|
|
fi
|
|
|
|
HOMEBREW_REPOSITORY="${HOMEBREW_PREFIX}"
|
|
|
|
# Resolve the bin/brew symlink to find Homebrew's repository
|
|
if [[ -L "${HOMEBREW_BREW_FILE}" ]]
|
|
then
|
|
BREW_FILE_DIRECTORY="$(symlink_target_directory "${HOMEBREW_BREW_FILE}" "${BREW_FILE_DIRECTORY}")"
|
|
HOMEBREW_REPOSITORY="${BREW_FILE_DIRECTORY%/*}"
|
|
fi
|
|
|
|
# Try to find a /usr/local HOMEBREW_PREFIX where possible (for bottles)
|
|
if [[ -L "/usr/local/bin/brew" && ! -L "${HOMEBREW_PREFIX}/Cellar" ]]
|
|
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%/*}"
|
|
if [[ "${HOMEBREW_REPOSITORY}" = "${USR_LOCAL_HOMEBREW_REPOSITORY}" ]]
|
|
then
|
|
HOMEBREW_PREFIX="/usr/local"
|
|
fi
|
|
fi
|
|
|
|
# If the location of HOMEBREW_LIBRARY changes
|
|
# keg_relocate.rb, formula_cellar_checks.rb, and test/global_spec.rb need to change.
|
|
HOMEBREW_LIBRARY="${HOMEBREW_REPOSITORY}/Library"
|
|
|
|
# Copy and export all HOMEBREW_* variables previously mentioned in
|
|
# manpage or used elsewhere by Homebrew.
|
|
|
|
# These variables are allowed to be set by the user as, e.g., `HOMEBREW_BROWSER`.
|
|
MANPAGE_VARS=(
|
|
BAT_CONFIG_PATH
|
|
BAT_THEME
|
|
BROWSER
|
|
DISPLAY
|
|
EDITOR
|
|
NO_COLOR
|
|
)
|
|
for VAR in "${MANPAGE_VARS[@]}"
|
|
do
|
|
# Skip if variable value is empty.
|
|
[[ -z "${!VAR:-}" ]] && continue
|
|
|
|
VAR_NEW="HOMEBREW_${VAR}"
|
|
# Skip if existing HOMEBREW_* variable is set.
|
|
[[ -n "${!VAR_NEW:-}" ]] && continue
|
|
export "${VAR_NEW}"="${!VAR}"
|
|
done
|
|
|
|
# We don't want to take the user's value for, e.g., `HOMEBREW_PATH` here!
|
|
USED_BY_HOMEBREW_VARS=(
|
|
CODESPACES
|
|
DBUS_SESSION_BUS_ADDRESS
|
|
PATH
|
|
TMUX
|
|
XDG_RUNTIME_DIR
|
|
)
|
|
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
|
|
|
|
export HOMEBREW_BREW_FILE
|
|
export HOMEBREW_PREFIX
|
|
export HOMEBREW_REPOSITORY
|
|
export HOMEBREW_LIBRARY
|
|
|
|
# set from user environment
|
|
# shellcheck disable=SC2154
|
|
# Use VISUAL if HOMEBREW_EDITOR and EDITOR are unset.
|
|
if [[ -z "${HOMEBREW_EDITOR:-}" && -n "${VISUAL:-}" ]]
|
|
then
|
|
export HOMEBREW_EDITOR="${VISUAL}"
|
|
fi
|
|
|
|
# set from user environment
|
|
# shellcheck disable=SC2154
|
|
# Set CI variable for Azure Pipelines and Jenkins
|
|
# (Set by default on GitHub Actions, Circle and Travis CI)
|
|
if [[ -z "${CI:-}" ]] && [[ -n "${TF_BUILD:-}" || -n "${JENKINS_HOME:-}" ]]
|
|
then
|
|
export CI="1"
|
|
fi
|
|
|
|
# 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
|
|
GITHUB_ACTIONS GITHUB_WORKSPACE GITHUB_ACTIONS_HOMEBREW_SELF_HOSTED
|
|
GITHUB_REPOSITORY GITHUB_RUN_ID GITHUB_RUN_ATTEMPT GITHUB_SHA GITHUB_HEAD_REF GITHUB_BASE_REF GITHUB_REF GITHUB_OUTPUT
|
|
)
|
|
# Filter all but the specific variables.
|
|
for VAR in "${ENV_VAR_NAMES[@]}" "${!HOMEBREW_@}"
|
|
do
|
|
# Skip if variable value is empty.
|
|
[[ -z "${!VAR:-}" ]] && continue
|
|
|
|
FILTERED_ENV+=("${VAR}=${!VAR}")
|
|
done
|
|
unset VAR ENV_VAR_NAMES
|
|
|
|
exec /usr/bin/env -i "${FILTERED_ENV[@]}" /bin/bash "${HOMEBREW_LIBRARY}/Homebrew/brew.sh" "$@"
|