Merge pull request #17037 from Homebrew/more_forbidden

Add more `HOMEBREW_FORBIDDEN_*` configuration
This commit is contained in:
Mike McQuaid 2024-04-08 17:33:47 +01:00 committed by GitHub
commit 3c910b94c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 585 additions and 41 deletions

View File

@ -71,6 +71,9 @@ module Cask
download(quiet:, timeout:)
satisfy_cask_and_formula_dependencies
forbidden_tap_check
forbidden_cask_and_formula_check
end
def stage
@ -571,6 +574,107 @@ on_request: true)
gain_permissions_remove(@cask.caskroom_path)
end
sig { void }
def forbidden_tap_check
forbidden_taps = Homebrew::EnvConfig.forbidden_taps
return if forbidden_taps.blank?
forbidden_taps_set = Set.new(forbidden_taps.split.filter_map do |tap|
Tap.fetch(tap)
rescue Tap::InvalidNameError
opoo "Invalid tap name in `HOMEBREW_FORBIDDEN_TAPS`: #{tap}"
nil
end)
owner = Homebrew::EnvConfig.forbidden_owner
owner_contact = if (contact = Homebrew::EnvConfig.forbidden_owner_contact.presence)
"\n#{contact}"
end
unless skip_cask_deps?
cask_and_formula_dependencies.each do |cask_or_formula|
dep_tap = cask_or_formula.tap
next if dep_tap.blank?
next unless forbidden_taps_set.include?(dep_tap)
dep_full_name = cask_or_formula.full_name
raise CaskCannotBeInstalledError.new(@cask, <<~EOS
The installation of #{@cask} has a dependency #{dep_full_name}
but the #{dep_tap} tap was forbidden by #{owner} in `HOMEBREW_FORBIDDEN_TAPS`.#{owner_contact}
EOS
)
end
end
cask_tap = @cask.tap
return if cask_tap.blank?
return unless forbidden_taps_set.include?(cask_tap)
raise CaskCannotBeInstalledError.new(@cask, <<~EOS
The installation of #{@cask.full_name} has the tap #{cask_tap}
which was forbidden by #{owner} in `HOMEBREW_FORBIDDEN_TAPS`.#{owner_contact}
EOS
)
end
sig { void }
def forbidden_cask_and_formula_check
forbidden_formulae = Set.new(Homebrew::EnvConfig.forbidden_formulae.to_s.split)
forbidden_casks = Set.new(Homebrew::EnvConfig.forbidden_casks.to_s.split)
return if forbidden_formulae.blank? && forbidden_casks.blank?
owner = Homebrew::EnvConfig.forbidden_owner
owner_contact = if (contact = Homebrew::EnvConfig.forbidden_owner_contact.presence)
"\n#{contact}"
end
unless skip_cask_deps?
cask_and_formula_dependencies.each do |dep_cask_or_formula|
dep_name, dep_type, variable = if dep_cask_or_formula.is_a?(Cask) && forbidden_casks.present?
dep_cask = dep_cask_or_formula
dep_cask_name = if forbidden_casks.include?(dep_cask.token)
dep_cask.token
elsif dep_cask.tap.present? &&
forbidden_casks.include?(dep_cask.full_name)
dep_cask.full_name
end
[dep_cask_name, "cask", "HOMEBREW_FORBIDDEN_CASKS"]
elsif dep_cask_or_formula.is_a?(Formula) && forbidden_formulae.present?
dep_formula = dep_cask_or_formula
formula_name = if forbidden_formulae.include?(dep_formula.name)
dep_formula.name
elsif dep_formula.tap.present? &&
forbidden_formulae.include?(dep_formula.full_name)
dep_formula.full_name
end
[formula_name, "formula", "HOMEBREW_FORBIDDEN_FORMULAE"]
end
next if dep_name.blank?
raise CaskCannotBeInstalledError.new(@cask, <<~EOS
The installation of #{@cask} has a dependency #{dep_name}
but the #{dep_name} #{dep_type} was forbidden by #{owner} in `#{variable}`.#{owner_contact}
EOS
)
end
end
return if forbidden_casks.blank?
cask_name = if forbidden_casks.include?(@cask.token)
@cask.token
elsif forbidden_casks.include?(@cask.full_name)
@cask.full_name
else
return
end
raise CaskCannotBeInstalledError.new(@cask, <<~EOS
The installation of #{cask_name} was forbidden by #{owner}
in `HOMEBREW_FORBIDDEN_CASKS`.#{owner_contact}
EOS
)
end
private
# load the same cask file that was used for installation, if possible

View File

@ -185,10 +185,29 @@ module Homebrew
description: "Output this many lines of output on formula `system` failures.",
default: 15,
},
HOMEBREW_FORBIDDEN_CASKS: {
description: "A space-separated list of casks. Homebrew will refuse to install a " \
"cask if it or any of its dependencies is on this list.",
},
HOMEBREW_FORBIDDEN_FORMULAE: {
description: "A space-separated list of formulae. Homebrew will refuse to install a " \
"formula or cask if it or any of its dependencies is on this list.",
},
HOMEBREW_FORBIDDEN_LICENSES: {
description: "A space-separated list of licenses. Homebrew will refuse to install a " \
"formula if it or any of its dependencies has a license on this list.",
},
HOMEBREW_FORBIDDEN_OWNER: {
description: "The person who has set any `HOMEBREW_FORBIDDEN_*` variables.",
default: "you",
},
HOMEBREW_FORBIDDEN_OWNER_CONTACT: {
description: "How to contact the `HOMEBREW_FORBIDDEN_OWNER`, if set and necessary.",
},
HOMEBREW_FORBIDDEN_TAPS: {
description: "A space-separated list of taps. Homebrew will refuse to install a " \
"formula if it or any of its dependencies is in a tap on this list.",
},
HOMEBREW_FORCE_BREWED_CA_CERTIFICATES: {
description: "If set, always use a Homebrew-installed `ca-certificates` rather than the system version. " \
"Automatically set if the system version is too old.",

View File

@ -217,7 +217,10 @@ class FormulaInstaller
Tab.clear_cache
verify_deps_exist unless ignore_deps?
forbidden_license_check
forbidden_tap_check
forbidden_formula_check
check_install_sanity
install_fetch_deps unless ignore_deps?
@ -1315,6 +1318,134 @@ on_request: installed_on_request?, options:)
@locked ||= []
end
sig { void }
def forbidden_license_check
forbidden_licenses = Homebrew::EnvConfig.forbidden_licenses.to_s.dup
SPDX::ALLOWED_LICENSE_SYMBOLS.each do |s|
pattern = /#{s.to_s.tr("_", " ")}/i
forbidden_licenses.sub!(pattern, s.to_s)
end
forbidden_licenses = forbidden_licenses.split.to_h do |license|
[license, SPDX.license_version_info(license)]
end
return if forbidden_licenses.blank?
owner = Homebrew::EnvConfig.forbidden_owner
owner_contact = if (contact = Homebrew::EnvConfig.forbidden_owner_contact.presence)
"\n#{contact}"
end
unless ignore_deps?
compute_dependencies.each do |(dep, _options)|
dep_f = dep.to_formula
next unless SPDX.licenses_forbid_installation? dep_f.license, forbidden_licenses
raise CannotInstallFormulaError, <<~EOS
The installation of #{formula.name} has a dependency on #{dep.name} where all
its licenses were forbidden by #{owner} in `HOMEBREW_FORBIDDEN_LICENSES`:
#{SPDX.license_expression_to_string dep_f.license}.#{owner_contact}
EOS
end
end
return if only_deps?
return unless SPDX.licenses_forbid_installation? formula.license, forbidden_licenses
raise CannotInstallFormulaError, <<~EOS
#{formula.name}'s licenses are all forbidden by #{owner} in `HOMEBREW_FORBIDDEN_LICENSES`:
#{SPDX.license_expression_to_string formula.license}.#{owner_contact}
EOS
end
sig { void }
def forbidden_tap_check
forbidden_taps = Homebrew::EnvConfig.forbidden_taps
return if forbidden_taps.blank?
forbidden_taps_set = Set.new(forbidden_taps.split.filter_map do |tap|
Tap.fetch(tap)
rescue Tap::InvalidNameError
opoo "Invalid tap name in `HOMEBREW_FORBIDDEN_TAPS`: #{tap}"
nil
end)
owner = Homebrew::EnvConfig.forbidden_owner
owner_contact = if (contact = Homebrew::EnvConfig.forbidden_owner_contact.presence)
"\n#{contact}"
end
unless ignore_deps?
compute_dependencies.each do |(dep, _options)|
dep_tap = dep.tap
next if dep_tap.blank?
next unless forbidden_taps_set.include?(dep_tap)
raise CannotInstallFormulaError, <<~EOS
The installation of #{formula.name} has a dependency #{dep.name}
but the #{dep_tap} tap was forbidden by #{owner} in `HOMEBREW_FORBIDDEN_TAPS`.#{owner_contact}
EOS
end
end
return if only_deps?
formula_tap = formula.tap
return if formula_tap.blank?
return unless forbidden_taps_set.include?(formula_tap)
raise CannotInstallFormulaError, <<~EOS
The installation of #{formula.full_name} has the tap #{formula_tap}
which was forbidden by #{owner} in `HOMEBREW_FORBIDDEN_TAPS`.#{owner_contact}
EOS
end
sig { void }
def forbidden_formula_check
forbidden_formulae = Set.new(Homebrew::EnvConfig.forbidden_formulae.to_s.split)
return if forbidden_formulae.blank?
owner = Homebrew::EnvConfig.forbidden_owner
owner_contact = if (contact = Homebrew::EnvConfig.forbidden_owner_contact.presence)
"\n#{contact}"
end
unless ignore_deps?
compute_dependencies.each do |(dep, _options)|
dep_name = if forbidden_formulae.include?(dep.name)
dep.name
elsif dep.tap.present? &&
(dep_full_name = "#{dep.tap}/#{dep.name}") &&
forbidden_formulae.include?(dep_full_name)
dep_full_name
else
next
end
raise CannotInstallFormulaError, <<~EOS
The installation of #{formula.name} has a dependency #{dep_name}
but the #{dep_name} formula was forbidden by #{owner} in `HOMEBREW_FORBIDDEN_FORMULAE`.#{owner_contact}
EOS
end
end
return if only_deps?
formula_name = if forbidden_formulae.include?(formula.name)
formula.name
elsif forbidden_formulae.include?(formula.full_name)
formula.full_name
else
return
end
raise CannotInstallFormulaError, <<~EOS
The installation of #{formula_name} was forbidden by #{owner}
in `HOMEBREW_FORBIDDEN_FORMULAE`.#{owner_contact}
EOS
end
private
attr_predicate :hold_locks?
@ -1349,39 +1480,4 @@ on_request: installed_on_request?, options:)
$stderr.puts @requirement_messages
end
sig { void }
def forbidden_license_check
forbidden_licenses = Homebrew::EnvConfig.forbidden_licenses.to_s.dup
SPDX::ALLOWED_LICENSE_SYMBOLS.each do |s|
pattern = /#{s.to_s.tr("_", " ")}/i
forbidden_licenses.sub!(pattern, s.to_s)
end
forbidden_licenses = forbidden_licenses.split.to_h do |license|
[license, SPDX.license_version_info(license)]
end
return if forbidden_licenses.blank?
return if ignore_deps?
compute_dependencies.each do |(dep, _options)|
dep_f = dep.to_formula
next unless SPDX.licenses_forbid_installation? dep_f.license, forbidden_licenses
raise CannotInstallFormulaError, <<~EOS
The installation of #{formula.name} has a dependency on #{dep.name} where all
its licenses are forbidden by HOMEBREW_FORBIDDEN_LICENSES:
#{SPDX.license_expression_to_string dep_f.license}.
EOS
end
return if only_deps?
return unless SPDX.licenses_forbid_installation? formula.license, forbidden_licenses
raise CannotInstallFormulaError, <<~EOS
#{formula.name}'s licenses are all forbidden by HOMEBREW_FORBIDDEN_LICENSES:
#{SPDX.license_expression_to_string formula.license}.
EOS
end
end

View File

@ -105,9 +105,24 @@ module Homebrew::EnvConfig
sig { returns(Integer) }
def fail_log_lines; end
sig { returns(T.nilable(::String)) }
def forbidden_casks; end
sig { returns(T.nilable(::String)) }
def forbidden_formulae; end
sig { returns(T.nilable(::String)) }
def forbidden_licenses; end
sig { returns(String) }
def forbidden_owner; end
sig { returns(T.nilable(::String)) }
def forbidden_owner_contact; end
sig { returns(T.nilable(::String)) }
def forbidden_taps; end
sig { returns(T::Boolean) }
def force_brewed_ca_certificates?; end

View File

@ -39,12 +39,14 @@ class Tap
#{HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR}/*.json
].freeze
class InvalidNameError < ArgumentError; end
sig { params(user: String, repo: String).returns(Tap) }
def self.fetch(user, repo = T.unsafe(nil))
user, repo = user.split("/", 2) if repo.nil?
if [user, repo].any? { |part| part.nil? || part.include?("/") }
raise ArgumentError, "Invalid tap name: '#{[*user, *repo].join("/")}'"
raise InvalidNameError, "Invalid tap name: '#{[*user, *repo].join("/")}'"
end
user = T.must(user)

View File

@ -324,4 +324,77 @@ RSpec.describe Cask::Installer, :cask do
expect(Cask::CaskLoader.load(cask_path("local-caffeine"))).not_to be_installed
end
end
describe "#forbidden_tap_check" do
it "raises on forbidden tap on cask" do
ENV["HOMEBREW_FORBIDDEN_TAPS"] = tap = "homebrew/forbidden"
cask = Cask::Cask.new("homebrew-forbidden-tap", tap: Tap.fetch(tap)) do
url "file://#{TEST_FIXTURE_DIR}/cask/container.tar.gz"
end
expect do
described_class.new(cask).forbidden_tap_check
end.to raise_error(Cask::CaskCannotBeInstalledError, /has the tap #{tap}/)
end
it "raises on forbidden tap on dependency" do
ENV["HOMEBREW_FORBIDDEN_TAPS"] = dep_tap = "homebrew/forbidden"
dep_name = "homebrew-forbidden-dependency-tap"
dep_path = Tap.fetch(dep_tap).new_formula_path(dep_name)
dep_path.parent.mkpath
dep_path.write <<~RUBY
class #{Formulary.class_s(dep_name)} < Formula
url "foo"
version "0.1"
end
RUBY
Formulary.cache.delete(dep_path)
cask = Cask::Cask.new("homebrew-forbidden-dependent-tap") do
url "file://#{TEST_FIXTURE_DIR}/cask/container.tar.gz"
depends_on formula: dep_name
end
expect do
described_class.new(cask).forbidden_tap_check
end.to raise_error(Cask::CaskCannotBeInstalledError, /but the #{dep_tap} tap was forbidden/)
ensure
dep_path.parent.parent.rmtree
end
end
describe "#forbidden_cask_and_formula_check" do
it "raises on forbidden cask" do
ENV["HOMEBREW_FORBIDDEN_CASKS"] = cask_name = "homebrew-forbidden-cask"
cask = Cask::Cask.new(cask_name) do
url "file://#{TEST_FIXTURE_DIR}/cask/container.tar.gz"
end
expect do
described_class.new(cask).forbidden_cask_and_formula_check
end.to raise_error(Cask::CaskCannotBeInstalledError, /#{cask_name} was forbidden/)
end
it "raises on forbidden dependency" do
ENV["HOMEBREW_FORBIDDEN_FORMULAE"] = dep_name = "homebrew-forbidden-dependency-formula"
dep_path = CoreTap.instance.new_formula_path(dep_name)
dep_path.write <<~RUBY
class #{Formulary.class_s(dep_name)} < Formula
url "foo"
version "0.1"
end
RUBY
Formulary.cache.delete(dep_path)
cask = Cask::Cask.new("homebrew-forbidden-dependent-cask") do
url "file://#{TEST_FIXTURE_DIR}/cask/container.tar.gz"
depends_on formula: dep_name
end
expect do
described_class.new(cask).forbidden_cask_and_formula_check
end.to raise_error(Cask::CaskCannotBeInstalledError, /#{dep_name} formula was forbidden/)
end
end
end

View File

@ -312,7 +312,7 @@ RSpec.describe Homebrew::CLI::NamedArgs do
it "raises an error for invalid tap" do
taps = described_class.new("homebrew/foo", "barbaz")
expect { taps.to_taps }.to raise_error(ArgumentError, /Invalid tap name/)
expect { taps.to_taps }.to raise_error(Tap::InvalidNameError, /Invalid tap name/)
end
end
@ -333,7 +333,7 @@ RSpec.describe Homebrew::CLI::NamedArgs do
it "raises an error for invalid tap" do
taps = described_class.new("homebrew/foo", "barbaz")
expect { taps.to_installed_taps }.to raise_error(ArgumentError, /Invalid tap name/)
expect { taps.to_installed_taps }.to raise_error(Tap::InvalidNameError, /Invalid tap name/)
end
end
end

View File

@ -170,6 +170,197 @@ RSpec.describe FormulaInstaller do
end
end
describe "#forbidden_license_check" do
it "raises on forbidden license on formula" do
ENV["HOMEBREW_FORBIDDEN_LICENSES"] = "AGPL-3.0"
f_name = "homebrew-forbidden-license"
f_path = CoreTap.instance.new_formula_path(f_name)
f_path.write <<~RUBY
class #{Formulary.class_s(f_name)} < Formula
url "foo"
version "0.1"
license "AGPL-3.0"
end
RUBY
Formulary.cache.delete(f_path)
f = Formulary.factory(f_name)
fi = described_class.new(f)
expect do
fi.forbidden_license_check
end.to raise_error(CannotInstallFormulaError, /#{f_name}'s licenses are all forbidden/)
end
it "raises on forbidden license on formula with contact instructions" do
ENV["HOMEBREW_FORBIDDEN_LICENSES"] = "AGPL-3.0"
ENV["HOMEBREW_FORBIDDEN_OWNER"] = owner = "your dog"
ENV["HOMEBREW_FORBIDDEN_OWNER_CONTACT"] = contact = "Woof loudly to get this unblocked."
f_name = "homebrew-forbidden-license"
f_path = CoreTap.instance.new_formula_path(f_name)
f_path.write <<~RUBY
class #{Formulary.class_s(f_name)} < Formula
url "foo"
version "0.1"
license "AGPL-3.0"
end
RUBY
Formulary.cache.delete(f_path)
f = Formulary.factory(f_name)
fi = described_class.new(f)
expect do
fi.forbidden_license_check
end.to raise_error(CannotInstallFormulaError, /#{owner}.+\n#{contact}/m)
end
it "raises on forbidden license on dependency" do
ENV["HOMEBREW_FORBIDDEN_LICENSES"] = "GPL-3.0"
dep_name = "homebrew-forbidden-dependency-license"
dep_path = CoreTap.instance.new_formula_path(dep_name)
dep_path.write <<~RUBY
class #{Formulary.class_s(dep_name)} < Formula
url "foo"
version "0.1"
license "GPL-3.0"
end
RUBY
Formulary.cache.delete(dep_path)
f_name = "homebrew-forbidden-dependent-license"
f_path = CoreTap.instance.new_formula_path(f_name)
f_path.write <<~RUBY
class #{Formulary.class_s(f_name)} < Formula
url "foo"
version "0.1"
depends_on "#{dep_name}"
end
RUBY
Formulary.cache.delete(f_path)
f = Formulary.factory(f_name)
fi = described_class.new(f)
expect do
fi.forbidden_license_check
end.to raise_error(CannotInstallFormulaError, /dependency on #{dep_name} where all/)
end
end
describe "#forbidden_tap_check" do
it "raises on forbidden tap on formula" do
ENV["HOMEBREW_FORBIDDEN_TAPS"] = f_tap = "homebrew/forbidden"
f_name = "homebrew-forbidden-tap"
f_path = Tap.fetch(f_tap).new_formula_path(f_name)
f_path.parent.mkpath
f_path.write <<~RUBY
class #{Formulary.class_s(f_name)} < Formula
url "foo"
version "0.1"
end
RUBY
Formulary.cache.delete(f_path)
f = Formulary.factory("#{f_tap}/#{f_name}")
fi = described_class.new(f)
expect do
fi.forbidden_tap_check
end.to raise_error(CannotInstallFormulaError, /has the tap #{f_tap}/)
ensure
f_path.parent.parent.rmtree
end
it "raises on forbidden tap on dependency" do
ENV["HOMEBREW_FORBIDDEN_TAPS"] = dep_tap = "homebrew/forbidden"
dep_name = "homebrew-forbidden-dependency-tap"
dep_path = Tap.fetch(dep_tap).new_formula_path(dep_name)
dep_path.parent.mkpath
dep_path.write <<~RUBY
class #{Formulary.class_s(dep_name)} < Formula
url "foo"
version "0.1"
end
RUBY
Formulary.cache.delete(dep_path)
f_name = "homebrew-forbidden-dependent-tap"
f_path = CoreTap.instance.new_formula_path(f_name)
f_path.write <<~RUBY
class #{Formulary.class_s(f_name)} < Formula
url "foo"
version "0.1"
depends_on "#{dep_name}"
end
RUBY
Formulary.cache.delete(f_path)
f = Formulary.factory(f_name)
fi = described_class.new(f)
expect do
fi.forbidden_tap_check
end.to raise_error(CannotInstallFormulaError, /but the #{dep_tap} tap was forbidden/)
ensure
dep_path.parent.parent.rmtree
end
end
describe "#forbidden_formula_check" do
it "raises on forbidden formula" do
ENV["HOMEBREW_FORBIDDEN_FORMULAE"] = f_name = "homebrew-forbidden-formula"
f_path = CoreTap.instance.new_formula_path(f_name)
f_path.write <<~RUBY
class #{Formulary.class_s(f_name)} < Formula
url "foo"
version "0.1"
end
RUBY
Formulary.cache.delete(f_path)
f = Formulary.factory(f_name)
fi = described_class.new(f)
expect do
fi.forbidden_formula_check
end.to raise_error(CannotInstallFormulaError, /#{f_name} was forbidden/)
end
it "raises on forbidden dependency" do
ENV["HOMEBREW_FORBIDDEN_FORMULAE"] = dep_name = "homebrew-forbidden-dependency-formula"
dep_path = CoreTap.instance.new_formula_path(dep_name)
dep_path.write <<~RUBY
class #{Formulary.class_s(dep_name)} < Formula
url "foo"
version "0.1"
end
RUBY
Formulary.cache.delete(dep_path)
f_name = "homebrew-forbidden-dependent-formula"
f_path = CoreTap.instance.new_formula_path(f_name)
f_path.write <<~RUBY
class #{Formulary.class_s(f_name)} < Formula
url "foo"
version "0.1"
depends_on "#{dep_name}"
end
RUBY
Formulary.cache.delete(f_path)
f = Formulary.factory(f_name)
fi = described_class.new(f)
expect do
fi.forbidden_formula_check
end.to raise_error(CannotInstallFormulaError, /#{dep_name} formula was forbidden/)
end
end
specify "install fails with BuildError when a system() call fails" do
ENV["HOMEBREW_TEST_NO_EXIT_CLEANUP"] = "1"
ENV["FAILBALL_BUILD_ERROR"] = "1"

View File

@ -105,15 +105,15 @@ RSpec.describe Tap do
expect do
described_class.fetch("foo")
end.to raise_error(ArgumentError, /Invalid tap name/)
end.to raise_error(Tap::InvalidNameError, /Invalid tap name/)
expect do
described_class.fetch("homebrew/homebrew/bar")
end.to raise_error(ArgumentError, /Invalid tap name/)
end.to raise_error(Tap::InvalidNameError, /Invalid tap name/)
expect do
described_class.fetch("homebrew", "homebrew/baz")
end.to raise_error(ArgumentError, /Invalid tap name/)
end.to raise_error(Tap::InvalidNameError, /Invalid tap name/)
end
describe "::from_path" do

View File

@ -3647,11 +3647,36 @@ command execution e.g. `$(cat file)`.
*Default:* `15`.
`HOMEBREW_FORBIDDEN_CASKS`
: A space-separated list of casks. Homebrew will refuse to install a cask if it
or any of its dependencies is on this list.
`HOMEBREW_FORBIDDEN_FORMULAE`
: A space-separated list of formulae. Homebrew will refuse to install a formula
or cask if it or any of its dependencies is on this list.
`HOMEBREW_FORBIDDEN_LICENSES`
: A space-separated list of licenses. Homebrew will refuse to install a formula
if it or any of its dependencies has a license on this list.
`HOMEBREW_FORBIDDEN_OWNER`
: The person who has set any `HOMEBREW_FORBIDDEN_*` variables.
*Default:* `you`.
`HOMEBREW_FORBIDDEN_OWNER_CONTACT`
: How to contact the `HOMEBREW_FORBIDDEN_OWNER`, if set and necessary.
`HOMEBREW_FORBIDDEN_TAPS`
: A space-separated list of taps. Homebrew will refuse to install a formula if
it or any of its dependencies is in a tap on this list.
`HOMEBREW_FORCE_BREWED_CA_CERTIFICATES`
: If set, always use a Homebrew-installed `ca-certificates` rather than the

View File

@ -2368,9 +2368,28 @@ Output this many lines of output on formula \fBsystem\fP failures\.
\fIDefault:\fP \fB15\fP\&\.
.RE
.TP
\fBHOMEBREW_FORBIDDEN_CASKS\fP
A space\-separated list of casks\. Homebrew will refuse to install a cask if it or any of its dependencies is on this list\.
.TP
\fBHOMEBREW_FORBIDDEN_FORMULAE\fP
A space\-separated list of formulae\. Homebrew will refuse to install a formula or cask if it or any of its dependencies is on this list\.
.TP
\fBHOMEBREW_FORBIDDEN_LICENSES\fP
A space\-separated list of licenses\. Homebrew will refuse to install a formula if it or any of its dependencies has a license on this list\.
.TP
\fBHOMEBREW_FORBIDDEN_OWNER\fP
The person who has set any \fBHOMEBREW_FORBIDDEN_*\fP variables\.
.RS
.P
\fIDefault:\fP \fByou\fP\&\.
.RE
.TP
\fBHOMEBREW_FORBIDDEN_OWNER_CONTACT\fP
How to contact the \fBHOMEBREW_FORBIDDEN_OWNER\fP, if set and necessary\.
.TP
\fBHOMEBREW_FORBIDDEN_TAPS\fP
A space\-separated list of taps\. Homebrew will refuse to install a formula if it or any of its dependencies is in a tap on this list\.
.TP
\fBHOMEBREW_FORCE_BREWED_CA_CERTIFICATES\fP
If set, always use a Homebrew\-installed \fBca\-certificates\fP rather than the system version\. Automatically set if the system version is too old\.
.TP