Merge branch 'master' into mohammad

This commit is contained in:
Mohammad Zain Abbas 2022-06-30 17:50:50 +02:00
commit dbfbd19674
344 changed files with 1614 additions and 762 deletions

View File

@ -107,7 +107,6 @@ jobs:
brew tap homebrew/cask-versions brew tap homebrew/cask-versions
brew tap homebrew/command-not-found brew tap homebrew/command-not-found
brew tap homebrew/formula-analytics brew tap homebrew/formula-analytics
brew tap homebrew/linux-dev
brew tap homebrew/portable-ruby brew tap homebrew/portable-ruby
brew tap homebrew/services brew tap homebrew/services
@ -136,7 +135,6 @@ jobs:
homebrew/autoupdate\ homebrew/autoupdate\
homebrew/command-not-found \ homebrew/command-not-found \
homebrew/formula-analytics \ homebrew/formula-analytics \
homebrew/linux-dev \
homebrew/portable-ruby homebrew/portable-ruby
- name: Run brew style on cask taps - name: Run brew style on cask taps

View File

@ -23,7 +23,7 @@ jobs:
steps: steps:
- name: Re-run this workflow - name: Re-run this workflow
if: github.event_name == 'schedule' || github.event.action == 'closed' if: github.event_name == 'schedule' || github.event.action == 'closed'
uses: reitermarkus/rerun-workflow@cd46218e13bd336b1c551c6ef4dc82aa5316facf uses: reitermarkus/rerun-workflow@c8d5bc3526acb50c12004f31c0dcb1598c87e32d
with: with:
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }} token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
continuous-label: waiting for feedback continuous-label: waiting for feedback
@ -35,7 +35,7 @@ jobs:
github.event.action != 'closed' && github.event.pull_request.state != 'closed' github.event.action != 'closed' && github.event.pull_request.state != 'closed'
uses: actions/github-script@v6 uses: actions/github-script@v6
with: with:
github-token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }} github-token: ${{ secrets.HOMEBREW_BREW_TRIAGE_PULL_REQUESTS_TOKEN }}
script: | script: |
async function approvePullRequest(pullRequestNumber) { async function approvePullRequest(pullRequestNumber) {
const reviews = await approvalsByAuthenticatedUser(pullRequestNumber) const reviews = await approvalsByAuthenticatedUser(pullRequestNumber)

View File

@ -13,6 +13,7 @@ inherit_mode:
AllCops: AllCops:
TargetRubyVersion: 2.6 TargetRubyVersion: 2.6
DisplayCopNames: false DisplayCopNames: false
ActiveSupportExtensionsEnabled: true
# enable all pending rubocops # enable all pending rubocops
NewCops: enable NewCops: enable
Include: Include:
@ -97,7 +98,7 @@ Naming/InclusiveLanguage:
- "patches/13_fix_scope_for_show_slave_status_data.patch" # Used in formula `mytop` - "patches/13_fix_scope_for_show_slave_status_data.patch" # Used in formula `mytop`
Naming/MethodName: Naming/MethodName:
IgnoredPatterns: AllowedPatterns:
- '\A(fetch_)?HEAD\?\Z' - '\A(fetch_)?HEAD\?\Z'
# Both styles are used depending on context, # Both styles are used depending on context,
@ -122,6 +123,14 @@ Style/BarePercentLiterals:
Style/CollectionMethods: Style/CollectionMethods:
Enabled: true Enabled: true
# This is quite a large change, so don't enforce this yet for formulae.
# We should consider doing so in the future, but be aware of the impact on third-party taps.
Style/FetchEnvVar:
Exclude:
- "Taps/*/*/*.rb"
- "/**/Formula/*.rb"
- "**/Formula/*.rb"
# Prefer tokens with type annotations for consistency # Prefer tokens with type annotations for consistency
# between formatting numbers and strings. # between formatting numbers and strings.
Style/FormatStringToken: Style/FormatStringToken:
@ -389,7 +398,7 @@ Naming/MethodParameterName:
Layout/LineLength: Layout/LineLength:
Max: 118 Max: 118
# ignore manpage comments and long single-line strings # ignore manpage comments and long single-line strings
IgnoredPatterns: AllowedPatterns:
[ [
"#: ", "#: ",
' url "', ' url "',

View File

@ -35,6 +35,7 @@ GEM
domain_name (~> 0.5) domain_name (~> 0.5)
i18n (1.10.0) i18n (1.10.0)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
json (2.6.2)
json_schemer (0.2.21) json_schemer (0.2.21)
ecma-re-validator (~> 0.3) ecma-re-validator (~> 0.3)
hana (~> 1.3) hana (~> 1.3)
@ -56,7 +57,7 @@ GEM
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2022.0105) mime-types-data (3.2022.0105)
mini_portile2 (2.8.0) mini_portile2 (2.8.0)
minitest (5.16.0) minitest (5.16.1)
msgpack (1.5.2) msgpack (1.5.2)
mustache (1.1.1) mustache (1.1.1)
net-http-digest_auth (1.4.1) net-http-digest_auth (1.4.1)
@ -66,7 +67,7 @@ GEM
mini_portile2 (~> 2.8.0) mini_portile2 (~> 2.8.0)
racc (~> 1.4) racc (~> 1.4)
parallel (1.22.1) parallel (1.22.1)
parallel_tests (3.11.0) parallel_tests (3.11.1)
parallel parallel
parlour (8.0.0) parlour (8.0.0)
commander (~> 4.5) commander (~> 4.5)
@ -123,13 +124,14 @@ GEM
rspec (>= 3, < 4) rspec (>= 3, < 4)
rspec_junit_formatter (0.5.1) rspec_junit_formatter (0.5.1)
rspec-core (>= 2, < 4, != 2.12.0) rspec-core (>= 2, < 4, != 2.12.0)
rubocop (1.27.0) rubocop (1.31.1)
json (~> 2.3)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 3.1.0.0) parser (>= 3.1.0.0)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0) regexp_parser (>= 1.8, < 3.0)
rexml rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.16.0, < 2.0) rubocop-ast (>= 1.18.0, < 2.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0) unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.18.0) rubocop-ast (1.18.0)
@ -137,13 +139,13 @@ GEM
rubocop-performance (1.14.2) rubocop-performance (1.14.2)
rubocop (>= 1.7.0, < 2.0) rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0) rubocop-ast (>= 0.4.0)
rubocop-rails (2.15.0) rubocop-rails (2.15.1)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
rack (>= 1.1) rack (>= 1.1)
rubocop (>= 1.7.0, < 2.0) rubocop (>= 1.7.0, < 2.0)
rubocop-rspec (2.11.1) rubocop-rspec (2.11.1)
rubocop (~> 1.19) rubocop (~> 1.19)
rubocop-sorbet (0.6.8) rubocop-sorbet (0.6.10)
rubocop (>= 0.90.0) rubocop (>= 0.90.0)
ruby-macho (3.0.0) ruby-macho (3.0.0)
ruby-progressbar (1.11.0) ruby-progressbar (1.11.0)
@ -157,14 +159,14 @@ GEM
simplecov (~> 0.19) simplecov (~> 0.19)
simplecov-html (0.12.3) simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4) simplecov_json_formatter (0.1.4)
sorbet (0.5.10097) sorbet (0.5.10132)
sorbet-static (= 0.5.10097) sorbet-static (= 0.5.10132)
sorbet-runtime (0.5.10097) sorbet-runtime (0.5.10132)
sorbet-runtime-stub (0.2.0) sorbet-runtime-stub (0.2.0)
sorbet-static (0.5.10097-universal-darwin-14) sorbet-static (0.5.10132-universal-darwin-14)
sorbet-static-and-runtime (0.5.10097) sorbet-static-and-runtime (0.5.10132)
sorbet (= 0.5.10097) sorbet (= 0.5.10132)
sorbet-runtime (= 0.5.10097) sorbet-runtime (= 0.5.10132)
spoom (1.1.11) spoom (1.1.11)
sorbet (>= 0.5.9204) sorbet (>= 0.5.9204)
sorbet-runtime (>= 0.5.9204) sorbet-runtime (>= 0.5.9204)
@ -184,7 +186,7 @@ GEM
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
unf_ext (0.0.8.2) unf_ext (0.0.8.2)
unicode-display_width (2.1.0) unicode-display_width (2.2.0)
unparser (0.6.4) unparser (0.6.4)
diff-lcs (~> 1.3) diff-lcs (~> 1.3)
parser (>= 3.1.0) parser (>= 3.1.0)

View File

@ -11,35 +11,14 @@ raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!" unle
std_trap = trap("INT") { exit! 130 } # no backtrace thanks std_trap = trap("INT") { exit! 130 } # no backtrace thanks
# check ruby version before requiring any modules. # check ruby version before requiring any modules.
unless ENV["HOMEBREW_REQUIRED_RUBY_VERSION"] REQUIRED_RUBY_X, REQUIRED_RUBY_Y, = ENV.fetch("HOMEBREW_REQUIRED_RUBY_VERSION").split(".").map(&:to_i)
raise "HOMEBREW_REQUIRED_RUBY_VERSION was not exported! Please call bin/brew directly!"
end
REQUIRED_RUBY_X, REQUIRED_RUBY_Y, = ENV["HOMEBREW_REQUIRED_RUBY_VERSION"].split(".").map(&:to_i)
RUBY_X, RUBY_Y, = RUBY_VERSION.split(".").map(&:to_i) RUBY_X, RUBY_Y, = RUBY_VERSION.split(".").map(&:to_i)
if RUBY_X < REQUIRED_RUBY_X || (RUBY_X == REQUIRED_RUBY_X && RUBY_Y < REQUIRED_RUBY_Y) if RUBY_X < REQUIRED_RUBY_X || (RUBY_X == REQUIRED_RUBY_X && RUBY_Y < REQUIRED_RUBY_Y)
raise "Homebrew must be run under Ruby #{REQUIRED_RUBY_X}.#{REQUIRED_RUBY_Y}! " \ raise "Homebrew must be run under Ruby #{REQUIRED_RUBY_X}.#{REQUIRED_RUBY_Y}! " \
"You're running #{RUBY_VERSION}." "You're running #{RUBY_VERSION}."
end end
# Also define here so we can rescue regardless of location. require_relative "global"
class MissingEnvironmentVariables < RuntimeError; end
begin
require_relative "global"
rescue MissingEnvironmentVariables => e
raise e if ENV["HOMEBREW_MISSING_ENV_RETRY"]
if ENV["HOMEBREW_DEVELOPER"]
$stderr.puts <<~EOS
Warning: #{e.message}
Retrying with `exec #{ENV["HOMEBREW_BREW_FILE"]}`!
EOS
end
ENV["HOMEBREW_MISSING_ENV_RETRY"] = "1"
exec ENV["HOMEBREW_BREW_FILE"], *ARGV
end
begin begin
trap("INT", std_trap) # restore default CTRL-C handler trap("INT", std_trap) # restore default CTRL-C handler
@ -74,8 +53,8 @@ begin
args = Homebrew::CLI::Parser.new.parse(ARGV.dup.freeze, ignore_invalid_options: true) args = Homebrew::CLI::Parser.new.parse(ARGV.dup.freeze, ignore_invalid_options: true)
Context.current = args.context Context.current = args.context
path = PATH.new(ENV["PATH"]) path = PATH.new(ENV.fetch("PATH"))
homebrew_path = PATH.new(ENV["HOMEBREW_PATH"]) homebrew_path = PATH.new(ENV.fetch("HOMEBREW_PATH"))
# Add shared wrappers. # Add shared wrappers.
path.prepend(HOMEBREW_SHIMS_PATH/"shared") path.prepend(HOMEBREW_SHIMS_PATH/"shared")
@ -107,6 +86,10 @@ begin
end end
if internal_cmd || Commands.external_ruby_v2_cmd_path(cmd) if internal_cmd || Commands.external_ruby_v2_cmd_path(cmd)
if Commands::INSTALL_FROM_API_FORBIDDEN_COMMANDS.include?(cmd) && Homebrew::EnvConfig.install_from_api?
odie "This command cannot be run while HOMEBREW_INSTALL_FROM_API is set!"
end
Homebrew.send Commands.method_name(cmd) Homebrew.send Commands.method_name(cmd)
elsif (path = Commands.external_ruby_cmd_path(cmd)) elsif (path = Commands.external_ruby_cmd_path(cmd))
require?(path) require?(path)

View File

@ -734,7 +734,7 @@ then
fi fi
export HOMEBREW_BREW_GIT_REMOTE export HOMEBREW_BREW_GIT_REMOTE
HOMEBREW_CORE_DEFAULT_GIT_REMOTE="https://github.com/Homebrew/homebrew-core" export HOMEBREW_CORE_DEFAULT_GIT_REMOTE="https://github.com/Homebrew/homebrew-core"
if [[ -z "${HOMEBREW_CORE_GIT_REMOTE}" ]] if [[ -z "${HOMEBREW_CORE_GIT_REMOTE}" ]]
then then
HOMEBREW_CORE_GIT_REMOTE="${HOMEBREW_CORE_DEFAULT_GIT_REMOTE}" HOMEBREW_CORE_GIT_REMOTE="${HOMEBREW_CORE_DEFAULT_GIT_REMOTE}"
@ -748,34 +748,6 @@ then
export HOMEBREW_DEVELOPER_COMMAND="1" export HOMEBREW_DEVELOPER_COMMAND="1"
fi fi
# Set HOMEBREW_DEVELOPER_MODE if this command will turn (or keep) developer mode on. This is the case if:
# - The command being run is not `brew developer off`
# - Any of the following are true
# - HOMEBREW_DEVELOPER is set
# - HOMEBREW_DEV_CMD_RUN is set
# - A developer command is being run
# - The command being run is `brew developer on`
if [[ "${HOMEBREW_COMMAND}" != "developer" || ! $* =~ "off" ]] &&
[[ -n "${HOMEBREW_DEVELOPER}" ||
-n "${HOMEBREW_DEV_CMD_RUN}" ||
-n "${HOMEBREW_DEVELOPER_COMMAND}" ||
"${HOMEBREW_COMMAND}" == "developer" && $* =~ "on" ]]
then
export HOMEBREW_DEVELOPER_MODE="1"
fi
if [[ -n "${HOMEBREW_INSTALL_FROM_API}" && -n "${HOMEBREW_DEVELOPER_COMMAND}" && "${HOMEBREW_COMMAND}" != "irb" ]]
then
odie "Developer commands cannot be run while HOMEBREW_INSTALL_FROM_API is set!"
elif [[ -n "${HOMEBREW_INSTALL_FROM_API}" && -n "${HOMEBREW_DEVELOPER_MODE}" ]]
then
message="Developers should not have HOMEBREW_INSTALL_FROM_API set!
Please unset HOMEBREW_INSTALL_FROM_API or turn developer mode off by running:
brew developer off
"
opoo "${message}"
fi
if [[ -n "${HOMEBREW_DEVELOPER_COMMAND}" && -z "${HOMEBREW_DEVELOPER}" ]] if [[ -n "${HOMEBREW_DEVELOPER_COMMAND}" && -z "${HOMEBREW_DEVELOPER}" ]]
then then
if [[ -z "${HOMEBREW_DEV_CMD_RUN}" ]] if [[ -z "${HOMEBREW_DEV_CMD_RUN}" ]]

View File

@ -106,7 +106,7 @@ module Cask
+"/Library/LaunchAgents/#{service}.plist", +"/Library/LaunchAgents/#{service}.plist",
+"/Library/LaunchDaemons/#{service}.plist", +"/Library/LaunchDaemons/#{service}.plist",
] ]
paths.each { |elt| elt.prepend(ENV["HOME"]).freeze } unless with_sudo paths.each { |elt| elt.prepend(Dir.home).freeze } unless with_sudo
paths = paths.map { |elt| Pathname(elt) }.select(&:exist?) paths = paths.map { |elt| Pathname(elt) }.select(&:exist?)
paths.each do |path| paths.each do |path|
command.run!("/bin/rm", args: ["-f", "--", path], sudo: with_sudo) command.run!("/bin/rm", args: ["-f", "--", path], sudo: with_sudo)

View File

@ -39,7 +39,7 @@ module Cask
executable_path, executable_path,
**args, **args,
env: { "PATH" => PATH.new( env: { "PATH" => PATH.new(
HOMEBREW_PREFIX/"bin", HOMEBREW_PREFIX/"sbin", ENV["PATH"] HOMEBREW_PREFIX/"bin", HOMEBREW_PREFIX/"sbin", ENV.fetch("PATH")
) }, ) },
) )
end end

View File

@ -96,7 +96,7 @@ module Cask
end end
def printable_target def printable_target
target.to_s.sub(/^#{ENV['HOME']}(#{File::SEPARATOR}|$)/, "~/") target.to_s.sub(/^#{Dir.home}(#{File::SEPARATOR}|$)/, "~/")
end end
end end
end end

View File

@ -308,6 +308,7 @@ module Cask
LIVECHECK_REFERENCE_URL = "https://docs.brew.sh/Cask-Cookbook#stanza-livecheck" LIVECHECK_REFERENCE_URL = "https://docs.brew.sh/Cask-Cookbook#stanza-livecheck"
def check_hosting_with_livecheck(livecheck_result:) def check_hosting_with_livecheck(livecheck_result:)
return if cask.discontinued? || cask.version.latest?
return if block_url_offline? || cask.appcast || cask.livecheckable? return if block_url_offline? || cask.appcast || cask.livecheckable?
return if livecheck_result == :auto_detected return if livecheck_result == :auto_detected
@ -315,7 +316,6 @@ module Cask
case cask.url.to_s case cask.url.to_s
when %r{sourceforge.net/(\S+)} when %r{sourceforge.net/(\S+)}
return if cask.version.latest?
return unless online? return unless online?
add_error "Download is hosted on SourceForge, #{add_livecheck}" add_error "Download is hosted on SourceForge, #{add_livecheck}"

View File

@ -6,6 +6,7 @@ require "cask/config"
require "cask/dsl" require "cask/dsl"
require "cask/metadata" require "cask/metadata"
require "searchable" require "searchable"
require "utils/bottles"
module Cask module Cask
# An instance of a cask. # An instance of a cask.
@ -20,7 +21,7 @@ module Cask
attr_reader :token, :sourcefile_path, :source, :config, :default_config attr_reader :token, :sourcefile_path, :source, :config, :default_config
attr_accessor :download attr_accessor :download, :allow_reassignment
def self.all def self.all
Tap.flat_map(&:cask_files).map do |f| Tap.flat_map(&:cask_files).map do |f|
@ -38,11 +39,12 @@ module Cask
@tap @tap
end end
def initialize(token, sourcefile_path: nil, source: nil, tap: nil, config: nil, &block) def initialize(token, sourcefile_path: nil, source: nil, tap: nil, config: nil, allow_reassignment: false, &block)
@token = token @token = token
@sourcefile_path = sourcefile_path @sourcefile_path = sourcefile_path
@source = source @source = source
@tap = tap @tap = tap
@allow_reassignment = allow_reassignment
@block = block @block = block
@default_config = config || Config.new @default_config = config || Config.new
@ -57,6 +59,10 @@ module Cask
def config=(config) def config=(config)
@config = config @config = config
refresh
end
def refresh
@dsl = DSL.new(self) @dsl = DSL.new(self)
return unless @block return unless @block
@ -88,7 +94,7 @@ module Cask
version_os_hash = {} version_os_hash = {}
actual_version = MacOS.full_version.to_s actual_version = MacOS.full_version.to_s
MacOS::Version::SYMBOLS.each do |os_name, os_version| MacOSVersions::SYMBOLS.each do |os_name, os_version|
MacOS.full_version = os_version MacOS.full_version = os_version
cask = CaskLoader.load(token) cask = CaskLoader.load(token)
version_os_hash[os_name] = cask.version if cask.version != version version_os_hash[os_name] = cask.version if cask.version != version
@ -213,7 +219,7 @@ module Cask
end end
alias == eql? alias == eql?
def to_h def to_hash
{ {
"token" => token, "token" => token,
"full_token" => full_name, "full_token" => full_name,
@ -237,11 +243,47 @@ module Cask
} }
end end
def to_h
hash = to_hash
variations = {}
hash_keys_to_skip = %w[outdated installed versions]
if @dsl.on_system_blocks_exist?
[:arm, :intel].each do |arch|
MacOSVersions::SYMBOLS.each_key do |os_name|
# Big Sur is the first version of macOS that supports arm
next if arch == :arm && MacOS::Version.from_symbol(os_name) < MacOS::Version.from_symbol(:big_sur)
Homebrew::SimulateSystem.os = os_name
Homebrew::SimulateSystem.arch = arch
refresh
bottle_tag = ::Utils::Bottles::Tag.new(system: os_name, arch: arch).to_sym
to_hash.each do |key, value|
next if hash_keys_to_skip.include? key
next if value.to_s == hash[key].to_s
variations[bottle_tag] ||= {}
variations[bottle_tag][key] = value
end
end
end
end
Homebrew::SimulateSystem.clear
refresh
hash["variations"] = variations
hash
end
private private
def to_h_string_gsubs(string) def to_h_string_gsubs(string)
string.to_s string.to_s
.gsub(ENV["HOME"], "$HOME") .gsub(Dir.home, "$HOME")
.gsub(HOMEBREW_PREFIX, "$(brew --prefix)") .gsub(HOMEBREW_PREFIX, "$(brew --prefix)")
end end

View File

@ -217,14 +217,17 @@ module Cask
next unless loader_class.can_load?(ref) next unless loader_class.can_load?(ref)
if loader_class == FromTapLoader && Homebrew::EnvConfig.install_from_api? && if loader_class == FromTapLoader && Homebrew::EnvConfig.install_from_api? &&
ref.start_with?("homebrew/cask/") && !Tap.fetch("homebrew/cask").installed? && ref.start_with?("homebrew/cask/") && Homebrew::API::CaskSource.available?(ref)
Homebrew::API::CaskSource.available?(ref)
return FromContentLoader.new(Homebrew::API::CaskSource.fetch(ref)) return FromContentLoader.new(Homebrew::API::CaskSource.fetch(ref))
end end
return loader_class.new(ref) return loader_class.new(ref)
end end
if Homebrew::EnvConfig.install_from_api? && Homebrew::API::CaskSource.available?(ref)
return FromContentLoader.new(Homebrew::API::CaskSource.fetch(ref))
end
return FromTapPathLoader.new(default_path(ref)) if FromTapPathLoader.can_load?(default_path(ref)) return FromTapPathLoader.new(default_path(ref)) if FromTapPathLoader.can_load?(default_path(ref))
case (possible_tap_casks = tap_paths(ref)).count case (possible_tap_casks = tap_paths(ref)).count
@ -233,14 +236,7 @@ module Cask
when 2..Float::INFINITY when 2..Float::INFINITY
loaders = possible_tap_casks.map(&FromTapPathLoader.method(:new)) loaders = possible_tap_casks.map(&FromTapPathLoader.method(:new))
raise CaskError, <<~EOS raise TapCaskAmbiguityError.new(ref, loaders)
Cask #{ref} exists in multiple taps:
#{loaders.map { |loader| " #{loader.tap}/#{loader.token}" }.join("\n")}
EOS
end
if Homebrew::EnvConfig.install_from_api? && Homebrew::API::CaskSource.available?(ref)
return FromContentLoader.new(Homebrew::API::CaskSource.fetch(ref))
end end
possible_installed_cask = Cask.new(ref) possible_installed_cask = Cask.new(ref)

View File

@ -47,14 +47,10 @@ module Cask
token = path.basename.to_s token = path.basename.to_s
begin begin
if (tap_path = CaskLoader.tap_paths(token).first)
CaskLoader::FromTapPathLoader.new(tap_path).load(config: config)
elsif (caskroom_path = Pathname.glob(path.join(".metadata/*/*/*/*.rb")).first) &&
(!Homebrew::EnvConfig.install_from_api? || !Homebrew::API::CaskSource.available?(token))
CaskLoader::FromPathLoader.new(caskroom_path).load(config: config)
else
CaskLoader.load(token, config: config) CaskLoader.load(token, config: config)
end rescue TapCaskAmbiguityError
tap_path = CaskLoader.tap_paths(token).first
CaskLoader::FromTapPathLoader.new(tap_path).load(config: config)
rescue CaskUnavailableError rescue CaskUnavailableError
# Don't blow up because of a single unavailable cask. # Don't blow up because of a single unavailable cask.
nil nil

View File

@ -190,7 +190,7 @@ module Cask
key = "language" key = "language"
value = T.cast(explicit.fetch(:languages, []), T::Array[String]).join(",") value = T.cast(explicit.fetch(:languages, []), T::Array[String]).join(",")
end end
"#{key}: \"#{value.to_s.sub(/^#{ENV['HOME']}/, "~")}\"" "#{key}: \"#{value.to_s.sub(/^#{Dir.home}/, "~")}\""
end.join(", ") end.join(", ")
end end

View File

@ -25,6 +25,8 @@ require "cask/dsl/version"
require "cask/url" require "cask/url"
require "cask/utils" require "cask/utils"
require "extend/on_system"
module Cask module Cask
# Class representing the domain-specific language used for casks. # Class representing the domain-specific language used for casks.
# #
@ -89,8 +91,13 @@ module Cask
*ARTIFACT_BLOCK_CLASSES.flat_map { |klass| [klass.dsl_key, klass.uninstall_dsl_key] }, *ARTIFACT_BLOCK_CLASSES.flat_map { |klass| [klass.dsl_key, klass.uninstall_dsl_key] },
]).freeze ]).freeze
extend Predicable
include OnSystem
attr_reader :cask, :token attr_reader :cask, :token
attr_predicate :on_system_blocks_exist?
def initialize(cask) def initialize(cask)
@cask = cask @cask = cask
@token = cask.token @token = cask.token
@ -112,10 +119,17 @@ module Cask
def set_unique_stanza(stanza, should_return) def set_unique_stanza(stanza, should_return)
return instance_variable_get("@#{stanza}") if should_return return instance_variable_get("@#{stanza}") if should_return
if instance_variable_defined?("@#{stanza}") unless @cask.allow_reassignment
if instance_variable_defined?("@#{stanza}") && !@called_in_on_system_block
raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only appear once.") raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only appear once.")
end end
if instance_variable_defined?("@#{stanza}_set_in_block") && @called_in_on_system_block
raise CaskInvalidError.new(cask, "'#{stanza}' stanza may only be overridden once.")
end
end
instance_variable_set("@#{stanza}_set_in_block", true) if @called_in_on_system_block
instance_variable_set("@#{stanza}", yield) instance_variable_set("@#{stanza}", yield)
rescue CaskInvalidError rescue CaskInvalidError
raise raise
@ -137,7 +151,7 @@ module Cask
return unless default return unless default
unless @language_blocks.default.nil? if !@cask.allow_reassignment && @language_blocks.default.present?
raise CaskInvalidError.new(cask, "Only one default language may be defined.") raise CaskInvalidError.new(cask, "Only one default language may be defined.")
end end
@ -281,7 +295,7 @@ module Cask
end end
def discontinued? def discontinued?
@caveats&.discontinued? @caveats&.discontinued? == true
end end
# @api public # @api public
@ -294,7 +308,9 @@ module Cask
@livecheck ||= Livecheck.new(self) @livecheck ||= Livecheck.new(self)
return @livecheck unless block return @livecheck unless block
raise CaskInvalidError.new(cask, "'livecheck' stanza may only appear once.") if @livecheckable if !@cask.allow_reassignment && @livecheckable
raise CaskInvalidError.new(cask, "'livecheck' stanza may only appear once.")
end
@livecheckable = true @livecheckable = true
@livecheck.instance_eval(&block) @livecheck.instance_eval(&block)

View File

@ -55,7 +55,7 @@ module Cask
begin begin
@macos = if args.count > 1 @macos = if args.count > 1
MacOSRequirement.new([args], comparator: "==") MacOSRequirement.new([args], comparator: "==")
elsif MacOS::Version::SYMBOLS.key?(args.first) elsif MacOSVersions::SYMBOLS.key?(args.first)
MacOSRequirement.new([args.first], comparator: "==") MacOSRequirement.new([args.first], comparator: "==")
elsif /^\s*(?<comparator><|>|[=<>]=)\s*:(?<version>\S+)\s*$/ =~ args.first elsif /^\s*(?<comparator><|>|[=<>]=)\s*:(?<version>\S+)\s*$/ =~ args.first
MacOSRequirement.new([version.to_sym], comparator: comparator) MacOSRequirement.new([version.to_sym], comparator: comparator)

View File

@ -124,6 +124,20 @@ module Cask
end end
end end
# Error when a cask with the same name is found in multiple taps.
#
# @api private
class TapCaskAmbiguityError < CaskError
extend T::Sig
def initialize(ref, loaders)
super <<~EOS
Cask #{ref} exists in multiple taps:
#{loaders.map { |loader| " #{loader.tap}/#{loader.token}" }.join("\n")}
EOS
end
end
# Error when a cask already exists. # Error when a cask already exists.
# #
# @api private # @api private

View File

@ -225,7 +225,7 @@ class URL < Delegator
@raw_interpolated_url = @raw_interpolated_url =
Pathname(@caller_location.absolute_path) Pathname(@caller_location.absolute_path)
.each_line.drop(@caller_location.lineno - 1) .each_line.drop(@caller_location.lineno - 1)
.first&.yield_self { |line| line[/url\s+"([^"]+)"/, 1] } .first&.then { |line| line[/url\s+"([^"]+)"/, 1] }
end end
private :raw_interpolated_url private :raw_interpolated_url

View File

@ -78,7 +78,7 @@ class Caveats
s << " #{Utils::Shell.export_value("CPPFLAGS", "-I#{f.opt_include}")}\n" if f.include.directory? s << " #{Utils::Shell.export_value("CPPFLAGS", "-I#{f.opt_include}")}\n" if f.include.directory?
if which("pkg-config", ENV["HOMEBREW_PATH"]) && if which("pkg-config", ORIGINAL_PATHS) &&
((f.lib/"pkgconfig").directory? || (f.share/"pkgconfig").directory?) ((f.lib/"pkgconfig").directory? || (f.share/"pkgconfig").directory?)
s << <<~EOS s << <<~EOS
@ -109,7 +109,7 @@ class Caveats
def function_completion_caveats(shell) def function_completion_caveats(shell)
return unless keg return unless keg
return unless which(shell.to_s, ENV["HOMEBREW_PATH"]) return unless which(shell.to_s, ORIGINAL_PATHS)
completion_installed = keg.completion_installed?(shell) completion_installed = keg.completion_installed?(shell)
functions_installed = keg.functions_installed?(shell) functions_installed = keg.functions_installed?(shell)

View File

@ -391,7 +391,7 @@ module Homebrew
end end
def cleanup_portable_ruby def cleanup_portable_ruby
rubies = [which("ruby"), which("ruby", ENV["HOMEBREW_PATH"])].compact rubies = [which("ruby"), which("ruby", ORIGINAL_PATHS)].compact
system_ruby = Pathname.new("/usr/bin/ruby") system_ruby = Pathname.new("/usr/bin/ruby")
rubies << system_ruby if system_ruby.exist? rubies << system_ruby if system_ruby.exist?

View File

@ -24,7 +24,7 @@ module Homebrew
description: "Show the cache file used when building from source." description: "Show the cache file used when building from source."
switch "--force-bottle", switch "--force-bottle",
description: "Show the cache file used when pouring a bottle." description: "Show the cache file used when pouring a bottle."
flag "--bottle-tag", flag "--bottle-tag=",
description: "Show the cache file used when pouring a bottle for the given tag." description: "Show the cache file used when pouring a bottle for the given tag."
switch "--HEAD", switch "--HEAD",
description: "Show the cache file used when building from HEAD." description: "Show the cache file used when building from HEAD."

View File

@ -20,13 +20,13 @@ module Homebrew
#{days} days old. This can be adjusted with `HOMEBREW_CLEANUP_MAX_AGE_DAYS`. #{days} days old. This can be adjusted with `HOMEBREW_CLEANUP_MAX_AGE_DAYS`.
EOS EOS
flag "--prune=", flag "--prune=",
description: "Remove all cache files older than specified <days>. "\ description: "Remove all cache files older than specified <days>. " \
"If you want to remove everything, use `--prune=all`." "If you want to remove everything, use `--prune=all`."
switch "-n", "--dry-run", switch "-n", "--dry-run",
description: "Show what would be removed, but do not actually remove anything." description: "Show what would be removed, but do not actually remove anything."
switch "-s", switch "-s",
description: "Scrub the cache, including downloads for even the latest versions. "\ description: "Scrub the cache, including downloads for even the latest versions. " \
"Note that downloads for any installed formulae or casks will still not be deleted. "\ "Note that downloads for any installed formulae or casks will still not be deleted. " \
"If you want to delete those too: `rm -rf \"$(brew --cache)\"`" "If you want to delete those too: `rm -rf \"$(brew --cache)\"`"
switch "--prune-prefix", switch "--prune-prefix",
description: "Only prune the symlinks and directories from the prefix and remove no other files." description: "Only prune the symlinks and directories from the prefix and remove no other files."
@ -38,7 +38,7 @@ module Homebrew
def cleanup def cleanup
args = cleanup_args.parse args = cleanup_args.parse
days = args.prune.presence&.yield_self do |prune| days = args.prune.presence&.then do |prune|
case prune case prune
when /\A\d+\Z/ when /\A\d+\Z/
prune.to_i prune.to_i

View File

@ -41,7 +41,7 @@ module Homebrew
switch "--include-requirements", switch "--include-requirements",
description: "Include requirements in addition to dependencies for <formula>." description: "Include requirements in addition to dependencies for <formula>."
switch "--tree", switch "--tree",
description: "Show dependencies as a tree. When given multiple formula arguments, "\ description: "Show dependencies as a tree. When given multiple formula arguments, " \
"show individual trees for each formula." "show individual trees for each formula."
switch "--graph", switch "--graph",
description: "Show dependencies as a directed graph." description: "Show dependencies as a directed graph."
@ -49,16 +49,16 @@ module Homebrew
depends_on: "--graph", depends_on: "--graph",
description: "Show text-based graph description in DOT format." description: "Show text-based graph description in DOT format."
switch "--annotate", switch "--annotate",
description: "Mark any build, test, optional, or recommended dependencies as "\ description: "Mark any build, test, optional, or recommended dependencies as " \
"such in the output." "such in the output."
switch "--installed", switch "--installed",
description: "List dependencies for formulae that are currently installed. If <formula> is "\ description: "List dependencies for formulae that are currently installed. If <formula> is " \
"specified, list only its dependencies that are currently installed." "specified, list only its dependencies that are currently installed."
switch "--all", switch "--all",
description: "List dependencies for all available formulae." description: "List dependencies for all available formulae."
switch "--for-each", switch "--for-each",
description: "Switch into the mode used by the `--all` option, but only list dependencies "\ description: "Switch into the mode used by the `--all` option, but only list dependencies " \
"for each provided <formula>, one formula per line. This is used for "\ "for each provided <formula>, one formula per line. This is used for " \
"debugging the `--installed`/`--all` display mode." "debugging the `--installed`/`--all` display mode."
switch "--formula", "--formulae", switch "--formula", "--formulae",
depends_on: "--installed", depends_on: "--installed",

View File

@ -22,13 +22,13 @@ module Homebrew
first search, making that search slower than subsequent ones. first search, making that search slower than subsequent ones.
EOS EOS
switch "-s", "--search", switch "-s", "--search",
description: "Search both names and descriptions for <text>. If <text> is flanked by "\ description: "Search both names and descriptions for <text>. If <text> is flanked by " \
"slashes, it is interpreted as a regular expression." "slashes, it is interpreted as a regular expression."
switch "-n", "--name", switch "-n", "--name",
description: "Search just names for <text>. If <text> is flanked by slashes, it is "\ description: "Search just names for <text>. If <text> is flanked by slashes, it is " \
"interpreted as a regular expression." "interpreted as a regular expression."
switch "-d", "--description", switch "-d", "--description",
description: "Search just descriptions for <text>. If <text> is flanked by slashes, "\ description: "Search just descriptions for <text>. If <text> is flanked by slashes, " \
"it is interpreted as a regular expression." "it is interpreted as a regular expression."
switch "--formula", "--formulae", switch "--formula", "--formulae",
description: "Treat all named arguments as formulae." description: "Treat all named arguments as formulae."

View File

@ -21,7 +21,7 @@ module Homebrew
an issue; just ignore this. an issue; just ignore this.
EOS EOS
switch "--list-checks", switch "--list-checks",
description: "List all audit methods, which can be run individually "\ description: "List all audit methods, which can be run individually " \
"if provided as arguments." "if provided as arguments."
switch "-D", "--audit-debug", switch "-D", "--audit-debug",
description: "Enable debugging and profiling of audit methods." description: "Enable debugging and profiling of audit methods."

View File

@ -20,17 +20,17 @@ module Homebrew
Download a bottle (if available) or source packages for <formula>e Download a bottle (if available) or source packages for <formula>e
and binaries for <cask>s. For files, also print SHA-256 checksums. and binaries for <cask>s. For files, also print SHA-256 checksums.
EOS EOS
flag "--bottle-tag", flag "--bottle-tag=",
description: "Download a bottle for given tag." description: "Download a bottle for given tag."
switch "--HEAD", switch "--HEAD",
description: "Fetch HEAD version instead of stable version." description: "Fetch HEAD version instead of stable version."
switch "-f", "--force", switch "-f", "--force",
description: "Remove a previously cached version and re-fetch." description: "Remove a previously cached version and re-fetch."
switch "-v", "--verbose", switch "-v", "--verbose",
description: "Do a verbose VCS checkout, if the URL represents a VCS. This is useful for "\ description: "Do a verbose VCS checkout, if the URL represents a VCS. This is useful for " \
"seeing if an existing VCS cache has been updated." "seeing if an existing VCS cache has been updated."
switch "--retry", switch "--retry",
description: "Retry if downloading fails or re-download if the checksum of a previously cached "\ description: "Retry if downloading fails or re-download if the checksum of a previously cached " \
"version no longer matches." "version no longer matches."
switch "--deps", switch "--deps",
description: "Also download dependencies for any listed <formula>." description: "Also download dependencies for any listed <formula>."
@ -39,7 +39,7 @@ module Homebrew
switch "--build-bottle", switch "--build-bottle",
description: "Download source packages (for eventual bottling) rather than a bottle." description: "Download source packages (for eventual bottling) rather than a bottle."
switch "--force-bottle", switch "--force-bottle",
description: "Download a bottle if it exists for the current or newest version of macOS, "\ description: "Download a bottle if it exists for the current or newest version of macOS, " \
"even if it would not be used during installation." "even if it would not be used during installation."
switch "--[no-]quarantine", switch "--[no-]quarantine",
description: "Disable/enable quarantining of downloads (default: enabled).", description: "Disable/enable quarantining of downloads (default: enabled).",

View File

@ -25,10 +25,10 @@ module Homebrew
switch "--with-hostname", switch "--with-hostname",
description: "Include the hostname in the Gist." description: "Include the hostname in the Gist."
switch "-n", "--new-issue", switch "-n", "--new-issue",
description: "Automatically create a new issue in the appropriate GitHub repository "\ description: "Automatically create a new issue in the appropriate GitHub repository " \
"after creating the Gist." "after creating the Gist."
switch "-p", "--private", switch "-p", "--private",
description: "The Gist will be marked private and will not appear in listings but will "\ description: "The Gist will be marked private and will not appear in listings but will " \
"be accessible with its link." "be accessible with its link."
named_args :formula, number: 1 named_args :formula, number: 1

View File

@ -31,25 +31,25 @@ module Homebrew
If a <formula> or <cask> is provided, show summary of information about it. If a <formula> or <cask> is provided, show summary of information about it.
EOS EOS
switch "--analytics", switch "--analytics",
description: "List global Homebrew analytics data or, if specified, installation and "\ description: "List global Homebrew analytics data or, if specified, installation and " \
"build error data for <formula> (provided neither `HOMEBREW_NO_ANALYTICS` "\ "build error data for <formula> (provided neither `HOMEBREW_NO_ANALYTICS` " \
"nor `HOMEBREW_NO_GITHUB_API` are set)." "nor `HOMEBREW_NO_GITHUB_API` are set)."
flag "--days=", flag "--days=",
depends_on: "--analytics", depends_on: "--analytics",
description: "How many days of analytics data to retrieve. "\ description: "How many days of analytics data to retrieve. " \
"The value for <days> must be `30`, `90` or `365`. The default is `30`." "The value for <days> must be `30`, `90` or `365`. The default is `30`."
flag "--category=", flag "--category=",
depends_on: "--analytics", depends_on: "--analytics",
description: "Which type of analytics data to retrieve. "\ description: "Which type of analytics data to retrieve. " \
"The value for <category> must be `install`, `install-on-request` or `build-error`; "\ "The value for <category> must be `install`, `install-on-request` or `build-error`; " \
"`cask-install` or `os-version` may be specified if <formula> is not. "\ "`cask-install` or `os-version` may be specified if <formula> is not. " \
"The default is `install`." "The default is `install`."
switch "--github", switch "--github",
description: "Open the GitHub source page for <formula> and <cask> in a browser. "\ description: "Open the GitHub source page for <formula> and <cask> in a browser. " \
"To view the history locally: `brew log -p` <formula> or <cask>" "To view the history locally: `brew log -p` <formula> or <cask>"
flag "--json", flag "--json",
description: "Print a JSON representation. Currently the default value for <version> is `v1` for "\ description: "Print a JSON representation. Currently the default value for <version> is `v1` for " \
"<formula>. For <formula> and <cask> use `v2`. See the docs for examples of using the "\ "<formula>. For <formula> and <cask> use `v2`. See the docs for examples of using the " \
"JSON output: <https://docs.brew.sh/Querying-Brew>" "JSON output: <https://docs.brew.sh/Querying-Brew>"
switch "--bottle", switch "--bottle",
depends_on: "--json", depends_on: "--json",

View File

@ -41,7 +41,7 @@ module Homebrew
"or a shell inside the temporary build directory." "or a shell inside the temporary build directory."
switch "-f", "--force", switch "-f", "--force",
description: "Install formulae without checking for previously installed keg-only or " \ description: "Install formulae without checking for previously installed keg-only or " \
"non-migrated versions. When installing casks, overwrite existing files "\ "non-migrated versions. When installing casks, overwrite existing files " \
"(binaries and symlinks are excluded, unless originally from the same cask)." "(binaries and symlinks are excluded, unless originally from the same cask)."
switch "-v", "--verbose", switch "-v", "--verbose",
description: "Print the verification and postinstall steps." description: "Print the verification and postinstall steps."
@ -140,6 +140,10 @@ module Homebrew
def install def install
args = install_args.parse args = install_args.parse
if args.build_from_source? && Homebrew::EnvConfig.install_from_api?
raise UsageError, "--build-from-source is not supported when using HOMEBREW_INSTALL_FROM_API."
end
if args.env.present? if args.env.present?
# Can't use `replacement: false` because `install_args` are used by # Can't use `replacement: false` because `install_args` are used by
# `build.rb`. Instead, `hide_from_man_page` and don't do anything with # `build.rb`. Instead, `hide_from_man_page` and don't do anything with

View File

@ -22,7 +22,7 @@ module Homebrew
switch "--overwrite", switch "--overwrite",
description: "Delete files that already exist in the prefix while linking." description: "Delete files that already exist in the prefix while linking."
switch "-n", "--dry-run", switch "-n", "--dry-run",
description: "List files which would be linked or deleted by "\ description: "List files which would be linked or deleted by " \
"`brew link --overwrite` without actually linking or deleting any files." "`brew link --overwrite` without actually linking or deleting any files."
switch "-f", "--force", switch "-f", "--force",
description: "Allow keg-only formulae to be linked." description: "Allow keg-only formulae to be linked."

View File

@ -25,17 +25,17 @@ module Homebrew
switch "--cask", "--casks", switch "--cask", "--casks",
description: "List only casks, or treat all named arguments as casks." description: "List only casks, or treat all named arguments as casks."
switch "--full-name", switch "--full-name",
description: "Print formulae with fully-qualified names. Unless `--full-name`, `--versions` "\ description: "Print formulae with fully-qualified names. Unless `--full-name`, `--versions` " \
"or `--pinned` are passed, other options (i.e. `-1`, `-l`, `-r` and `-t`) are "\ "or `--pinned` are passed, other options (i.e. `-1`, `-l`, `-r` and `-t`) are " \
"passed to `ls`(1) which produces the actual output." "passed to `ls`(1) which produces the actual output."
switch "--versions", switch "--versions",
description: "Show the version number for installed formulae, or only the specified "\ description: "Show the version number for installed formulae, or only the specified " \
"formulae if <formula> are provided." "formulae if <formula> are provided."
switch "--multiple", switch "--multiple",
depends_on: "--versions", depends_on: "--versions",
description: "Only show formulae with multiple versions installed." description: "Only show formulae with multiple versions installed."
switch "--pinned", switch "--pinned",
description: "List only pinned formulae, or only the specified (pinned) "\ description: "List only pinned formulae, or only the specified (pinned) " \
"formulae if <formula> are provided. See also `pin`, `unpin`." "formulae if <formula> are provided. See also `pin`, `unpin`."
# passed through to ls # passed through to ls
switch "-1", switch "-1",

View File

@ -42,7 +42,7 @@ module Homebrew
# As this command is simplifying user-run commands then let's just use a # As this command is simplifying user-run commands then let's just use a
# user path, too. # user path, too.
ENV["PATH"] = ENV["HOMEBREW_PATH"] ENV["PATH"] = PATH.new(ORIGINAL_PATHS).to_s
if args.no_named? if args.no_named?
git_log HOMEBREW_REPOSITORY, args: args git_log HOMEBREW_REPOSITORY, args: args

View File

@ -17,7 +17,7 @@ module Homebrew
packages. packages.
EOS EOS
switch "-f", "--force", switch "-f", "--force",
description: "Treat installed <formula> and provided <formula> as if they are from "\ description: "Treat installed <formula> and provided <formula> as if they are from " \
"the same taps and migrate them anyway." "the same taps and migrate them anyway."
switch "-n", "--dry-run", switch "-n", "--dry-run",
description: "Show what would be migrated, but do not actually migrate anything." description: "Show what would be migrated, but do not actually migrate anything."

View File

@ -20,7 +20,7 @@ module Homebrew
to be missing dependencies. to be missing dependencies.
EOS EOS
comma_array "--hide", comma_array "--hide",
description: "Act as if none of the specified <hidden> are installed. <hidden> should be "\ description: "Act as if none of the specified <hidden> are installed. <hidden> should be " \
"a comma-separated list of formulae." "a comma-separated list of formulae."
named_args :formula named_args :formula

View File

@ -33,17 +33,17 @@ module Homebrew
"`v1` is deprecated and is currently the default if no version is specified. " \ "`v1` is deprecated and is currently the default if no version is specified. " \
"`v2` prints outdated formulae and casks." "`v2` prints outdated formulae and casks."
switch "--fetch-HEAD", switch "--fetch-HEAD",
description: "Fetch the upstream repository to detect if the HEAD installation of the "\ description: "Fetch the upstream repository to detect if the HEAD installation of the " \
"formula is outdated. Otherwise, the repository's HEAD will only be checked for "\ "formula is outdated. Otherwise, the repository's HEAD will only be checked for " \
"updates when a new stable or development version has been released." "updates when a new stable or development version has been released."
switch "--greedy", switch "--greedy",
description: "Print outdated casks with `auto_updates true` or `version :latest`." description: "Also include outdated casks with `auto_updates true` or `version :latest`."
switch "--greedy-latest", switch "--greedy-latest",
description: "Print outdated casks including those with `version :latest`." description: "Also include outdated casks including those with `version :latest`."
switch "--greedy-auto-updates", switch "--greedy-auto-updates",
description: "Print outdated casks including those with `auto_updates true`." description: "Also include outdated casks including those with `auto_updates true`."
conflicts "--quiet", "--verbose", "--json" conflicts "--quiet", "--verbose", "--json"
conflicts "--formula", "--cask" conflicts "--formula", "--cask"

View File

@ -88,6 +88,10 @@ module Homebrew
def reinstall def reinstall
args = reinstall_args.parse args = reinstall_args.parse
if args.build_from_source? && Homebrew::EnvConfig.install_from_api?
raise UsageError, "--build-from-source is not supported when using HOMEBREW_INSTALL_FROM_API."
end
formulae, casks = args.named.to_formulae_and_casks(method: :resolve) formulae, casks = args.named.to_formulae_and_casks(method: :resolve)
.partition { |o| o.is_a?(Formula) } .partition { |o| o.is_a?(Formula) }

View File

@ -42,7 +42,7 @@ module Homebrew
switch "--cask", "--casks", switch "--cask", "--casks",
description: "Search online and locally for casks." description: "Search online and locally for casks."
switch "--desc", switch "--desc",
description: "Search for formulae with a description matching <text> and casks with "\ description: "Search for formulae with a description matching <text> and casks with " \
"a name or description matching <text>." "a name or description matching <text>."
switch "--pull-request", switch "--pull-request",
description: "Search for GitHub pull requests containing <text>." description: "Search for GitHub pull requests containing <text>."

View File

@ -19,8 +19,8 @@ module Homebrew
switch "--installed", switch "--installed",
description: "Show information on each installed tap." description: "Show information on each installed tap."
flag "--json", flag "--json",
description: "Print a JSON representation of <tap>. Currently the default and only accepted "\ description: "Print a JSON representation of <tap>. Currently the default and only accepted " \
"value for <version> is `v1`. See the docs for examples of using the JSON "\ "value for <version> is `v1`. See the docs for examples of using the JSON " \
"output: <https://docs.brew.sh/Querying-Brew>" "output: <https://docs.brew.sh/Querying-Brew>"
named_args :tap named_args :tap

View File

@ -28,14 +28,14 @@ module Homebrew
using protocols other than HTTPS, e.g. SSH, git, HTTP, FTP(S), rsync. using protocols other than HTTPS, e.g. SSH, git, HTTP, FTP(S), rsync.
EOS EOS
switch "--full", switch "--full",
description: "Convert a shallow clone to a full clone without untapping. Taps are only cloned as "\ description: "Convert a shallow clone to a full clone without untapping. Taps are only cloned as " \
"shallow clones if `--shallow` was originally passed.", "shallow clones if `--shallow` was originally passed.",
replacement: false replacement: false
switch "--shallow", switch "--shallow",
description: "Fetch tap as a shallow clone rather than a full clone. Useful for continuous integration.", description: "Fetch tap as a shallow clone rather than a full clone. Useful for continuous integration.",
replacement: false replacement: false
switch "--[no-]force-auto-update", switch "--[no-]force-auto-update",
description: "Auto-update tap even if it is not hosted on GitHub. By default, only taps "\ description: "Auto-update tap even if it is not hosted on GitHub. By default, only taps " \
"hosted on GitHub are auto-updated (for performance reasons)." "hosted on GitHub are auto-updated (for performance reasons)."
switch "--custom-remote", switch "--custom-remote",
description: "Install or change a tap with a custom remote. Useful for mirrors." description: "Install or change a tap with a custom remote. Useful for mirrors."

View File

@ -28,7 +28,7 @@ module Homebrew
description: "Remove all files associated with a <cask>. " \ description: "Remove all files associated with a <cask>. " \
"*May remove files which are shared between applications.*" "*May remove files which are shared between applications.*"
switch "--ignore-dependencies", switch "--ignore-dependencies",
description: "Don't fail uninstall, even if <formula> is a dependency of any installed "\ description: "Don't fail uninstall, even if <formula> is a dependency of any installed " \
"formulae." "formulae."
switch "--formula", "--formulae", switch "--formula", "--formulae",
description: "Treat all named arguments as formulae." description: "Treat all named arguments as formulae."

View File

@ -19,7 +19,7 @@ module Homebrew
`brew unlink` <formula> `&&` <commands> `&& brew link` <formula> `brew unlink` <formula> `&&` <commands> `&& brew link` <formula>
EOS EOS
switch "-n", "--dry-run", switch "-n", "--dry-run",
description: "List files which would be unlinked without actually unlinking or "\ description: "List files which would be unlinked without actually unlinking or " \
"deleting any files." "deleting any files."
named_args :installed_formula, min: 1 named_args :installed_formula, min: 1

View File

@ -31,7 +31,7 @@ module Homebrew
switch "--auto-update", "--preinstall", switch "--auto-update", "--preinstall",
description: "Run in 'auto-update' mode (faster, less output)." description: "Run in 'auto-update' mode (faster, less output)."
switch "-f", "--force", switch "-f", "--force",
description: "Treat installed and updated formulae as if they are from "\ description: "Treat installed and updated formulae as if they are from " \
"the same taps and migrate them anyway." "the same taps and migrate them anyway."
hide_from_man_page! hide_from_man_page!
@ -54,9 +54,9 @@ module Homebrew
ENV["HOMEBREW_LINUXBREW_CORE_MIGRATION"].blank? ENV["HOMEBREW_LINUXBREW_CORE_MIGRATION"].blank?
ohai "Re-running `brew update` for linuxbrew-core migration" ohai "Re-running `brew update` for linuxbrew-core migration"
if ENV["HOMEBREW_CORE_DEFAULT_GIT_REMOTE"] != ENV["HOMEBREW_CORE_GIT_REMOTE"] if HOMEBREW_CORE_DEFAULT_GIT_REMOTE != Homebrew::EnvConfig.core_git_remote
opoo <<~EOS opoo <<~EOS
HOMEBREW_CORE_GIT_REMOTE was set: #{ENV["HOMEBREW_CORE_GIT_REMOTE"]}. HOMEBREW_CORE_GIT_REMOTE was set: #{Homebrew::EnvConfig.core_git_remote}.
It has been unset for the migration. It has been unset for the migration.
You may need to change this from a linuxbrew-core mirror to a homebrew-core one. You may need to change this from a linuxbrew-core mirror to a homebrew-core one.
@ -64,9 +64,9 @@ module Homebrew
end end
ENV.delete("HOMEBREW_CORE_GIT_REMOTE") ENV.delete("HOMEBREW_CORE_GIT_REMOTE")
if ENV["HOMEBREW_BOTTLE_DEFAULT_DOMAIN"] != ENV["HOMEBREW_BOTTLE_DOMAIN"] if HOMEBREW_BOTTLE_DEFAULT_DOMAIN != Homebrew::EnvConfig.bottle_domain
opoo <<~EOS opoo <<~EOS
HOMEBREW_BOTTLE_DOMAIN was set: #{ENV["HOMEBREW_BOTTLE_DOMAIN"]}. HOMEBREW_BOTTLE_DOMAIN was set: #{Homebrew::EnvConfig.bottle_domain}.
It has been unset for the migration. It has been unset for the migration.
You may need to change this from a Linuxbrew package mirror to a Homebrew one. You may need to change this from a Linuxbrew package mirror to a Homebrew one.
@ -142,14 +142,14 @@ module Homebrew
end end
Homebrew.failed = true if ENV["HOMEBREW_UPDATE_FAILED"] Homebrew.failed = true if ENV["HOMEBREW_UPDATE_FAILED"]
return if ENV["HOMEBREW_DISABLE_LOAD_FORMULA"] return if Homebrew::EnvConfig.disable_load_formula?
hub = ReporterHub.new hub = ReporterHub.new
updated_taps = [] updated_taps = []
Tap.each do |tap| Tap.each do |tap|
next unless tap.git? next unless tap.git?
next if (tap.core_tap? || tap == "homebrew/cask") && Homebrew::EnvConfig.install_from_api? && args.auto_update? next if (tap.core_tap? || tap == "homebrew/cask") && Homebrew::EnvConfig.install_from_api?
if ENV["HOMEBREW_MIGRATE_LINUXBREW_FORMULAE"].present? && tap.core_tap? && if ENV["HOMEBREW_MIGRATE_LINUXBREW_FORMULAE"].present? && tap.core_tap? &&
Settings.read("linuxbrewmigrated") != "true" Settings.read("linuxbrewmigrated") != "true"
@ -239,14 +239,13 @@ module Homebrew
puts puts
ohai "Homebrew was updated to version #{new_repository_version}" ohai "Homebrew was updated to version #{new_repository_version}"
if new_repository_version.split(".").last == "0"
Settings.write "latesttag", new_repository_version Settings.write "latesttag", new_repository_version
if new_repository_version.split(".").last == "0"
puts <<~EOS puts <<~EOS
More detailed release notes are available on the Homebrew Blog: More detailed release notes are available on the Homebrew Blog:
#{Formatter.url("https://brew.sh/blog/#{new_repository_version}")} #{Formatter.url("https://brew.sh/blog/#{new_repository_version}")}
EOS EOS
elsif !args.quiet? elsif !args.quiet?
Settings.write "latesttag", new_repository_version
puts <<~EOS puts <<~EOS
The changelog can be found at: The changelog can be found at:
#{Formatter.url("https://github.com/Homebrew/brew/releases/tag/#{new_repository_version}")} #{Formatter.url("https://github.com/Homebrew/brew/releases/tag/#{new_repository_version}")}
@ -608,9 +607,7 @@ class ReporterHub
private private
def dump_new_formula_report def dump_new_formula_report
formulae = select_formula_or_cask(:A).sort.map do |name| formulae = select_formula_or_cask(:A).sort.reject { |name| installed?(name) }
name unless installed?(name)
end.compact
output_dump_formula_or_cask_report "New Formulae", formulae output_dump_formula_or_cask_report "New Formulae", formulae
end end

View File

@ -701,10 +701,7 @@ EOS
for DIR in "${HOMEBREW_REPOSITORY}" "${HOMEBREW_LIBRARY}"/Taps/*/* for DIR in "${HOMEBREW_REPOSITORY}" "${HOMEBREW_LIBRARY}"/Taps/*/*
do do
# HOMEBREW_UPDATE_AUTO wasn't modified in subshell.
# shellcheck disable=SC2031
if [[ -n "${HOMEBREW_INSTALL_FROM_API}" ]] && if [[ -n "${HOMEBREW_INSTALL_FROM_API}" ]] &&
[[ -n "${HOMEBREW_UPDATE_AUTO}" ]] &&
[[ "${DIR}" == "${HOMEBREW_CORE_REPOSITORY}" || [[ "${DIR}" == "${HOMEBREW_CORE_REPOSITORY}" ||
"${DIR}" == "${HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-cask" ]] "${DIR}" == "${HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-cask" ]]
then then

View File

@ -30,11 +30,11 @@ module Homebrew
upgraded formulae or, every 30 days, for all formulae. upgraded formulae or, every 30 days, for all formulae.
EOS EOS
switch "-d", "--debug", switch "-d", "--debug",
description: "If brewing fails, open an interactive debugging session with access to IRB "\ description: "If brewing fails, open an interactive debugging session with access to IRB " \
"or a shell inside the temporary build directory." "or a shell inside the temporary build directory."
switch "-f", "--force", switch "-f", "--force",
description: "Install formulae without checking for previously installed keg-only or "\ description: "Install formulae without checking for previously installed keg-only or " \
"non-migrated versions. When installing casks, overwrite existing files "\ "non-migrated versions. When installing casks, overwrite existing files " \
"(binaries and symlinks are excluded, unless originally from the same cask)." "(binaries and symlinks are excluded, unless originally from the same cask)."
switch "-v", "--verbose", switch "-v", "--verbose",
description: "Print the verification and postinstall steps." description: "Print the verification and postinstall steps."
@ -49,17 +49,17 @@ module Homebrew
description: "Compile <formula> from source even if a bottle is available.", description: "Compile <formula> from source even if a bottle is available.",
}], }],
[:switch, "-i", "--interactive", { [:switch, "-i", "--interactive", {
description: "Download and patch <formula>, then open a shell. This allows the user to "\ description: "Download and patch <formula>, then open a shell. This allows the user to " \
"run `./configure --help` and otherwise determine how to turn the software "\ "run `./configure --help` and otherwise determine how to turn the software " \
"package into a Homebrew package.", "package into a Homebrew package.",
}], }],
[:switch, "--force-bottle", { [:switch, "--force-bottle", {
description: "Install from a bottle if it exists for the current or newest version of "\ description: "Install from a bottle if it exists for the current or newest version of " \
"macOS, even if it would not normally be used for installation.", "macOS, even if it would not normally be used for installation.",
}], }],
[:switch, "--fetch-HEAD", { [:switch, "--fetch-HEAD", {
description: "Fetch the upstream repository to detect if the HEAD installation of the "\ description: "Fetch the upstream repository to detect if the HEAD installation of the " \
"formula is outdated. Otherwise, the repository's HEAD will only be checked for "\ "formula is outdated. Otherwise, the repository's HEAD will only be checked for " \
"updates when a new stable or development version has been released.", "updates when a new stable or development version has been released.",
}], }],
[:switch, "--ignore-pinned", { [:switch, "--ignore-pinned", {

View File

@ -31,6 +31,25 @@ module Commands
"tc" => "typecheck", "tc" => "typecheck",
}.freeze }.freeze
INSTALL_FROM_API_FORBIDDEN_COMMANDS = %w[
audit
bottle
bump-cask-pr
bump-formula-pr
bump-revision
bump-unversioned-casks
cat
create
edit
extract
formula
livecheck
pr-pull
pr-upload
test
update-python-resources
].freeze
def valid_internal_cmd?(cmd) def valid_internal_cmd?(cmd)
require?(HOMEBREW_CMD_PATH/cmd) require?(HOMEBREW_CMD_PATH/cmd)
end end
@ -74,11 +93,11 @@ module Commands
# Ruby commands which are run by being `require`d. # Ruby commands which are run by being `require`d.
def external_ruby_cmd_path(cmd) def external_ruby_cmd_path(cmd)
which("brew-#{cmd}.rb", PATH.new(ENV["PATH"]).append(Tap.cmd_directories)) which("brew-#{cmd}.rb", PATH.new(ENV.fetch("PATH")).append(Tap.cmd_directories))
end end
def external_cmd_path(cmd) def external_cmd_path(cmd)
which("brew-#{cmd}", PATH.new(ENV["PATH"]).append(Tap.cmd_directories)) which("brew-#{cmd}", PATH.new(ENV.fetch("PATH")).append(Tap.cmd_directories))
end end
def path(cmd) def path(cmd)

View File

@ -37,7 +37,7 @@ class Dependency
alias eql? == alias eql? ==
def hash def hash
name.hash ^ tags.hash [name, tags].hash
end end
def to_formula def to_formula

View File

@ -16,7 +16,7 @@ module DeprecateDisable
unsupported: "is not supported upstream", unsupported: "is not supported upstream",
deprecated_upstream: "is deprecated upstream", deprecated_upstream: "is deprecated upstream",
versioned_formula: "is a versioned formula", versioned_formula: "is a versioned formula",
checksum_mismatch: "was built with an initially released source file that had "\ checksum_mismatch: "was built with an initially released source file that had " \
"a different checksum than the current one. " \ "a different checksum than the current one. " \
"Upstream's repository might have been compromised. " \ "Upstream's repository might have been compromised. " \
"We can re-package this once upstream has confirmed that they retagged their release", "We can re-package this once upstream has confirmed that they retagged their release",

View File

@ -45,8 +45,8 @@ module Homebrew
description: "Check all formulae and casks whether installed or not.", description: "Check all formulae and casks whether installed or not.",
hidden: true hidden: true
switch "--new", "--new-formula", "--new-cask", switch "--new", "--new-formula", "--new-cask",
description: "Run various additional style checks to determine if a new formula or cask is eligible "\ description: "Run various additional style checks to determine if a new formula or cask is eligible " \
"for Homebrew. This should be used when creating new formula and implies "\ "for Homebrew. This should be used when creating new formula and implies " \
"`--strict` and `--online`." "`--strict` and `--online`."
switch "--[no-]appcast", switch "--[no-]appcast",
description: "Audit the appcast." description: "Audit the appcast."
@ -59,27 +59,27 @@ module Homebrew
switch "--display-cop-names", switch "--display-cop-names",
description: "Include the RuboCop cop name for each violation in the output." description: "Include the RuboCop cop name for each violation in the output."
switch "--display-filename", switch "--display-filename",
description: "Prefix every line of output with the file or formula name being audited, to "\ description: "Prefix every line of output with the file or formula name being audited, to " \
"make output easy to grep." "make output easy to grep."
switch "--display-failures-only", switch "--display-failures-only",
description: "Only display casks that fail the audit. This is the default for formulae." description: "Only display casks that fail the audit. This is the default for formulae."
switch "--skip-style", switch "--skip-style",
description: "Skip running non-RuboCop style checks. Useful if you plan on running "\ description: "Skip running non-RuboCop style checks. Useful if you plan on running " \
"`brew style` separately. Enabled by default unless a formula is specified by name." "`brew style` separately. Enabled by default unless a formula is specified by name."
switch "-D", "--audit-debug", switch "-D", "--audit-debug",
description: "Enable debugging and profiling of audit methods." description: "Enable debugging and profiling of audit methods."
comma_array "--only", comma_array "--only",
description: "Specify a comma-separated <method> list to only run the methods named "\ description: "Specify a comma-separated <method> list to only run the methods named " \
"`audit_`<method>." "`audit_`<method>."
comma_array "--except", comma_array "--except",
description: "Specify a comma-separated <method> list to skip running the methods named "\ description: "Specify a comma-separated <method> list to skip running the methods named " \
"`audit_`<method>." "`audit_`<method>."
comma_array "--only-cops", comma_array "--only-cops",
description: "Specify a comma-separated <cops> list to check for violations of only the listed "\ description: "Specify a comma-separated <cops> list to check for violations of only the listed " \
"RuboCop cops." "RuboCop cops."
comma_array "--except-cops", comma_array "--except-cops",
description: "Specify a comma-separated <cops> list to skip checking for violations of the listed "\ description: "Specify a comma-separated <cops> list to skip checking for violations of the " \
"RuboCop cops." "listed RuboCop cops."
switch "--formula", "--formulae", switch "--formula", "--formulae",
description: "Treat all named arguments as formulae." description: "Treat all named arguments as formulae."
switch "--cask", "--casks", switch "--cask", "--casks",
@ -121,7 +121,7 @@ module Homebrew
# TODO: 3.6.0: odeprecate not specifying args.all?, require args.installed? # TODO: 3.6.0: odeprecate not specifying args.all?, require args.installed?
audit_formulae, audit_casks = if args.tap audit_formulae, audit_casks = if args.tap
Tap.fetch(args.tap).yield_self do |tap| Tap.fetch(args.tap).then do |tap|
[ [
tap.formula_names.map { |name| Formula[name] }, tap.formula_names.map { |name| Formula[name] },
tap.cask_files.map { |path| Cask::CaskLoader.load(path) }, tap.cask_files.map { |path| Cask::CaskLoader.load(path) },

View File

@ -58,22 +58,22 @@ module Homebrew
switch "--no-rebuild", switch "--no-rebuild",
description: "If the formula specifies a rebuild version, remove it from the generated DSL." description: "If the formula specifies a rebuild version, remove it from the generated DSL."
switch "--keep-old", switch "--keep-old",
description: "If the formula specifies a rebuild version, attempt to preserve its value in the "\ description: "If the formula specifies a rebuild version, attempt to preserve its value in the " \
"generated DSL." "generated DSL."
switch "--json", switch "--json",
description: "Write bottle information to a JSON file, which can be used as the value for "\ description: "Write bottle information to a JSON file, which can be used as the value for " \
"`--merge`." "`--merge`."
switch "--merge", switch "--merge",
description: "Generate an updated bottle block for a formula and optionally merge it into the "\ description: "Generate an updated bottle block for a formula and optionally merge it into the " \
"formula file. Instead of a formula name, requires the path to a JSON file generated with "\ "formula file. Instead of a formula name, requires the path to a JSON file generated " \
"`brew bottle --json` <formula>." "with `brew bottle --json` <formula>."
switch "--write", switch "--write",
depends_on: "--merge", depends_on: "--merge",
description: "Write changes to the formula file. A new commit will be generated unless "\ description: "Write changes to the formula file. A new commit will be generated unless " \
"`--no-commit` is passed." "`--no-commit` is passed."
switch "--no-commit", switch "--no-commit",
depends_on: "--write", depends_on: "--write",
description: "When passed with `--write`, a new commit will not generated after writing changes "\ description: "When passed with `--write`, a new commit will not generated after writing changes " \
"to the formula file." "to the formula file."
switch "--only-json-tab", switch "--only-json-tab",
depends_on: "--json", depends_on: "--json",
@ -83,7 +83,7 @@ module Homebrew
flag "--root-url=", flag "--root-url=",
description: "Use the specified <URL> as the root of the bottle's URL instead of Homebrew's default." description: "Use the specified <URL> as the root of the bottle's URL instead of Homebrew's default."
flag "--root-url-using=", flag "--root-url-using=",
description: "Use the specified download strategy class for downloading the bottle's URL instead of "\ description: "Use the specified download strategy class for downloading the bottle's URL instead of " \
"Homebrew's default." "Homebrew's default."
conflicts "--no-rebuild", "--keep-old" conflicts "--no-rebuild", "--keep-old"

View File

@ -26,7 +26,7 @@ module Homebrew
description: "Make the expected file modifications without taking any Git actions." description: "Make the expected file modifications without taking any Git actions."
switch "--commit", switch "--commit",
depends_on: "--write-only", depends_on: "--write-only",
description: "When passed with `--write-only`, generate a new commit after writing changes "\ description: "When passed with `--write-only`, generate a new commit after writing changes " \
"to the cask file." "to the cask file."
switch "--no-audit", switch "--no-audit",
description: "Don't run `brew audit` before opening the PR." description: "Don't run `brew audit` before opening the PR."
@ -67,7 +67,7 @@ module Homebrew
# As this command is simplifying user-run commands then let's just use a # As this command is simplifying user-run commands then let's just use a
# user path, too. # user path, too.
ENV["PATH"] = ENV["HOMEBREW_PATH"] ENV["PATH"] = PATH.new(ORIGINAL_PATHS).to_s
# Use the user's browser, too. # Use the user's browser, too.
ENV["BROWSER"] = Homebrew::EnvConfig.browser ENV["BROWSER"] = Homebrew::EnvConfig.browser

View File

@ -42,7 +42,7 @@ module Homebrew
switch "--write", hidden: true switch "--write", hidden: true
switch "--commit", switch "--commit",
depends_on: "--write-only", depends_on: "--write-only",
description: "When passed with `--write-only`, generate a new commit after writing changes "\ description: "When passed with `--write-only`, generate a new commit after writing changes " \
"to the formula file." "to the formula file."
switch "--no-audit", switch "--no-audit",
description: "Don't run `brew audit` before opening the PR." description: "Don't run `brew audit` before opening the PR."
@ -55,18 +55,18 @@ module Homebrew
switch "--no-fork", switch "--no-fork",
description: "Don't try to fork the repository." description: "Don't try to fork the repository."
comma_array "--mirror", comma_array "--mirror",
description: "Use the specified <URL> as a mirror URL. If <URL> is a comma-separated list "\ description: "Use the specified <URL> as a mirror URL. If <URL> is a comma-separated list " \
"of URLs, multiple mirrors will be added." "of URLs, multiple mirrors will be added."
flag "--fork-org=", flag "--fork-org=",
description: "Use the specified GitHub organization for forking." description: "Use the specified GitHub organization for forking."
flag "--version=", flag "--version=",
description: "Use the specified <version> to override the value parsed from the URL or tag. Note "\ description: "Use the specified <version> to override the value parsed from the URL or tag. Note " \
"that `--version=0` can be used to delete an existing version override from a "\ "that `--version=0` can be used to delete an existing version override from a " \
"formula if it has become redundant." "formula if it has become redundant."
flag "--message=", flag "--message=",
description: "Append <message> to the default pull request message." description: "Append <message> to the default pull request message."
flag "--url=", flag "--url=",
description: "Specify the <URL> for the new download. If a <URL> is specified, the <SHA-256> "\ description: "Specify the <URL> for the new download. If a <URL> is specified, the <SHA-256> " \
"checksum of the new download should also be specified." "checksum of the new download should also be specified."
flag "--sha256=", flag "--sha256=",
depends_on: "--url=", depends_on: "--url=",
@ -74,12 +74,12 @@ module Homebrew
flag "--tag=", flag "--tag=",
description: "Specify the new git commit <tag> for the formula." description: "Specify the new git commit <tag> for the formula."
flag "--revision=", flag "--revision=",
description: "Specify the new commit <revision> corresponding to the specified git <tag> "\ description: "Specify the new commit <revision> corresponding to the specified git <tag> " \
"or specified <version>." "or specified <version>."
switch "-f", "--force", switch "-f", "--force",
description: "Ignore duplicate open PRs. Remove all mirrors if `--mirror` was not specified." description: "Ignore duplicate open PRs. Remove all mirrors if `--mirror` was not specified."
flag "--python-package-name=", flag "--python-package-name=",
description: "Use the specified <package-name> when finding Python resources for <formula>. "\ description: "Use the specified <package-name> when finding Python resources for <formula>. " \
"If no package name is specified, it will be inferred from the formula's stable URL." "If no package name is specified, it will be inferred from the formula's stable URL."
comma_array "--python-extra-packages=", comma_array "--python-extra-packages=",
description: "Include these additional Python packages when finding resources." description: "Include these additional Python packages when finding resources."
@ -108,7 +108,7 @@ module Homebrew
# As this command is simplifying user-run commands then let's just use a # As this command is simplifying user-run commands then let's just use a
# user path, too. # user path, too.
ENV["PATH"] = ENV["HOMEBREW_PATH"] ENV["PATH"] = PATH.new(ORIGINAL_PATHS).to_s
# Use the user's browser, too. # Use the user's browser, too.
ENV["BROWSER"] = Homebrew::EnvConfig.browser ENV["BROWSER"] = Homebrew::EnvConfig.browser
@ -275,7 +275,7 @@ module Homebrew
if new_mirrors.present? if new_mirrors.present?
replacement_pairs << [ replacement_pairs << [
/^( +)(url "#{Regexp.escape(new_url)}"\n)/m, /^( +)(url "#{Regexp.escape(new_url)}"[^\n]*?\n)/m,
"\\1\\2\\1mirror \"#{new_mirrors.join("\"\n\\1mirror \"")}\"\n", "\\1\\2\\1mirror \"#{new_mirrors.join("\"\n\\1mirror \"")}\"\n",
] ]
end end
@ -293,7 +293,7 @@ module Homebrew
] ]
elsif new_url.present? elsif new_url.present?
[ [
/^( +)(url "#{Regexp.escape(new_url)}"\n)/m, /^( +)(url "#{Regexp.escape(new_url)}"[^\n]*?\n)/m,
"\\1\\2\\1version \"#{new_version}\"\n", "\\1\\2\\1version \"#{new_version}\"\n",
] ]
elsif new_revision.present? elsif new_revision.present?

View File

@ -36,7 +36,7 @@ module Homebrew
# As this command is simplifying user-run commands then let's just use a # As this command is simplifying user-run commands then let's just use a
# user path, too. # user path, too.
ENV["PATH"] = ENV["HOMEBREW_PATH"] ENV["PATH"] = PATH.new(ORIGINAL_PATHS).to_s
args.named.to_formulae.each do |formula| args.named.to_formulae.each do |formula|
current_revision = formula.revision current_revision = formula.revision

View File

@ -98,7 +98,7 @@ module Homebrew
return return
end end
last_check_time = state["check_time"]&.yield_self { |t| Time.parse(t) } last_check_time = state["check_time"]&.then { |t| Time.parse(t) }
check_time = Time.now check_time = Time.now
if last_check_time && check_time < (last_check_time + 1.day) if last_check_time && check_time < (last_check_time + 1.day)
@ -107,7 +107,7 @@ module Homebrew
end end
last_sha256 = state["sha256"] last_sha256 = state["sha256"]
last_time = state["time"]&.yield_self { |t| Time.parse(t) } last_time = state["time"]&.then { |t| Time.parse(t) }
last_file_size = state["file_size"] last_file_size = state["file_size"]
download = Cask::Download.new(cask) download = Cask::Download.new(cask)

View File

@ -61,9 +61,7 @@ module Homebrew
unless Utils::Curl.curl_supports_tls13? unless Utils::Curl.curl_supports_tls13?
begin begin
unless Pathname.new(ENV["HOMEBREW_BREWED_CURL_PATH"]).exist? ensure_formula_installed!("curl", reason: "Repology queries") unless HOMEBREW_BREWED_CURL_PATH.exist?
ensure_formula_installed!("curl", reason: "Repology queries")
end
rescue FormulaUnavailableError rescue FormulaUnavailableError
opoo "A newer `curl` is required for Repology queries." opoo "A newer `curl` is required for Repology queries."
end end

View File

@ -46,8 +46,8 @@ module Homebrew
switch "--rust", switch "--rust",
description: "Create a basic template for a Rust build." description: "Create a basic template for a Rust build."
switch "--no-fetch", switch "--no-fetch",
description: "Homebrew will not download <URL> to the cache and will thus not add its SHA-256 "\ description: "Homebrew will not download <URL> to the cache and will thus not add its SHA-256 " \
"to the formula for you, nor will it check the GitHub API for GitHub projects "\ "to the formula for you, nor will it check the GitHub API for GitHub projects " \
"(to fill out its description and homepage)." "(to fill out its description and homepage)."
switch "--HEAD", switch "--HEAD",
description: "Indicate that <URL> points to the package's repository rather than a file." description: "Indicate that <URL> points to the package's repository rather than a file."

View File

@ -52,7 +52,7 @@ module Homebrew
if (macos = args.macos&.compact_blank) && macos.present? if (macos = args.macos&.compact_blank) && macos.present?
runners += macos.map do |element| runners += macos.map do |element|
# We accept runner name syntax (11-arm64) or bottle syntax (arm64_big_sur) # We accept runner name syntax (11-arm64) or bottle syntax (arm64_big_sur)
os, arch = element.yield_self do |s| os, arch = element.then do |s|
tag = Utils::Bottles::Tag.from_symbol(s.to_sym) tag = Utils::Bottles::Tag.from_symbol(s.to_sym)
[tag.to_macos_version, tag.arch] [tag.to_macos_version, tag.arch]
rescue ArgumentError, MacOSVersionError rescue ArgumentError, MacOSVersionError

View File

@ -23,9 +23,9 @@ module Homebrew
Generate Homebrew's manpages and shell completions. Generate Homebrew's manpages and shell completions.
EOS EOS
switch "--fail-if-not-changed", switch "--fail-if-not-changed",
description: "Return a failing status code if no changes are detected in the manpage outputs. "\ description: "Return a failing status code if no changes are detected in the manpage outputs. " \
"This can be used to notify CI when the manpages are out of date. Additionally, "\ "This can be used to notify CI when the manpages are out of date. Additionally, " \
"the date used in new manpages will match those in the existing manpages (to allow "\ "the date used in new manpages will match those in the existing manpages (to allow " \
"comparison without factoring in the date)." "comparison without factoring in the date)."
named_args :none named_args :none
end end

View File

@ -18,16 +18,16 @@ module Homebrew
provided, check all kegs. Raises an error if run on uninstalled formulae. provided, check all kegs. Raises an error if run on uninstalled formulae.
EOS EOS
switch "--test", switch "--test",
description: "Show only missing libraries and exit with a non-zero status if any missing "\ description: "Show only missing libraries and exit with a non-zero status if any missing " \
"libraries are found." "libraries are found."
switch "--strict", switch "--strict",
depends_on: "--test", depends_on: "--test",
description: "Exit with a non-zero status if any undeclared dependencies with linkage are found." description: "Exit with a non-zero status if any undeclared dependencies with linkage are found."
switch "--reverse", switch "--reverse",
description: "For every library that a keg references, print its dylib path followed by the "\ description: "For every library that a keg references, print its dylib path followed by the " \
"binaries that link to it." "binaries that link to it."
switch "--cached", switch "--cached",
description: "Print the cached linkage values stored in `HOMEBREW_CACHE`, set by a previous "\ description: "Print the cached linkage values stored in `HOMEBREW_CACHE`, set by a previous " \
"`brew linkage` run." "`brew linkage` run."
named_args :installed_formula named_args :installed_formula

View File

@ -11,10 +11,7 @@ module Homebrew
module_function module_function
WATCHLIST_PATH = ( WATCHLIST_PATH = File.expand_path(Homebrew::EnvConfig.livecheck_watchlist).freeze
ENV["HOMEBREW_LIVECHECK_WATCHLIST"] ||
"#{Dir.home}/.brew_livecheck_watchlist"
).freeze
sig { returns(CLI::Parser) } sig { returns(CLI::Parser) }
def livecheck_args def livecheck_args
@ -58,7 +55,7 @@ module Homebrew
if args.debug? && args.verbose? if args.debug? && args.verbose?
puts args puts args
puts ENV["HOMEBREW_LIVECHECK_WATCHLIST"] if ENV["HOMEBREW_LIVECHECK_WATCHLIST"].present? puts Homebrew::EnvConfig.livecheck_watchlist if Homebrew::EnvConfig.livecheck_watchlist.present?
end end
formulae_and_casks_to_check = if args.tap formulae_and_casks_to_check = if args.tap

View File

@ -22,14 +22,14 @@ module Homebrew
flag "--with-label=", flag "--with-label=",
description: "Pull requests must have this label." description: "Pull requests must have this label."
comma_array "--without-labels", comma_array "--without-labels",
description: "Pull requests must not have these labels (default: "\ description: "Pull requests must not have these labels (default: " \
"`do not merge`, `new formula`, `automerge-skip`)." "`do not merge`, `new formula`, `automerge-skip`)."
switch "--without-approval", switch "--without-approval",
description: "Pull requests do not require approval to be merged." description: "Pull requests do not require approval to be merged."
switch "--publish", switch "--publish",
description: "Run `brew pr-publish` on matching pull requests." description: "Run `brew pr-publish` on matching pull requests."
switch "--no-autosquash", switch "--no-autosquash",
description: "Instruct `brew pr-publish` to skip automatically reformatting and rewording commits "\ description: "Instruct `brew pr-publish` to skip automatically reformatting and rewording commits " \
"in the pull request to the preferred format." "in the pull request to the preferred format."
switch "--ignore-failures", switch "--ignore-failures",
description: "Include pull requests that have failing status checks." description: "Include pull requests that have failing status checks."

View File

@ -17,7 +17,7 @@ module Homebrew
Requires write access to the repository. Requires write access to the repository.
EOS EOS
switch "--no-autosquash", switch "--no-autosquash",
description: "Skip automatically reformatting and rewording commits in the pull request "\ description: "Skip automatically reformatting and rewording commits in the pull request " \
"to the preferred format, even if supported on the target tap." "to the preferred format, even if supported on the target tap."
flag "--branch=", flag "--branch=",
description: "Branch to publish to (default: `master`)." description: "Branch to publish to (default: `master`)."

View File

@ -33,15 +33,15 @@ module Homebrew
description: "If the formula specifies a rebuild version, " \ description: "If the formula specifies a rebuild version, " \
"attempt to preserve its value in the generated DSL." "attempt to preserve its value in the generated DSL."
switch "--no-autosquash", switch "--no-autosquash",
description: "Skip automatically reformatting and rewording commits in the pull request to our "\ description: "Skip automatically reformatting and rewording commits in the pull request to our " \
"preferred format." "preferred format."
switch "--branch-okay", switch "--branch-okay",
description: "Do not warn if pulling to a branch besides the repository default (useful for testing)." description: "Do not warn if pulling to a branch besides the repository default (useful for testing)."
switch "--resolve", switch "--resolve",
description: "When a patch fails to apply, leave in progress and allow user to resolve, "\ description: "When a patch fails to apply, leave in progress and allow user to resolve, " \
"instead of aborting." "instead of aborting."
switch "--warn-on-upload-failure", switch "--warn-on-upload-failure",
description: "Warn instead of raising an error if the bottle upload fails. "\ description: "Warn instead of raising an error if the bottle upload fails. " \
"Useful for repairing bottle uploads that previously failed." "Useful for repairing bottle uploads that previously failed."
flag "--committer=", flag "--committer=",
description: "Specify a committer name and email in `git`'s standard author format." description: "Specify a committer name and email in `git`'s standard author format."
@ -54,10 +54,10 @@ module Homebrew
flag "--root-url=", flag "--root-url=",
description: "Use the specified <URL> as the root of the bottle's URL instead of Homebrew's default." description: "Use the specified <URL> as the root of the bottle's URL instead of Homebrew's default."
flag "--root-url-using=", flag "--root-url-using=",
description: "Use the specified download strategy class for downloading the bottle's URL instead of "\ description: "Use the specified download strategy class for downloading the bottle's URL instead of " \
"Homebrew's default." "Homebrew's default."
comma_array "--workflows=", comma_array "--workflows=",
description: "Retrieve artifacts from the specified workflow (default: `tests.yml`). "\ description: "Retrieve artifacts from the specified workflow (default: `tests.yml`). " \
"Can be a comma-separated list to include multiple workflows." "Can be a comma-separated list to include multiple workflows."
comma_array "--ignore-missing-artifacts=", comma_array "--ignore-missing-artifacts=",
description: "Comma-separated list of workflows which can be ignored if they have not been run." description: "Comma-separated list of workflows which can be ignored if they have not been run."

View File

@ -24,7 +24,7 @@ module Homebrew
switch "--no-commit", switch "--no-commit",
description: "Do not generate a new commit before uploading." description: "Do not generate a new commit before uploading."
switch "--warn-on-upload-failure", switch "--warn-on-upload-failure",
description: "Warn instead of raising an error if the bottle upload fails. "\ description: "Warn instead of raising an error if the bottle upload fails. " \
"Useful for repairing bottle uploads that previously failed." "Useful for repairing bottle uploads that previously failed."
switch "--upload-only", switch "--upload-only",
description: "Skip running `brew bottle` before uploading." description: "Skip running `brew bottle` before uploading."
@ -34,7 +34,7 @@ module Homebrew
flag "--root-url=", flag "--root-url=",
description: "Use the specified <URL> as the root of the bottle's URL instead of Homebrew's default." description: "Use the specified <URL> as the root of the bottle's URL instead of Homebrew's default."
flag "--root-url-using=", flag "--root-url-using=",
description: "Use the specified download strategy class for downloading the bottle's URL instead of "\ description: "Use the specified download strategy class for downloading the bottle's URL instead of " \
"Homebrew's default." "Homebrew's default."
conflicts "--upload-only", "--keep-old" conflicts "--upload-only", "--keep-old"

View File

@ -32,7 +32,7 @@ module Homebrew
if args.stackprof? if args.stackprof?
Homebrew.install_gem_setup_path! "stackprof" Homebrew.install_gem_setup_path! "stackprof"
with_env HOMEBREW_STACKPROF: "1" do with_env HOMEBREW_STACKPROF: "1" do
system ENV["HOMEBREW_RUBY_PATH"], brew_rb, *args.named system RUBY_PATH, brew_rb, *args.named
end end
output_filename = "prof/d3-flamegraph.html" output_filename = "prof/d3-flamegraph.html"
safe_system "stackprof --d3-flamegraph prof/stackprof.dump > #{output_filename}" safe_system "stackprof --d3-flamegraph prof/stackprof.dump > #{output_filename}"

View File

@ -33,10 +33,9 @@ module Homebrew
ruby_sys_args << "-e #{args.e}" if args.e ruby_sys_args << "-e #{args.e}" if args.e
ruby_sys_args += args.named ruby_sys_args += args.named
exec RUBY_PATH, exec(*HOMEBREW_RUBY_EXEC_ARGS,
ENV["HOMEBREW_RUBY_WARNINGS"],
"-I", $LOAD_PATH.join(File::PATH_SEPARATOR), "-I", $LOAD_PATH.join(File::PATH_SEPARATOR),
"-rglobal", "-rdev-cmd/irb", "-rglobal", "-rdev-cmd/irb",
*ruby_sys_args *ruby_sys_args)
end end
end end

View File

@ -38,22 +38,24 @@ module Homebrew
ENV.setup_build_environment ENV.setup_build_environment
if superenv?(args.env) if superenv?(args.env)
# superenv stopped adding brew's bin but generally users will want it # superenv stopped adding brew's bin but generally users will want it
ENV["PATH"] = PATH.new(ENV["PATH"]).insert(1, HOMEBREW_PREFIX/"bin") ENV["PATH"] = PATH.new(ENV.fetch("PATH")).insert(1, HOMEBREW_PREFIX/"bin")
end end
ENV["VERBOSE"] = "1" if args.verbose? ENV["VERBOSE"] = "1" if args.verbose?
if args.cmd.present? if args.cmd.present?
safe_system(ENV["SHELL"], "-c", args.cmd) safe_system(preferred_shell, "-c", args.cmd)
elsif args.named.present? elsif args.named.present?
safe_system(ENV["SHELL"], args.named.first) safe_system(preferred_shell, args.named.first)
else else
subshell = if ENV["SHELL"].include?("zsh") shell_type = Utils::Shell.preferred
"PS1='brew %B%F{green}%~%f%b$ ' #{ENV["SHELL"]} -d -f" subshell = case shell_type
elsif ENV["SHELL"].include?("bash") when :zsh
"PS1=\"brew \\[\\033[1;32m\\]\\w\\[\\033[0m\\]$ \" #{ENV["SHELL"]} --noprofile --norc" "PS1='brew %B%F{green}%~%f%b$ ' #{preferred_shell} -d -f"
when :bash
"PS1=\"brew \\[\\033[1;32m\\]\\w\\[\\033[0m\\]$ \" #{preferred_shell} --noprofile --norc"
else else
"PS1=\"brew \\[\\033[1;32m\\]\\w\\[\\033[0m\\]$ \" #{ENV["SHELL"]}" "PS1=\"brew \\[\\033[1;32m\\]\\w\\[\\033[0m\\]$ \" #{preferred_shell}"
end end
puts <<~EOS puts <<~EOS
Your shell has been configured to use Homebrew's build environment; Your shell has been configured to use Homebrew's build environment;

View File

@ -32,10 +32,10 @@ module Homebrew
switch "--cask", "--casks", switch "--cask", "--casks",
description: "Treat all named arguments as casks." description: "Treat all named arguments as casks."
comma_array "--only-cops", comma_array "--only-cops",
description: "Specify a comma-separated <cops> list to check for violations of only the "\ description: "Specify a comma-separated <cops> list to check for violations of only the " \
"listed RuboCop cops." "listed RuboCop cops."
comma_array "--except-cops", comma_array "--except-cops",
description: "Specify a comma-separated <cops> list to skip checking for violations of the "\ description: "Specify a comma-separated <cops> list to skip checking for violations of the " \
"listed RuboCop cops." "listed RuboCop cops."
conflicts "--formula", "--cask" conflicts "--formula", "--cask"

View File

@ -22,14 +22,14 @@ module Homebrew
switch "--no-compat", switch "--no-compat",
description: "Do not load the compatibility layer when running tests." description: "Do not load the compatibility layer when running tests."
switch "--online", switch "--online",
description: "Include tests that use the GitHub API and tests that use any of the taps for "\ description: "Include tests that use the GitHub API and tests that use any of the taps for " \
"official external commands." "official external commands."
switch "--byebug", switch "--byebug",
description: "Enable debugging using byebug." description: "Enable debugging using byebug."
switch "--changed", switch "--changed",
description: "Only runs tests on files that were changed from the master branch." description: "Only runs tests on files that were changed from the master branch."
flag "--only=", flag "--only=",
description: "Run only <test_script>`_spec.rb`. Appending `:`<line_number> will start at a "\ description: "Run only <test_script>`_spec.rb`. Appending `:`<line_number> will start at a " \
"specific line." "specific line."
flag "--seed=", flag "--seed=",
description: "Randomise tests with the specified <value> instead of a random seed." description: "Randomise tests with the specified <value> instead of a random seed."
@ -57,15 +57,15 @@ module Homebrew
reason: "reporting test flakiness") reason: "reporting test flakiness")
end end
ENV["BUILDPULSE_ACCESS_KEY_ID"] = ENV["HOMEBREW_BUILDPULSE_ACCESS_KEY_ID"] ENV["BUILDPULSE_ACCESS_KEY_ID"] = ENV.fetch("HOMEBREW_BUILDPULSE_ACCESS_KEY_ID")
ENV["BUILDPULSE_SECRET_ACCESS_KEY"] = ENV["HOMEBREW_BUILDPULSE_SECRET_ACCESS_KEY"] ENV["BUILDPULSE_SECRET_ACCESS_KEY"] = ENV.fetch("HOMEBREW_BUILDPULSE_SECRET_ACCESS_KEY")
ohai "Sending test results to BuildPulse" ohai "Sending test results to BuildPulse"
safe_system Formula["buildpulse-test-reporter"].opt_bin/"buildpulse-test-reporter", safe_system Formula["buildpulse-test-reporter"].opt_bin/"buildpulse-test-reporter",
"submit", "#{HOMEBREW_LIBRARY_PATH}/test/junit", "submit", "#{HOMEBREW_LIBRARY_PATH}/test/junit",
"--account-id", ENV["HOMEBREW_BUILDPULSE_ACCOUNT_ID"], "--account-id", ENV.fetch("HOMEBREW_BUILDPULSE_ACCOUNT_ID"),
"--repository-id", ENV["HOMEBREW_BUILDPULSE_REPOSITORY_ID"] "--repository-id", ENV.fetch("HOMEBREW_BUILDPULSE_REPOSITORY_ID")
end end
def changed_test_files def changed_test_files
@ -212,7 +212,7 @@ module Homebrew
ENV["HOMEBREW_TESTS_GEM_USER_DIR"] = gem_user_dir ENV["HOMEBREW_TESTS_GEM_USER_DIR"] = gem_user_dir
# Let `bundle` in PATH find its gem. # Let `bundle` in PATH find its gem.
ENV["GEM_PATH"] = "#{ENV["GEM_PATH"]}:#{gem_user_dir}" ENV["GEM_PATH"] = "#{ENV.fetch("GEM_PATH")}:#{gem_user_dir}"
# Submit test flakiness information using BuildPulse # Submit test flakiness information using BuildPulse
# BUILDPULSE used in spec_helper.rb # BUILDPULSE used in spec_helper.rb

View File

@ -114,7 +114,7 @@ module Homebrew
end.compact end.compact
@sort = " (sorted by installs in the last 90 days; top 10,000 only)" @sort = " (sorted by installs in the last 90 days; top 10,000 only)"
all_formulae = Formula all_formulae = Formula.all
end end
[formulae, all_formulae, formula_installs] [formulae, all_formulae, formula_installs]

View File

@ -22,7 +22,7 @@ module Homebrew
switch "--patch", switch "--patch",
description: "Patches for <formula> will be applied to the unpacked source." description: "Patches for <formula> will be applied to the unpacked source."
switch "-g", "--git", switch "-g", "--git",
description: "Initialise a Git repository in the unpacked source. This is useful for creating "\ description: "Initialise a Git repository in the unpacked source. This is useful for creating " \
"patches for the software." "patches for the software."
switch "-f", "--force", switch "-f", "--force",
description: "Overwrite the destination directory if it already exists." description: "Overwrite the destination directory if it already exists."

View File

@ -22,10 +22,10 @@ module Homebrew
switch "--ignore-non-pypi-packages", switch "--ignore-non-pypi-packages",
description: "Don't fail if <formula> is not a PyPI package." description: "Don't fail if <formula> is not a PyPI package."
flag "--version=", flag "--version=",
description: "Use the specified <version> when finding resources for <formula>. "\ description: "Use the specified <version> when finding resources for <formula>. " \
"If no version is specified, the current version for <formula> will be used." "If no version is specified, the current version for <formula> will be used."
flag "--package-name=", flag "--package-name=",
description: "Use the specified <package-name> when finding resources for <formula>. "\ description: "Use the specified <package-name> when finding resources for <formula>. " \
"If no package name is specified, it will be inferred from the formula's stable URL." "If no package name is specified, it will be inferred from the formula's stable URL."
comma_array "--extra-packages=", comma_array "--extra-packages=",
description: "Include these additional packages when finding resources." description: "Include these additional packages when finding resources."

View File

@ -123,7 +123,7 @@ module Homebrew
safe_system "git", "reset", "--hard", start_commit safe_system "git", "reset", "--hard", start_commit
# update ENV["PATH"] # update ENV["PATH"]
ENV["PATH"] = PATH.new(ENV["PATH"]).prepend(curdir/"bin") ENV["PATH"] = PATH.new(ENV.fetch("PATH")).prepend(curdir/"bin")
# run brew help to install portable-ruby (if needed) # run brew help to install portable-ruby (if needed)
quiet_system "brew", "help" quiet_system "brew", "help"

View File

@ -118,7 +118,7 @@ class DevelopmentTools
sig { returns(T::Hash[String, T.nilable(String)]) } sig { returns(T::Hash[String, T.nilable(String)]) }
def build_system_info def build_system_info
{ {
"os" => ENV["HOMEBREW_SYSTEM"], "os" => HOMEBREW_SYSTEM,
"os_version" => OS_VERSION, "os_version" => OS_VERSION,
"cpu_family" => Hardware::CPU.family.to_s, "cpu_family" => Hardware::CPU.family.to_s,
} }

View File

@ -70,7 +70,7 @@ module Homebrew
end end
def user_tilde(path) def user_tilde(path)
path.gsub(ENV["HOME"], "~") path.gsub(Dir.home, "~")
end end
sig { returns(String) } sig { returns(String) }
@ -541,7 +541,7 @@ module Homebrew
end end
def check_git_version def check_git_version
minimum_version = ENV["HOMEBREW_MINIMUM_GIT_VERSION"] minimum_version = ENV.fetch("HOMEBREW_MINIMUM_GIT_VERSION")
return unless Utils::Git.available? return unless Utils::Git.available?
return if Version.create(Utils::Git.version) >= Version.create(minimum_version) return if Version.create(Utils::Git.version) >= Version.create(minimum_version)
@ -668,7 +668,7 @@ module Homebrew
end end
def check_tmpdir def check_tmpdir
tmpdir = ENV["TMPDIR"] tmpdir = ENV.fetch("TMPDIR", nil)
return if tmpdir.nil? || File.directory?(tmpdir) return if tmpdir.nil? || File.directory?(tmpdir)
<<~EOS <<~EOS
@ -766,7 +766,7 @@ module Homebrew
end end
def check_for_pydistutils_cfg_in_home def check_for_pydistutils_cfg_in_home
return unless File.exist? "#{ENV["HOME"]}/.pydistutils.cfg" return unless File.exist? "#{Dir.home}/.pydistutils.cfg"
<<~EOS <<~EOS
A '.pydistutils.cfg' file was found in $HOME, which may cause Python A '.pydistutils.cfg' file was found in $HOME, which may cause Python
@ -828,7 +828,7 @@ module Homebrew
cmd_map.reject! { |_cmd_name, cmd_paths| cmd_paths.size == 1 } cmd_map.reject! { |_cmd_name, cmd_paths| cmd_paths.size == 1 }
return if cmd_map.empty? return if cmd_map.empty?
if ENV["CI"] && cmd_map.keys.length == 1 && if ENV["CI"].present? && cmd_map.keys.length == 1 &&
cmd_map.keys.first == "brew-test-bot" cmd_map.keys.first == "brew-test-bot"
return return
end end
@ -1007,7 +1007,7 @@ module Homebrew
add_info "Cask Environment Variables:", ((locale_variables + environment_variables).sort.each do |var| add_info "Cask Environment Variables:", ((locale_variables + environment_variables).sort.each do |var|
next unless ENV.key?(var) next unless ENV.key?(var)
var = %Q(#{var}="#{ENV[var]}") var = %Q(#{var}="#{ENV.fetch(var)}")
user_tilde(var) user_tilde(var)
end) end)
end end

View File

@ -1139,7 +1139,7 @@ class CVSDownloadStrategy < VCSDownloadStrategy
private private
def env def env
{ "PATH" => PATH.new("/usr/bin", Formula["cvs"].opt_bin, ENV["PATH"]) } { "PATH" => PATH.new("/usr/bin", Formula["cvs"].opt_bin, ENV.fetch("PATH")) }
end end
sig { returns(String) } sig { returns(String) }
@ -1214,7 +1214,7 @@ class MercurialDownloadStrategy < VCSDownloadStrategy
private private
def env def env
{ "PATH" => PATH.new(Formula["mercurial"].opt_bin, ENV["PATH"]) } { "PATH" => PATH.new(Formula["mercurial"].opt_bin, ENV.fetch("PATH")) }
end end
sig { returns(String) } sig { returns(String) }
@ -1280,7 +1280,7 @@ class BazaarDownloadStrategy < VCSDownloadStrategy
def env def env
{ {
"PATH" => PATH.new(Formula["bazaar"].opt_bin, ENV["PATH"]), "PATH" => PATH.new(Formula["bazaar"].opt_bin, ENV.fetch("PATH")),
"BZR_HOME" => HOMEBREW_TEMP, "BZR_HOME" => HOMEBREW_TEMP,
} }
end end
@ -1345,7 +1345,7 @@ class FossilDownloadStrategy < VCSDownloadStrategy
private private
def env def env
{ "PATH" => PATH.new(Formula["fossil"].opt_bin, ENV["PATH"]) } { "PATH" => PATH.new(Formula["fossil"].opt_bin, ENV.fetch("PATH")) }
end end
sig { returns(String) } sig { returns(String) }

View File

@ -49,7 +49,7 @@ module Homebrew
default_text: "`$BAT_THEME`.", default_text: "`$BAT_THEME`.",
}, },
HOMEBREW_BOOTSNAP: { HOMEBREW_BOOTSNAP: {
description: "If set, use Bootsnap to speed up repeated `brew` calls. "\ description: "If set, use Bootsnap to speed up repeated `brew` calls. " \
"A no-op when using Homebrew's vendored, relocatable Ruby on macOS (as it doesn't work).", "A no-op when using Homebrew's vendored, relocatable Ruby on macOS (as it doesn't work).",
boolean: true, boolean: true,
}, },
@ -82,8 +82,8 @@ module Homebrew
description: "Append these options to all `cask` commands. All `--*dir` options, " \ description: "Append these options to all `cask` commands. All `--*dir` options, " \
"`--language`, `--require-sha`, `--no-quarantine` and `--no-binaries` are supported. " \ "`--language`, `--require-sha`, `--no-quarantine` and `--no-binaries` are supported. " \
"For example, you might add something like the following to your " \ "For example, you might add something like the following to your " \
"`~/.profile`, `~/.bash_profile`, or `~/.zshenv`:\n\n" \ "`~/.profile`, `~/.bash_profile`, or `~/.zshenv`:" \
' `export HOMEBREW_CASK_OPTS="--appdir=~/Applications --fontdir=/Library/Fonts"`', '\n\n `export HOMEBREW_CASK_OPTS="--appdir=~/Applications --fontdir=/Library/Fonts"`',
}, },
HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS: { HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS: {
description: "If set, `brew install`, `brew upgrade` and `brew reinstall` will cleanup all formulae " \ description: "If set, `brew install`, `brew upgrade` and `brew reinstall` will cleanup all formulae " \
@ -184,7 +184,7 @@ module Homebrew
"developer commands may require additional permissions.", "developer commands may require additional permissions.",
}, },
HOMEBREW_GITHUB_PACKAGES_TOKEN: { HOMEBREW_GITHUB_PACKAGES_TOKEN: {
description: "Use this GitHub personal access token when accessing the GitHub Packages Registry "\ description: "Use this GitHub personal access token when accessing the GitHub Packages Registry " \
"(where bottles may be stored).", "(where bottles may be stored).",
}, },
HOMEBREW_DOCKER_REGISTRY_BASIC_AUTH_TOKEN: { HOMEBREW_DOCKER_REGISTRY_BASIC_AUTH_TOKEN: {
@ -223,7 +223,8 @@ module Homebrew
HOMEBREW_LIVECHECK_WATCHLIST: { HOMEBREW_LIVECHECK_WATCHLIST: {
description: "Consult this file for the list of formulae to check by default when no formula argument " \ description: "Consult this file for the list of formulae to check by default when no formula argument " \
"is passed to `brew livecheck`.", "is passed to `brew livecheck`.",
default: "$HOME/.brew_livecheck_watchlist", default_text: "`$HOME/.brew_livecheck_watchlist`",
default: "~/.brew_livecheck_watchlist",
}, },
HOMEBREW_LOGS: { HOMEBREW_LOGS: {
description: "Use this directory to store log files.", description: "Use this directory to store log files.",
@ -257,7 +258,7 @@ module Homebrew
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: { HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: {
description: "If set, do not check for broken linkage of dependents or outdated dependents after " \ description: "If set, do not check for broken linkage of dependents or outdated dependents after " \
"installing, upgrading or reinstalling formulae. This will result in fewer dependents " \ "installing, upgrading or reinstalling formulae. This will result in fewer dependents " \
" (and their dependencies) being upgraded or reinstalled but may result in more breakage " \ "(and their dependencies) being upgraded or reinstalled but may result in more breakage " \
"from running `brew install <formula>` or `brew upgrade <formula>`.", "from running `brew install <formula>` or `brew upgrade <formula>`.",
boolean: true, boolean: true,
}, },

View File

@ -28,7 +28,7 @@ module Stdenv
self["HOMEBREW_ENV"] = "std" self["HOMEBREW_ENV"] = "std"
PATH.new(ENV["HOMEBREW_PATH"]).reverse_each { |p| prepend_path "PATH", p } ORIGINAL_PATHS.reverse_each { |p| prepend_path "PATH", p }
prepend_path "PATH", HOMEBREW_SHIMS_PATH/"shared" prepend_path "PATH", HOMEBREW_SHIMS_PATH/"shared"
# Set the default pkg-config search path, overriding the built-in paths # Set the default pkg-config search path, overriding the built-in paths

View File

@ -1,26 +0,0 @@
# typed: strict
# frozen_string_literal: true
module OnOS
extend T::Sig
# Block only executed on macOS. No-op on Linux.
# <pre>on_macos do
# # Do something Mac-specific
# end</pre>
sig { params(block: T.proc.void).void }
def on_macos(&block)
raise "No block content defined for 'on_macos' block" unless T.unsafe(block)
end
# Block only executed on Linux. No-op on macOS.
# <pre>on_linux do
# # Do something Linux-specific
# end</pre>
sig { params(block: T.proc.void).void }
def on_linux(&block)
raise "No block content defined for 'on_linux' block" unless T.unsafe(block)
end
end
require "extend/os/on_os"

View File

@ -1,5 +0,0 @@
# typed: strict
module OnOS
include Kernel
end

View File

@ -0,0 +1,103 @@
# typed: false
# frozen_string_literal: true
require "simulate_system"
module OnSystem
extend T::Sig
ARCH_OPTIONS = [:intel, :arm].freeze
BASE_OS_OPTIONS = [:macos, :linux].freeze
module_function
sig { params(arch: Symbol).returns(T::Boolean) }
def arch_condition_met?(arch)
raise ArgumentError, "Invalid arch condition: #{arch.inspect}" if ARCH_OPTIONS.exclude?(arch)
current_arch = Homebrew::SimulateSystem.arch || Hardware::CPU.type
arch == current_arch
end
sig { params(os_name: Symbol, or_condition: T.nilable(Symbol)).returns(T::Boolean) }
def os_condition_met?(os_name, or_condition = nil)
if Homebrew::EnvConfig.simulate_macos_on_linux?
return false if os_name == :linux
return true if [:macos, *MacOSVersions::SYMBOLS.keys].include?(os_name)
end
if BASE_OS_OPTIONS.include?(os_name)
if Homebrew::SimulateSystem.none?
return OS.linux? if os_name == :linux
return OS.mac? if os_name == :macos
end
return Homebrew::SimulateSystem.send("#{os_name}?")
end
raise ArgumentError, "Invalid OS condition: #{os_name.inspect}" unless MacOSVersions::SYMBOLS.key?(os_name)
if or_condition.present? && [:or_newer, :or_older].exclude?(or_condition)
raise ArgumentError, "Invalid OS `or_*` condition: #{or_condition.inspect}"
end
base_os = MacOS::Version.from_symbol(os_name)
current_os = MacOS::Version.from_symbol(Homebrew::SimulateSystem.os || MacOS.version.to_sym)
return current_os >= base_os if or_condition == :or_newer
return current_os <= base_os if or_condition == :or_older
current_os == base_os
end
sig { params(method_name: Symbol).returns(Symbol) }
def condition_from_method_name(method_name)
method_name.to_s.sub(/^on_/, "").to_sym
end
sig { params(base: Class).void }
def self.included(base)
ARCH_OPTIONS.each do |arch|
base.define_method("on_#{arch}") do |&block|
@on_system_blocks_exist = true
return unless OnSystem.arch_condition_met? OnSystem.condition_from_method_name(__method__)
@called_in_on_system_block = true
result = block.call
@called_in_on_system_block = false
result
end
end
BASE_OS_OPTIONS.each do |base_os|
base.define_method("on_#{base_os}") do |&block|
@on_system_blocks_exist = true
return unless OnSystem.os_condition_met? OnSystem.condition_from_method_name(__method__)
@called_in_on_system_block = true
result = block.call
@called_in_on_system_block = false
result
end
end
MacOSVersions::SYMBOLS.each_key do |os_name|
base.define_method("on_#{os_name}") do |or_condition = nil, &block|
@on_system_blocks_exist = true
os_condition = OnSystem.condition_from_method_name __method__
return unless OnSystem.os_condition_met? os_condition, or_condition
@called_in_on_system_block = true
result = block.call
@called_in_on_system_block = false
result
end
end
end
end

View File

@ -1,10 +0,0 @@
# typed: strict
# frozen_string_literal: true
module OnOS
def on_linux(&block)
raise "No block content defined for 'on_linux' block" unless T.unsafe(block)
yield
end
end

View File

@ -1,10 +0,0 @@
# typed: strict
# frozen_string_literal: true
module OnOS
def on_macos(&block)
raise "No block content defined for 'on_macos' block" unless T.unsafe(block)
yield
end
end

View File

@ -1,8 +0,0 @@
# typed: strict
# frozen_string_literal: true
if OS.mac? || Homebrew::EnvConfig.simulate_macos_on_linux?
require "extend/os/mac/on_os"
elsif OS.linux?
require "extend/os/linux/on_os"
end

View File

@ -28,7 +28,7 @@ require "tab"
require "mktemp" require "mktemp"
require "find" require "find"
require "utils/spdx" require "utils/spdx"
require "extend/on_os" require "extend/on_system"
require "api" require "api"
# A formula provides instructions and metadata for Homebrew to install a piece # A formula provides instructions and metadata for Homebrew to install a piece
@ -64,7 +64,7 @@ class Formula
include Utils::Shebang include Utils::Shebang
include Utils::Shell include Utils::Shell
include Context include Context
include OnOS include OnSystem
extend Forwardable extend Forwardable
extend Cachable extend Cachable
extend Predicable extend Predicable
@ -421,9 +421,9 @@ class Formula
return unless head.downloader.cached_location.exist? return unless head.downloader.cached_location.exist?
path = if ENV["HOMEBREW_ENV"] path = if ENV["HOMEBREW_ENV"]
ENV["PATH"] ENV.fetch("PATH")
else else
ENV["HOMEBREW_PATH"] PATH.new(ORIGINAL_PATHS)
end end
with_env(PATH: path) do with_env(PATH: path) do
@ -1103,7 +1103,7 @@ class Formula
TMP: HOMEBREW_TEMP, TMP: HOMEBREW_TEMP,
_JAVA_OPTIONS: "-Djava.io.tmpdir=#{HOMEBREW_TEMP}", _JAVA_OPTIONS: "-Djava.io.tmpdir=#{HOMEBREW_TEMP}",
HOMEBREW_PATH: nil, HOMEBREW_PATH: nil,
PATH: ENV["HOMEBREW_PATH"], PATH: PATH.new(ORIGINAL_PATHS),
} }
with_env(new_env) do with_env(new_env) do
@ -2077,7 +2077,7 @@ class Formula
TEMP: HOMEBREW_TEMP, TEMP: HOMEBREW_TEMP,
TMP: HOMEBREW_TEMP, TMP: HOMEBREW_TEMP,
TERM: "dumb", TERM: "dumb",
PATH: PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin"), PATH: PATH.new(ENV.fetch("PATH"), HOMEBREW_PREFIX/"bin"),
HOMEBREW_PATH: nil, HOMEBREW_PATH: nil,
}.merge(common_stage_test_env) }.merge(common_stage_test_env)
test_env[:_JAVA_OPTIONS] += " -Djava.io.tmpdir=#{HOMEBREW_TEMP}" test_env[:_JAVA_OPTIONS] += " -Djava.io.tmpdir=#{HOMEBREW_TEMP}"
@ -2433,7 +2433,7 @@ class Formula
GOCACHE: "#{HOMEBREW_CACHE}/go_cache", GOCACHE: "#{HOMEBREW_CACHE}/go_cache",
GOPATH: "#{HOMEBREW_CACHE}/go_mod_cache", GOPATH: "#{HOMEBREW_CACHE}/go_mod_cache",
CARGO_HOME: "#{HOMEBREW_CACHE}/cargo_cache", CARGO_HOME: "#{HOMEBREW_CACHE}/cargo_cache",
CURL_HOME: ENV["CURL_HOME"] || ENV["HOME"], CURL_HOME: ENV.fetch("CURL_HOME") { Dir.home },
} }
end end
@ -2470,7 +2470,7 @@ class Formula
# The methods below define the formula DSL. # The methods below define the formula DSL.
class << self class << self
include BuildEnvironment::DSL include BuildEnvironment::DSL
include OnOS include OnSystem
def method_added(method) def method_added(method)
super super

View File

@ -48,4 +48,7 @@ class Formula
def env; end def env; end
def conflicts; end def conflicts; end
# This method is included by `OnSystem`
def self.on_macos(&block); end
end end

View File

@ -291,7 +291,7 @@ module FormulaCellarChecks
dot_brew_formula = formula.prefix/".brew/#{formula.name}.rb" dot_brew_formula = formula.prefix/".brew/#{formula.name}.rb"
return unless dot_brew_formula.exist? return unless dot_brew_formula.exist?
# TODO: add methods to `utils/ast` to allow checking for method use
return unless dot_brew_formula.read.include? "ENV.runtime_cpu_detection" return unless dot_brew_formula.read.include? "ENV.runtime_cpu_detection"
# macOS `objdump` is a bit slow, so we prioritise llvm's `llvm-objdump` (~5.7x faster) # macOS `objdump` is a bit slow, so we prioritise llvm's `llvm-objdump` (~5.7x faster)
@ -299,7 +299,7 @@ module FormulaCellarChecks
objdump = Formula["llvm"].opt_bin/"llvm-objdump" if Formula["llvm"].any_version_installed? objdump = Formula["llvm"].opt_bin/"llvm-objdump" if Formula["llvm"].any_version_installed?
objdump ||= Formula["binutils"].opt_bin/"objdump" if Formula["binutils"].any_version_installed? objdump ||= Formula["binutils"].opt_bin/"objdump" if Formula["binutils"].any_version_installed?
objdump ||= which("objdump") objdump ||= which("objdump")
objdump ||= which("objdump", ENV["HOMEBREW_PATH"]) objdump ||= which("objdump", ORIGINAL_PATHS)
unless objdump unless objdump
return <<~EOS return <<~EOS

View File

@ -823,6 +823,7 @@ class FormulaInstaller
if formula.name == "curl" && if formula.name == "curl" &&
!DevelopmentTools.curl_handles_most_https_certificates? !DevelopmentTools.curl_handles_most_https_certificates?
ENV["HOMEBREW_CURL"] = formula.opt_bin/"curl" ENV["HOMEBREW_CURL"] = formula.opt_bin/"curl"
Utils::Curl.clear_path_cache
end end
caveats caveats
@ -903,7 +904,7 @@ class FormulaInstaller
sandbox = Sandbox.new sandbox = Sandbox.new
formula.logs.mkpath formula.logs.mkpath
sandbox.record_log(formula.logs/"build.sandbox.log") sandbox.record_log(formula.logs/"build.sandbox.log")
sandbox.allow_write_path(ENV["HOME"]) if interactive? sandbox.allow_write_path(Dir.home) if interactive?
sandbox.allow_write_temp_and_cache sandbox.allow_write_temp_and_cache
sandbox.allow_write_log(formula) sandbox.allow_write_log(formula)
sandbox.allow_cvs sandbox.allow_cvs
@ -1083,12 +1084,12 @@ class FormulaInstaller
sig { void } sig { void }
def post_install def post_install
args = %W[ args = [
nice #{RUBY_PATH} "nice",
#{ENV["HOMEBREW_RUBY_WARNINGS"]} *HOMEBREW_RUBY_EXEC_ARGS,
-I #{$LOAD_PATH.join(File::PATH_SEPARATOR)} "-I", $LOAD_PATH.join(File::PATH_SEPARATOR),
-- "--",
#{HOMEBREW_LIBRARY_PATH}/postinstall.rb HOMEBREW_LIBRARY_PATH/"postinstall.rb"
] ]
# Use the formula from the keg if: # Use the formula from the keg if:

View File

@ -641,7 +641,7 @@ module Formulary
when URL_START_REGEX when URL_START_REGEX
return FromUrlLoader.new(ref) return FromUrlLoader.new(ref)
when HOMEBREW_TAP_FORMULA_REGEX when HOMEBREW_TAP_FORMULA_REGEX
if ref.start_with?("homebrew/core/") && !CoreTap.instance.installed? && Homebrew::EnvConfig.install_from_api? if ref.start_with?("homebrew/core/") && Homebrew::EnvConfig.install_from_api?
name = ref.split("/", 3).last name = ref.split("/", 3).last
return FormulaAPILoader.new(name) if Homebrew::API::Formula.all_formulae.key?(name) return FormulaAPILoader.new(name) if Homebrew::API::Formula.all_formulae.key?(name)
end end
@ -651,18 +651,16 @@ module Formulary
return FromPathLoader.new(ref) if File.extname(ref) == ".rb" && Pathname.new(ref).expand_path.exist? return FromPathLoader.new(ref) if File.extname(ref) == ".rb" && Pathname.new(ref).expand_path.exist?
if Homebrew::EnvConfig.install_from_api? && Homebrew::API::Formula.all_formulae.key?(ref)
return FormulaAPILoader.new(ref)
end
formula_with_that_name = core_path(ref) formula_with_that_name = core_path(ref)
return FormulaLoader.new(ref, formula_with_that_name) if formula_with_that_name.file? return FormulaLoader.new(ref, formula_with_that_name) if formula_with_that_name.file?
possible_alias = CoreTap.instance.alias_dir/ref possible_alias = CoreTap.instance.alias_dir/ref
return AliasLoader.new(possible_alias) if possible_alias.file? return AliasLoader.new(possible_alias) if possible_alias.file?
if !CoreTap.instance.installed? &&
Homebrew::EnvConfig.install_from_api? &&
Homebrew::API::Formula.all_formulae.key?(ref)
return FormulaAPILoader.new(ref)
end
possible_tap_formulae = tap_paths(ref) possible_tap_formulae = tap_paths(ref)
raise TapFormulaAmbiguityError.new(ref, possible_tap_formulae) if possible_tap_formulae.size > 1 raise TapFormulaAmbiguityError.new(ref, possible_tap_formulae) if possible_tap_formulae.size > 1

View File

@ -34,25 +34,28 @@ ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.irregular "it", "they" inflect.irregular "it", "they"
end end
HOMEBREW_BOTTLE_DEFAULT_DOMAIN = ENV["HOMEBREW_BOTTLE_DEFAULT_DOMAIN"] HOMEBREW_BOTTLE_DEFAULT_DOMAIN = ENV.fetch("HOMEBREW_BOTTLE_DEFAULT_DOMAIN").freeze
HOMEBREW_BREW_DEFAULT_GIT_REMOTE = ENV["HOMEBREW_BREW_DEFAULT_GIT_REMOTE"] HOMEBREW_BREW_DEFAULT_GIT_REMOTE = ENV.fetch("HOMEBREW_BREW_DEFAULT_GIT_REMOTE").freeze
HOMEBREW_CORE_DEFAULT_GIT_REMOTE = ENV["HOMEBREW_CORE_DEFAULT_GIT_REMOTE"] HOMEBREW_CORE_DEFAULT_GIT_REMOTE = ENV.fetch("HOMEBREW_CORE_DEFAULT_GIT_REMOTE").freeze
HOMEBREW_DEFAULT_CACHE = ENV["HOMEBREW_DEFAULT_CACHE"] HOMEBREW_DEFAULT_CACHE = ENV.fetch("HOMEBREW_DEFAULT_CACHE").freeze
HOMEBREW_DEFAULT_LOGS = ENV["HOMEBREW_DEFAULT_LOGS"] HOMEBREW_DEFAULT_LOGS = ENV.fetch("HOMEBREW_DEFAULT_LOGS").freeze
HOMEBREW_DEFAULT_TEMP = ENV["HOMEBREW_DEFAULT_TEMP"] HOMEBREW_DEFAULT_TEMP = ENV.fetch("HOMEBREW_DEFAULT_TEMP").freeze
HOMEBREW_REQUIRED_RUBY_VERSION = ENV["HOMEBREW_REQUIRED_RUBY_VERSION"] HOMEBREW_REQUIRED_RUBY_VERSION = ENV.fetch("HOMEBREW_REQUIRED_RUBY_VERSION").freeze
HOMEBREW_PRODUCT = ENV["HOMEBREW_PRODUCT"] HOMEBREW_PRODUCT = ENV.fetch("HOMEBREW_PRODUCT").freeze
HOMEBREW_VERSION = ENV["HOMEBREW_VERSION"] HOMEBREW_VERSION = ENV.fetch("HOMEBREW_VERSION").freeze
HOMEBREW_WWW = "https://brew.sh" HOMEBREW_WWW = "https://brew.sh"
HOMEBREW_SYSTEM = ENV.fetch("HOMEBREW_SYSTEM").freeze
HOMEBREW_PROCESSOR = ENV.fetch("HOMEBREW_PROCESSOR").freeze
HOMEBREW_USER_AGENT_CURL = ENV["HOMEBREW_USER_AGENT_CURL"] HOMEBREW_BREWED_CURL_PATH = Pathname(ENV.fetch("HOMEBREW_BREWED_CURL_PATH")).freeze
HOMEBREW_USER_AGENT_CURL = ENV.fetch("HOMEBREW_USER_AGENT_CURL").freeze
HOMEBREW_USER_AGENT_RUBY = HOMEBREW_USER_AGENT_RUBY =
"#{ENV["HOMEBREW_USER_AGENT"]} ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}" "#{ENV.fetch("HOMEBREW_USER_AGENT")} ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
HOMEBREW_USER_AGENT_FAKE_SAFARI = HOMEBREW_USER_AGENT_FAKE_SAFARI =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/602.4.8 " \ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/602.4.8 " \
"(KHTML, like Gecko) Version/10.0.3 Safari/602.4.8" "(KHTML, like Gecko) Version/10.0.3 Safari/602.4.8"
HOMEBREW_GITHUB_PACKAGES_AUTH = ENV["HOMEBREW_GITHUB_PACKAGES_AUTH"] HOMEBREW_GITHUB_PACKAGES_AUTH = ENV.fetch("HOMEBREW_GITHUB_PACKAGES_AUTH").freeze
HOMEBREW_DEFAULT_PREFIX = "/usr/local" HOMEBREW_DEFAULT_PREFIX = "/usr/local"
HOMEBREW_DEFAULT_REPOSITORY = "#{HOMEBREW_DEFAULT_PREFIX}/Homebrew" HOMEBREW_DEFAULT_REPOSITORY = "#{HOMEBREW_DEFAULT_PREFIX}/Homebrew"
@ -69,6 +72,7 @@ HOMEBREW_BOTTLES_EXTNAME_REGEX = /\.([a-z0-9_]+)\.bottle\.(?:(\d+)\.)?tar\.gz$/.
require "env_config" require "env_config"
require "compat/early" unless Homebrew::EnvConfig.no_compat? require "compat/early" unless Homebrew::EnvConfig.no_compat?
require "macos_versions"
require "os" require "os"
require "messages" require "messages"
require "default_prefix" require "default_prefix"
@ -116,8 +120,8 @@ require "cli/args"
require "PATH" require "PATH"
ENV["HOMEBREW_PATH"] ||= ENV["PATH"] ENV["HOMEBREW_PATH"] ||= ENV.fetch("PATH")
ORIGINAL_PATHS = PATH.new(ENV["HOMEBREW_PATH"]).map do |p| ORIGINAL_PATHS = PATH.new(ENV.fetch("HOMEBREW_PATH")).map do |p|
Pathname.new(p).expand_path Pathname.new(p).expand_path
rescue rescue
nil nil

View File

@ -26,7 +26,7 @@ module Language
end end
def self.each_python(build, &block) def self.each_python(build, &block)
original_pythonpath = ENV["PYTHONPATH"] original_pythonpath = ENV.fetch("PYTHONPATH", nil)
pythons = { "python@3" => "python3", pythons = { "python@3" => "python3",
"pypy" => "pypy", "pypy" => "pypy",
"pypy3" => "pypy3" } "pypy3" => "pypy3" }

View File

@ -563,6 +563,7 @@ module Homebrew
# Identifies the latest version of the formula and returns a Hash containing # Identifies the latest version of the formula and returns a Hash containing
# the version information. Returns nil if a latest version couldn't be found. # the version information. Returns nil if a latest version couldn't be found.
# rubocop:disable Metrics/CyclomaticComplexity
sig { sig {
params( params(
formula_or_cask: T.any(Formula, Cask::Cask), formula_or_cask: T.any(Formula, Cask::Cask),
@ -657,7 +658,7 @@ module Homebrew
end end
if livecheck_strategy.present? if livecheck_strategy.present?
if livecheck_url.blank? if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url])
odebug "#{strategy_name} strategy requires a URL" odebug "#{strategy_name} strategy requires a URL"
next next
elsif livecheck_strategy != :page_match && strategies.exclude?(strategy) elsif livecheck_strategy != :page_match && strategies.exclude?(strategy)
@ -768,6 +769,7 @@ module Homebrew
nil nil
end end
# rubocop:enable Metrics/CyclomaticComplexity
end end
# rubocop:enable Metrics/ModuleLength # rubocop:enable Metrics/ModuleLength
end end

View File

@ -82,25 +82,37 @@ module Homebrew
# versions from `plist` files. # versions from `plist` files.
# #
# @param cask [Cask::Cask] the cask to check for version information # @param cask [Cask::Cask] the cask to check for version information
# @param url [String, nil] an alternative URL to check for version
# information
# @param regex [Regexp, nil] a regex for use in a strategy block # @param regex [Regexp, nil] a regex for use in a strategy block
# @return [Hash] # @return [Hash]
sig { sig {
params( params(
cask: Cask::Cask, cask: Cask::Cask,
url: T.nilable(String),
regex: T.nilable(Regexp), regex: T.nilable(Regexp),
_unused: T.nilable(T::Hash[Symbol, T.untyped]), _unused: T.nilable(T::Hash[Symbol, T.untyped]),
block: T.untyped, block: T.untyped,
).returns(T::Hash[Symbol, T.untyped]) ).returns(T::Hash[Symbol, T.untyped])
} }
def self.find_versions(cask:, regex: nil, **_unused, &block) def self.find_versions(cask:, url: nil, regex: nil, **_unused, &block)
if regex.present? && block.blank? if regex.present? && block.blank?
raise ArgumentError, "#{T.must(name).demodulize} only supports a regex when using a `strategy` block" raise ArgumentError, "#{T.must(name).demodulize} only supports a regex when using a `strategy` block"
end end
raise ArgumentError, "The #{T.must(name).demodulize} strategy only supports casks." unless T.unsafe(cask) raise ArgumentError, "The #{T.must(name).demodulize} strategy only supports casks." unless T.unsafe(cask)
match_data = { matches: {}, regex: regex } match_data = { matches: {}, regex: regex, url: url }
unversioned_cask_checker = if url.present? && url != cask.url.to_s
# Create a copy of the `cask` that uses the `livecheck` block URL
cask_copy = Cask::CaskLoader.load(cask.full_name)
cask_copy.allow_reassignment = true
cask_copy.url { url }
UnversionedCaskChecker.new(cask_copy)
else
UnversionedCaskChecker.new(cask)
end
unversioned_cask_checker = UnversionedCaskChecker.new(cask)
items = unversioned_cask_checker.all_versions.transform_values { |v| Item.new(bundle_version: v) } items = unversioned_cask_checker.all_versions.transform_values { |v| Item.new(bundle_version: v) }
versions_from_items(items, regex, &block).each do |version_text| versions_from_items(items, regex, &block).each do |version_text|

View File

@ -110,7 +110,7 @@ module Homebrew
version ||= item.elements["version"]&.text&.strip version ||= item.elements["version"]&.text&.strip
title = item.elements["title"]&.text&.strip title = item.elements["title"]&.text&.strip
pub_date = item.elements["pubDate"]&.text&.strip&.presence&.yield_self do |date_string| pub_date = item.elements["pubDate"]&.text&.strip&.presence&.then do |date_string|
Time.parse(date_string) Time.parse(date_string)
rescue ArgumentError rescue ArgumentError
# Omit unparseable strings (e.g. non-English dates) # Omit unparseable strings (e.g. non-English dates)

View File

@ -0,0 +1,20 @@
# typed: true
# frozen_string_literal: true
# Helper functions for querying operating system information.
#
# @api private
module MacOSVersions
# TODO: when removing symbols here, ensure that they are added to
# DEPRECATED_MACOS_VERSIONS in MacOSRequirement.
SYMBOLS = {
ventura: "13",
monterey: "12",
big_sur: "11",
catalina: "10.15",
mojave: "10.14",
high_sierra: "10.13",
sierra: "10.12",
el_capitan: "10.11",
}.freeze
end

View File

@ -43,7 +43,7 @@ module OS
@kernel_name ||= Utils.safe_popen_read("uname", "-s").chomp @kernel_name ||= Utils.safe_popen_read("uname", "-s").chomp
end end
::OS_VERSION = ENV["HOMEBREW_OS_VERSION"] ::OS_VERSION = ENV.fetch("HOMEBREW_OS_VERSION").freeze
CI_GLIBC_VERSION = "2.23" CI_GLIBC_VERSION = "2.23"
CI_OS_VERSION = "Ubuntu 16.04" CI_OS_VERSION = "Ubuntu 16.04"
@ -54,8 +54,8 @@ module OS
if !OS::Mac.version.prerelease? && if !OS::Mac.version.prerelease? &&
!OS::Mac.version.outdated_release? && !OS::Mac.version.outdated_release? &&
ARGV.none? { |v| v.start_with?("--cc=") } && ARGV.none? { |v| v.start_with?("--cc=") } &&
(ENV["HOMEBREW_PREFIX"] == HOMEBREW_DEFAULT_PREFIX || (HOMEBREW_PREFIX == HOMEBREW_DEFAULT_PREFIX ||
(ENV["HOMEBREW_PREFIX"] == HOMEBREW_MACOS_ARM_DEFAULT_PREFIX && Hardware::CPU.arm?)) (HOMEBREW_PREFIX == HOMEBREW_MACOS_ARM_DEFAULT_PREFIX && Hardware::CPU.arm?))
ISSUES_URL = "https://docs.brew.sh/Troubleshooting" ISSUES_URL = "https://docs.brew.sh/Troubleshooting"
end end
PATH_OPEN = "/usr/bin/open" PATH_OPEN = "/usr/bin/open"

View File

@ -31,11 +31,7 @@ module OS
module Mac module Mac
module_function module_function
# rubocop:disable Naming/ConstantName
# rubocop:disable Style/MutableConstant
::MacOS = OS::Mac ::MacOS = OS::Mac
# rubocop:enable Naming/ConstantName
# rubocop:enable Style/MutableConstant
raise "Loaded OS::Linux on generic OS!" if ENV["HOMEBREW_TEST_GENERIC_OS"] raise "Loaded OS::Linux on generic OS!" if ENV["HOMEBREW_TEST_GENERIC_OS"]

View File

@ -13,14 +13,13 @@ module OS
module_function module_function
# rubocop:disable Naming/ConstantName
# rubocop:disable Style/MutableConstant
::MacOS = OS::Mac ::MacOS = OS::Mac
# rubocop:enable Naming/ConstantName
# rubocop:enable Style/MutableConstant
raise "Loaded OS::Mac on generic OS!" if ENV["HOMEBREW_TEST_GENERIC_OS"] raise "Loaded OS::Mac on generic OS!" if ENV["HOMEBREW_TEST_GENERIC_OS"]
VERSION = ENV.fetch("HOMEBREW_MACOS_VERSION").chomp.freeze
private_constant :VERSION
# This can be compared to numerics, strings, or symbols # This can be compared to numerics, strings, or symbols
# using the standard Ruby Comparable methods. # using the standard Ruby Comparable methods.
sig { returns(Version) } sig { returns(Version) }
@ -35,7 +34,7 @@ module OS
@full_version ||= if ENV["HOMEBREW_FAKE_EL_CAPITAN"] # for Portable Ruby building @full_version ||= if ENV["HOMEBREW_FAKE_EL_CAPITAN"] # for Portable Ruby building
Version.new("10.11.6") Version.new("10.11.6")
else else
Version.new((ENV["HOMEBREW_MACOS_VERSION"]).chomp) Version.new(VERSION)
end end
end end

View File

@ -13,22 +13,10 @@ module OS
class Version < ::Version class Version < ::Version
extend T::Sig extend T::Sig
# TODO: when removing symbols here, ensure that they are added to
# DEPRECATED_MACOS_VERSIONS in MacOSRequirement.
SYMBOLS = {
ventura: "13",
monterey: "12",
big_sur: "11",
catalina: "10.15",
mojave: "10.14",
high_sierra: "10.13",
sierra: "10.12",
el_capitan: "10.11",
}.freeze
# TODO: bump version when new macOS is released or announced # TODO: bump version when new macOS is released or announced
# and also update references in docs/Installation.md and # and also update references in docs/Installation.md,
# https://github.com/Homebrew/install/blob/HEAD/install.sh # https://github.com/Homebrew/install/blob/HEAD/install.sh and
# MacOSVersions::SYMBOLS
NEWEST_UNSUPPORTED = "13" NEWEST_UNSUPPORTED = "13"
private_constant :NEWEST_UNSUPPORTED private_constant :NEWEST_UNSUPPORTED
@ -42,7 +30,7 @@ module OS
sig { params(version: Symbol).returns(T.attached_class) } sig { params(version: Symbol).returns(T.attached_class) }
def self.from_symbol(version) def self.from_symbol(version)
str = SYMBOLS.fetch(version) { raise MacOSVersionError, version } str = MacOSVersions::SYMBOLS.fetch(version) { raise MacOSVersionError, version }
new(str) new(str)
end end
@ -60,10 +48,10 @@ module OS
sig { override.params(other: T.untyped).returns(T.nilable(Integer)) } sig { override.params(other: T.untyped).returns(T.nilable(Integer)) }
def <=>(other) def <=>(other)
@comparison_cache.fetch(other) do @comparison_cache.fetch(other) do
if SYMBOLS.key?(other) && to_sym == other if MacOSVersions::SYMBOLS.key?(other) && to_sym == other
0 0
else else
v = SYMBOLS.fetch(other) { other.to_s } v = MacOSVersions::SYMBOLS.fetch(other) { other.to_s }
@comparison_cache[other] = super(::Version.new(v)) @comparison_cache[other] = super(::Version.new(v))
end end
end end
@ -81,7 +69,7 @@ module OS
sig { returns(Symbol) } sig { returns(Symbol) }
def to_sym def to_sym
@to_sym ||= SYMBOLS.invert.fetch(strip_patch.to_s, :dunno) @to_sym ||= MacOSVersions::SYMBOLS.invert.fetch(strip_patch.to_s, :dunno)
end end
sig { returns(String) } sig { returns(String) }

View File

@ -52,6 +52,6 @@ class PkgVersion
alias eql? == alias eql? ==
def hash def hash
version.hash ^ revision.hash [version, revision].hash
end end
end end

View File

@ -103,7 +103,7 @@ class Requirement
parent = satisfied_result_parent parent = satisfied_result_parent
return unless parent return unless parent
return if ["#{HOMEBREW_PREFIX}/bin", "#{HOMEBREW_PREFIX}/bin"].include?(parent.to_s) return if ["#{HOMEBREW_PREFIX}/bin", "#{HOMEBREW_PREFIX}/bin"].include?(parent.to_s)
return if PATH.new(ENV["PATH"]).include?(parent.to_s) return if PATH.new(ENV.fetch("PATH")).include?(parent.to_s)
ENV.prepend_path("PATH", parent) ENV.prepend_path("PATH", parent)
end end
@ -122,7 +122,7 @@ class Requirement
alias eql? == alias eql? ==
def hash def hash
name.hash ^ tags.hash [name, tags].hash
end end
sig { returns(String) } sig { returns(String) }

Some files were not shown because too many files have changed in this diff Show More