mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Add support for Homebrew wrappers
Allow the ability for a system administrator to use `HOMEBREW_BREW_WRAPPER` and `HOMEBREW_FORCE_BREW_WRAPPER` variables to enforce the usage of a particular `brew` command for non-trivial (e.g. `brew --prefix` is considered trivial, it doesn't need to write to the prefix) Homebrew commands. This also introduces a `HOMEBREW_ORIGINAL_BREW_FILE` variable for some internal usage; `HOMEBREW_BREW_FILE` was being used internally for both "how should we shell out to Homebrew" and "what should we use to check permissions on Homebrew". `HOMEBREW_ORIGINAL_BREW_FILE` is now used just for the latter case. Inspired by conversation in https://github.com/Homebrew/homebrew-bundle/pull/1551 which suggested this was worth fixing in wider than just `brew bundle`.
This commit is contained in:
parent
d87d336c82
commit
e9b4979f40
@ -127,12 +127,6 @@ case "$1" in
|
||||
homebrew-shellenv "$1"
|
||||
exit 0
|
||||
;;
|
||||
setup-ruby)
|
||||
source "${HOMEBREW_LIBRARY}/Homebrew/cmd/setup-ruby.sh"
|
||||
shift
|
||||
homebrew-setup-ruby "$1"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
source "${HOMEBREW_LIBRARY}/Homebrew/help.sh"
|
||||
@ -184,11 +178,56 @@ case "$@" in
|
||||
;;
|
||||
esac
|
||||
|
||||
#####
|
||||
##### Next, define all helper functions.
|
||||
#####
|
||||
# Include some helper functions.
|
||||
source "${HOMEBREW_LIBRARY}/Homebrew/utils/helpers.sh"
|
||||
|
||||
# Require HOMEBREW_BREW_WRAPPER to be set if HOMEBREW_FORCE_BREW_WRAPPER is set
|
||||
# for all non-trivial commands (i.e. not run above).
|
||||
if [[ -n "${HOMEBREW_FORCE_BREW_WRAPPER}" ]]
|
||||
then
|
||||
if [[ -z "${HOMEBREW_BREW_WRAPPER:-}" ]]
|
||||
then
|
||||
odie <<EOS
|
||||
HOMEBREW_FORCE_BREW_WRAPPER was set to
|
||||
${HOMEBREW_FORCE_BREW_WRAPPER}
|
||||
but HOMEBREW_BREW_WRAPPER was unset. This indicates that you are running
|
||||
${HOMEBREW_BREW_FILE}
|
||||
directly but should instead run
|
||||
${HOMEBREW_FORCE_BREW_WRAPPER}
|
||||
EOS
|
||||
elif [[ "${HOMEBREW_FORCE_BREW_WRAPPER:-}" != "${HOMEBREW_BREW_WRAPPER:-}" ]]
|
||||
then
|
||||
odie <<EOS
|
||||
HOMEBREW_FORCE_BREW_WRAPPER was set to
|
||||
${HOMEBREW_FORCE_BREW_WRAPPER}
|
||||
but HOMEBREW_BREW_WRAPPER was set to
|
||||
${HOMEBREW_BREW_WRAPPER}
|
||||
This indicates that you are running
|
||||
${HOMEBREW_BREW_FILE}
|
||||
directly but should instead run:
|
||||
${HOMEBREW_FORCE_BREW_WRAPPER}
|
||||
EOS
|
||||
fi
|
||||
fi
|
||||
|
||||
# commands that take a single or no arguments and need to write to HOMEBREW_PREFIX.
|
||||
# HOMEBREW_LIBRARY set by bin/brew
|
||||
# shellcheck disable=SC2154
|
||||
# doesn't need a default case as other arguments handled elsewhere.
|
||||
# shellcheck disable=SC2249
|
||||
case "$1" in
|
||||
setup-ruby)
|
||||
source "${HOMEBREW_LIBRARY}/Homebrew/cmd/setup-ruby.sh"
|
||||
shift
|
||||
homebrew-setup-ruby "$1"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
#####
|
||||
##### Next, define all other helper functions.
|
||||
#####
|
||||
|
||||
check-run-command-as-root() {
|
||||
[[ "${EUID}" == 0 || "${UID}" == 0 ]] || return
|
||||
|
||||
|
@ -87,6 +87,9 @@ module Homebrew
|
||||
description: "Use this URL as the Homebrew/brew `git`(1) remote.",
|
||||
default: HOMEBREW_BREW_DEFAULT_GIT_REMOTE,
|
||||
},
|
||||
HOMEBREW_BREW_WRAPPER: {
|
||||
description: "If set, use wrapper to call `brew` rather than auto-detecting it.",
|
||||
},
|
||||
HOMEBREW_BROWSER: {
|
||||
description: "Use this as the browser when opening project homepages.",
|
||||
default_text: "`$BROWSER` or the OS's default browser.",
|
||||
@ -242,6 +245,10 @@ module Homebrew
|
||||
"Automatically set if the system version of `git` is too old.",
|
||||
boolean: true,
|
||||
},
|
||||
HOMEBREW_FORCE_BREW_WRAPPER: {
|
||||
description: "If set, require `HOMEBREW_BREW_WRAPPER` to be set to the same value as " \
|
||||
"`HOMEBREW_FORCE_BREW_WRAPPER` for non-trivial `brew` commands.",
|
||||
},
|
||||
HOMEBREW_FORCE_VENDOR_RUBY: {
|
||||
description: "If set, always use Homebrew's vendored, relocatable Ruby version even if the system version " \
|
||||
"of Ruby is new enough.",
|
||||
|
@ -1499,7 +1499,7 @@ class Formula
|
||||
# @see .link_overwrite
|
||||
def link_overwrite?(path)
|
||||
# Don't overwrite files not created by Homebrew.
|
||||
return false if path.stat.uid != HOMEBREW_BREW_FILE.stat.uid
|
||||
return false if path.stat.uid != HOMEBREW_ORIGINAL_BREW_FILE.stat.uid
|
||||
|
||||
# Don't overwrite files belong to other keg except when that
|
||||
# keg's formula is deleted.
|
||||
|
@ -100,7 +100,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
def owner_uid
|
||||
@owner_uid ||= HOMEBREW_BREW_FILE.stat.uid
|
||||
@owner_uid ||= HOMEBREW_ORIGINAL_BREW_FILE.stat.uid
|
||||
end
|
||||
|
||||
def running_as_root_but_not_owned_by_root?
|
||||
|
@ -67,8 +67,8 @@ class Mktemp
|
||||
# Reference from `man 2 open`
|
||||
# > When a new file is created, it is given the group of the directory which
|
||||
# contains it.
|
||||
group_id = if HOMEBREW_BREW_FILE.grpowned?
|
||||
HOMEBREW_BREW_FILE.stat.gid
|
||||
group_id = if HOMEBREW_ORIGINAL_BREW_FILE.grpowned?
|
||||
HOMEBREW_ORIGINAL_BREW_FILE.stat.gid
|
||||
else
|
||||
Process.gid
|
||||
end
|
||||
|
@ -103,7 +103,7 @@ class Sandbox
|
||||
|
||||
sig { void }
|
||||
def deny_write_homebrew_repository
|
||||
deny_write path: HOMEBREW_BREW_FILE
|
||||
deny_write path: HOMEBREW_ORIGINAL_BREW_FILE
|
||||
if HOMEBREW_PREFIX.to_s == HOMEBREW_REPOSITORY.to_s
|
||||
deny_write_path HOMEBREW_LIBRARY
|
||||
deny_write_path HOMEBREW_REPOSITORY/".git"
|
||||
|
@ -49,6 +49,9 @@ module Homebrew::EnvConfig
|
||||
sig { returns(String) }
|
||||
def brew_git_remote; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def brew_wrapper; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def browser; end
|
||||
|
||||
@ -139,6 +142,9 @@ module Homebrew::EnvConfig
|
||||
sig { returns(T::Boolean) }
|
||||
def force_api_auto_update?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def force_brew_wrapper?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def force_brewed_ca_certificates?; end
|
||||
|
||||
|
@ -4,6 +4,11 @@
|
||||
raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!" unless ENV["HOMEBREW_BREW_FILE"]
|
||||
|
||||
# Path to `bin/brew` main executable in `HOMEBREW_PREFIX`
|
||||
# Used for e.g. permissions checks.
|
||||
HOMEBREW_ORIGINAL_BREW_FILE = Pathname(ENV.fetch("HOMEBREW_ORIGINAL_BREW_FILE")).freeze
|
||||
|
||||
# Path to the executable that should be used to run `brew`.
|
||||
# This may be HOMEBREW_ORIGINAL_BREW_FILE or HOMEBREW_BREW_WRAPPER.
|
||||
HOMEBREW_BREW_FILE = Pathname(ENV.fetch("HOMEBREW_BREW_FILE")).freeze
|
||||
|
||||
# Where we link under
|
||||
|
@ -304,7 +304,7 @@ module Homebrew
|
||||
|
||||
def self.shell_scripts
|
||||
[
|
||||
HOMEBREW_BREW_FILE,
|
||||
HOMEBREW_ORIGINAL_BREW_FILE,
|
||||
HOMEBREW_REPOSITORY/"completions/bash/brew",
|
||||
HOMEBREW_REPOSITORY/"Dockerfile",
|
||||
*HOMEBREW_REPOSITORY.glob(".devcontainer/**/*.sh"),
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!" unless ENV["HOMEBREW_BREW_FILE"]
|
||||
|
||||
HOMEBREW_ORIGINAL_BREW_FILE = Pathname.new(ENV.fetch("HOMEBREW_ORIGINAL_BREW_FILE")).freeze
|
||||
HOMEBREW_BREW_FILE = Pathname.new(ENV.fetch("HOMEBREW_BREW_FILE")).freeze
|
||||
|
||||
TEST_TMPDIR = ENV.fetch("HOMEBREW_TEST_TMPDIR") do |k|
|
||||
|
35
bin/brew
35
bin/brew
@ -116,6 +116,23 @@ unset BREW_FILE_DIRECTORY
|
||||
# keg_relocate.rb, formula_cellar_checks.rb, and test/global_spec.rb need to change.
|
||||
HOMEBREW_LIBRARY="${HOMEBREW_REPOSITORY}/Library"
|
||||
|
||||
# Use HOMEBREW_BREW_WRAPPER if set.
|
||||
export HOMEBREW_ORIGINAL_BREW_FILE="${HOMEBREW_BREW_FILE}"
|
||||
if [[ -n "${HOMEBREW_BREW_WRAPPER:-}" ]]
|
||||
then
|
||||
HOMEBREW_BREW_FILE="${HOMEBREW_BREW_WRAPPER}"
|
||||
fi
|
||||
|
||||
# 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
|
||||
)
|
||||
|
||||
# Load Homebrew's variable configuration files from disk.
|
||||
export_homebrew_env_file() {
|
||||
local env_file
|
||||
@ -126,6 +143,15 @@ export_homebrew_env_file() {
|
||||
do
|
||||
# only load HOMEBREW_* lines
|
||||
[[ "${line}" = "HOMEBREW_"* ]] || continue
|
||||
|
||||
# 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
|
||||
[[ -n "${invalid_variable}" ]] && continue
|
||||
|
||||
export "${line?}"
|
||||
done <"${env_file}"
|
||||
}
|
||||
@ -212,11 +238,10 @@ done
|
||||
|
||||
unset VAR VAR_NEW MANPAGE_VARS USED_BY_HOMEBREW_VARS
|
||||
|
||||
export HOMEBREW_BREW_FILE
|
||||
export HOMEBREW_PREFIX
|
||||
export HOMEBREW_REPOSITORY
|
||||
export HOMEBREW_LIBRARY
|
||||
export HOMEBREW_USER_CONFIG_HOME
|
||||
for VAR in "${BIN_BREW_EXPORTED_VARS[@]}"
|
||||
do
|
||||
export "${VAR?}"
|
||||
done
|
||||
|
||||
# set from user environment
|
||||
# shellcheck disable=SC2154
|
||||
|
Loading…
x
Reference in New Issue
Block a user