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.
class MissingEnvironmentVariables < RuntimeError; end
begin
require_relative "global" 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

@ -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

@ -20,7 +20,7 @@ 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."

View File

@ -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

@ -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

@ -37,13 +37,13 @@ module Homebrew
"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

@ -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

@ -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

@ -78,8 +78,8 @@ module Homebrew
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

@ -65,8 +65,8 @@ module Homebrew
"`--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 " \

View File

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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 " \
@ -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.",

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) }

View File

@ -18,7 +18,7 @@ class Resource
include Context include Context
include FileUtils include FileUtils
include OnOS include OnSystem
attr_reader :mirrors, :specs, :using, :source_modified_time, :patches, :owner attr_reader :mirrors, :specs, :using, :source_modified_time, :patches, :owner
attr_writer :version attr_writer :version

View File

@ -0,0 +1,50 @@
# typed: true
# frozen_string_literal: true
module Homebrew
# Helper module for simulating different system condfigurations.
#
# @api private
class SimulateSystem
class << self
extend T::Sig
attr_reader :os, :arch
sig { params(new_os: Symbol).void }
def os=(new_os)
os_options = [:macos, :linux, *MacOSVersions::SYMBOLS.keys]
raise "Unknown OS: #{new_os}" unless os_options.include?(new_os)
@os = new_os
end
sig { params(new_arch: Symbol).void }
def arch=(new_arch)
raise "New arch must be :arm or :intel" unless [:arm, :intel].include?(new_arch)
@arch = new_arch
end
sig { void }
def clear
@os = @arch = nil
end
sig { returns(T::Boolean) }
def none?
@os.nil? && @arch.nil?
end
sig { returns(T::Boolean) }
def macos?
[:macos, *MacOSVersions::SYMBOLS.keys].include?(@os)
end
sig { returns(T::Boolean) }
def linux?
@os == :linux
end
end
end
end

View File

@ -12,13 +12,13 @@ require "utils/bottles"
require "patch" require "patch"
require "compilers" require "compilers"
require "os/mac/version" require "os/mac/version"
require "extend/on_os" require "extend/on_system"
class SoftwareSpec class SoftwareSpec
extend T::Sig extend T::Sig
extend Forwardable extend Forwardable
include OnOS include OnSystem
PREDEFINED_OPTIONS = { PREDEFINED_OPTIONS = {
universal: Option.new("universal", "Build a universal binary"), universal: Option.new("universal", "Build a universal binary"),
@ -508,8 +508,8 @@ class BottleSpecification
prefix = Pathname(cellar).parent.to_s prefix = Pathname(cellar).parent.to_s
cellar_relocatable = cellar.size >= HOMEBREW_CELLAR.to_s.size && ENV["HOMEBREW_RELOCATE_BUILD_PREFIX"] cellar_relocatable = cellar.size >= HOMEBREW_CELLAR.to_s.size && ENV["HOMEBREW_RELOCATE_BUILD_PREFIX"].present?
prefix_relocatable = prefix.size >= HOMEBREW_PREFIX.to_s.size && ENV["HOMEBREW_RELOCATE_BUILD_PREFIX"] prefix_relocatable = prefix.size >= HOMEBREW_PREFIX.to_s.size && ENV["HOMEBREW_RELOCATE_BUILD_PREFIX"].present?
compatible_cellar = cellar == HOMEBREW_CELLAR.to_s || cellar_relocatable compatible_cellar = cellar == HOMEBREW_CELLAR.to_s || cellar_relocatable
compatible_prefix = prefix == HOMEBREW_PREFIX.to_s || prefix_relocatable compatible_prefix = prefix == HOMEBREW_PREFIX.to_s || prefix_relocatable
@ -583,7 +583,7 @@ class BottleSpecification
end end
class PourBottleCheck class PourBottleCheck
include OnOS include OnSystem
def initialize(formula) def initialize(formula)
@formula = formula @formula = formula

View File

@ -97,9 +97,12 @@ class Attr < Parlour::Plugin
when :attr_rw when :attr_rw
name = node.shift name = node.shift
name = "self.#{name}" if sclass name = "self.#{name}" if sclass
namespace.create_method(name, parameters: [ namespace.create_method(name,
Parlour::RbiGenerator::Parameter.new("arg", type: "T.untyped", default: "T.unsafe(nil)"), parameters: [
], return_type: "T.untyped") Parlour::RbiGenerator::Parameter.new("arg", type: "T.untyped",
default: "T.unsafe(nil)"),
],
return_type: "T.untyped")
when :attr_predicate when :attr_predicate
name = node.shift name = node.shift
name = "self.#{name}" if sclass name = "self.#{name}" if sclass

View File

@ -0,0 +1,101 @@
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `json` gem.
# Please instead update this file by running `bin/tapioca gem json`.
class Class < ::Module
def json_creatable?; end
end
module JSON
private
def dump(obj, anIO = T.unsafe(nil), limit = T.unsafe(nil)); end
def fast_generate(obj, opts = T.unsafe(nil)); end
def fast_unparse(obj, opts = T.unsafe(nil)); end
def generate(obj, opts = T.unsafe(nil)); end
def load(source, proc = T.unsafe(nil), options = T.unsafe(nil)); end
def load_file(filespec, opts = T.unsafe(nil)); end
def load_file!(filespec, opts = T.unsafe(nil)); end
def parse(source, opts = T.unsafe(nil)); end
def parse!(source, opts = T.unsafe(nil)); end
def pretty_generate(obj, opts = T.unsafe(nil)); end
def pretty_unparse(obj, opts = T.unsafe(nil)); end
def recurse_proc(result, &proc); end
def restore(source, proc = T.unsafe(nil), options = T.unsafe(nil)); end
def unparse(obj, opts = T.unsafe(nil)); end
class << self
def [](object, opts = T.unsafe(nil)); end
def create_fast_state; end
def create_id; end
def create_id=(new_value); end
def create_pretty_state; end
def deep_const_get(path); end
def dump(obj, anIO = T.unsafe(nil), limit = T.unsafe(nil)); end
def dump_default_options; end
def dump_default_options=(_arg0); end
def fast_generate(obj, opts = T.unsafe(nil)); end
def fast_unparse(obj, opts = T.unsafe(nil)); end
def generate(obj, opts = T.unsafe(nil)); end
def generator; end
def generator=(generator); end
def iconv(to, from, string); end
def load(source, proc = T.unsafe(nil), options = T.unsafe(nil)); end
def load_default_options; end
def load_default_options=(_arg0); end
def load_file(filespec, opts = T.unsafe(nil)); end
def load_file!(filespec, opts = T.unsafe(nil)); end
def parse(source, opts = T.unsafe(nil)); end
def parse!(source, opts = T.unsafe(nil)); end
def parser; end
def parser=(parser); end
def pretty_generate(obj, opts = T.unsafe(nil)); end
def pretty_unparse(obj, opts = T.unsafe(nil)); end
def recurse_proc(result, &proc); end
def restore(source, proc = T.unsafe(nil), options = T.unsafe(nil)); end
def state; end
def state=(_arg0); end
def unparse(obj, opts = T.unsafe(nil)); end
end
end
JSON::CREATE_ID_TLS_KEY = T.let(T.unsafe(nil), String)
JSON::DEFAULT_CREATE_ID = T.let(T.unsafe(nil), String)
class JSON::GenericObject < ::OpenStruct
def as_json(*_arg0); end
def to_hash; end
def to_json(*a); end
def |(other); end
class << self
def dump(obj, *args); end
def from_hash(object); end
def json_creatable=(_arg0); end
def json_creatable?; end
def json_create(data); end
def load(source, proc = T.unsafe(nil), opts = T.unsafe(nil)); end
end
end
class JSON::JSONError < ::StandardError
class << self
def wrap(exception); end
end
end
JSON::Parser = JSON::Ext::Parser
JSON::State = JSON::Ext::Generator::State
JSON::UnparserError = JSON::GeneratorError
module Kernel
extend ::Forwardable
private
def JSON(object, *args); end
def j(*objs); end
def jj(*objs); end
end

View File

@ -53,6 +53,8 @@ module RuboCop::Cop::EnforceSuperclass
end end
end end
RuboCop::Cop::IgnoredPattern = RuboCop::Cop::AllowedPattern
module RuboCop::Cop::IndexMethod module RuboCop::Cop::IndexMethod
def on_block(node); end def on_block(node); end
def on_csend(node); end def on_csend(node); end
@ -1902,7 +1904,7 @@ RuboCop::Cop::Rails::TimeZone::TIMEZONE_SPECIFIER = T.let(T.unsafe(nil), Regexp)
class RuboCop::Cop::Rails::TimeZoneAssignment < ::RuboCop::Cop::Base class RuboCop::Cop::Rails::TimeZoneAssignment < ::RuboCop::Cop::Base
def on_send(node); end def on_send(node); end
def time_zone_assignement?(param0 = T.unsafe(nil)); end def time_zone_assignment?(param0 = T.unsafe(nil)); end
end end
RuboCop::Cop::Rails::TimeZoneAssignment::MSG = T.let(T.unsafe(nil), String) RuboCop::Cop::Rails::TimeZoneAssignment::MSG = T.let(T.unsafe(nil), String)
@ -1913,6 +1915,7 @@ class RuboCop::Cop::Rails::ToFormattedS < ::RuboCop::Cop::Base
extend ::RuboCop::Cop::AutoCorrector extend ::RuboCop::Cop::AutoCorrector
extend ::RuboCop::Cop::TargetRailsVersion extend ::RuboCop::Cop::TargetRailsVersion
def on_csend(node); end
def on_send(node); end def on_send(node); end
end end
@ -2167,8 +2170,8 @@ end
class RuboCop::Rails::SchemaLoader::Schema class RuboCop::Rails::SchemaLoader::Schema
def initialize(ast); end def initialize(ast); end
def add_indicies; end def add_indices; end
def add_indicies_by(table_name:); end def add_indices_by(table_name:); end
def table_by(name:); end def table_by(name:); end
def tables; end def tables; end

View File

@ -166,6 +166,11 @@ class RuboCop::Cop::Sorbet::ForbidTUnsafe < ::RuboCop::Cop::Cop
def t_unsafe?(param0 = T.unsafe(nil)); end def t_unsafe?(param0 = T.unsafe(nil)); end
end end
class RuboCop::Cop::Sorbet::ForbidTUntyped < ::RuboCop::Cop::Cop
def on_send(node); end
def t_untyped?(param0 = T.unsafe(nil)); end
end
class RuboCop::Cop::Sorbet::ForbidUntypedStructProps < ::RuboCop::Cop::Cop class RuboCop::Cop::Sorbet::ForbidUntypedStructProps < ::RuboCop::Cop::Cop
def on_class(node); end def on_class(node); end
def subclass_of_t_struct?(param0 = T.unsafe(nil)); end def subclass_of_t_struct?(param0 = T.unsafe(nil)); end

View File

@ -1044,8 +1044,6 @@ end
class Class class Class
def any_instance(); end def any_instance(); end
def json_creatable?(); end
end end
class CompilerSelector::Compiler class CompilerSelector::Compiler
@ -2662,6 +2660,10 @@ module Homebrew::Livecheck::Strategy
extend ::T::Private::Methods::SingletonMethodHooks extend ::T::Private::Methods::SingletonMethodHooks
end end
class Homebrew::SimulateSystem
extend ::T::Private::Methods::SingletonMethodHooks
end
class Homebrew::Style::LineLocation class Homebrew::Style::LineLocation
extend ::T::Private::Methods::MethodHooks extend ::T::Private::Methods::MethodHooks
extend ::T::Private::Methods::SingletonMethodHooks extend ::T::Private::Methods::SingletonMethodHooks
@ -2959,12 +2961,6 @@ class JSON::Ext::Parser
def initialize(*arg); end def initialize(*arg); end
end end
JSON::Parser = JSON::Ext::Parser
JSON::State = JSON::Ext::Generator::State
JSON::UnparserError = JSON::GeneratorError
class Keg::ConflictError class Keg::ConflictError
extend ::T::Private::Methods::MethodHooks extend ::T::Private::Methods::MethodHooks
extend ::T::Private::Methods::SingletonMethodHooks extend ::T::Private::Methods::SingletonMethodHooks
@ -3387,13 +3383,7 @@ end
Net::HTTPFatalErrorCode = Net::HTTPClientError Net::HTTPFatalErrorCode = Net::HTTPClientError
class Net::HTTPInformation Net::HTTPInformationCode = Net::HTTPInformation
end
Net::HTTPInformationCode::EXCEPTION_TYPE = Net::HTTPError
class Net::HTTPInformation
end
class Net::HTTPLoopDetected class Net::HTTPLoopDetected
HAS_BODY = ::T.let(nil, ::T.untyped) HAS_BODY = ::T.let(nil, ::T.untyped)
@ -3453,13 +3443,7 @@ Net::HTTPServerErrorCode = Net::HTTPServerError
Net::HTTPSession = Net::HTTP Net::HTTPSession = Net::HTTP
class Net::HTTPSuccess Net::HTTPSuccessCode = Net::HTTPSuccess
end
Net::HTTPSuccessCode::EXCEPTION_TYPE = Net::HTTPError
class Net::HTTPSuccess
end
class Net::HTTPURITooLong class Net::HTTPURITooLong
HAS_BODY = ::T.let(nil, ::T.untyped) HAS_BODY = ::T.let(nil, ::T.untyped)
@ -3526,7 +3510,7 @@ class Object
def __send!(*arg); end def __send!(*arg); end
def stub(name, val_or_callable, *block_args, **block_kwargs); end def stub(name, val_or_callable, *block_args, **block_kwargs, &block); end
def to_yaml(options=T.unsafe(nil)); end def to_yaml(options=T.unsafe(nil)); end
ARGF = ::T.let(nil, ::T.untyped) ARGF = ::T.let(nil, ::T.untyped)
@ -3538,6 +3522,7 @@ class Object
FORMULA_COMPONENT_PRECEDENCE_LIST = ::T.let(nil, ::T.untyped) FORMULA_COMPONENT_PRECEDENCE_LIST = ::T.let(nil, ::T.untyped)
HOMEBREW_BOTTLES_EXTNAME_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_BOTTLES_EXTNAME_REGEX = ::T.let(nil, ::T.untyped)
HOMEBREW_BOTTLE_DEFAULT_DOMAIN = ::T.let(nil, ::T.untyped) HOMEBREW_BOTTLE_DEFAULT_DOMAIN = ::T.let(nil, ::T.untyped)
HOMEBREW_BREWED_CURL_PATH = ::T.let(nil, ::T.untyped)
HOMEBREW_BREW_DEFAULT_GIT_REMOTE = ::T.let(nil, ::T.untyped) HOMEBREW_BREW_DEFAULT_GIT_REMOTE = ::T.let(nil, ::T.untyped)
HOMEBREW_BREW_FILE = ::T.let(nil, ::T.untyped) HOMEBREW_BREW_FILE = ::T.let(nil, ::T.untyped)
HOMEBREW_CACHE = ::T.let(nil, ::T.untyped) HOMEBREW_CACHE = ::T.let(nil, ::T.untyped)
@ -3564,6 +3549,7 @@ class Object
HOMEBREW_OFFICIAL_REPO_PREFIXES_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_OFFICIAL_REPO_PREFIXES_REGEX = ::T.let(nil, ::T.untyped)
HOMEBREW_PINNED_KEGS = ::T.let(nil, ::T.untyped) HOMEBREW_PINNED_KEGS = ::T.let(nil, ::T.untyped)
HOMEBREW_PREFIX = ::T.let(nil, ::T.untyped) HOMEBREW_PREFIX = ::T.let(nil, ::T.untyped)
HOMEBREW_PROCESSOR = ::T.let(nil, ::T.untyped)
HOMEBREW_PRODUCT = ::T.let(nil, ::T.untyped) HOMEBREW_PRODUCT = ::T.let(nil, ::T.untyped)
HOMEBREW_PULL_API_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_PULL_API_REGEX = ::T.let(nil, ::T.untyped)
HOMEBREW_PULL_OR_COMMIT_URL_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_PULL_OR_COMMIT_URL_REGEX = ::T.let(nil, ::T.untyped)
@ -3571,6 +3557,7 @@ class Object
HOMEBREW_REQUIRED_RUBY_VERSION = ::T.let(nil, ::T.untyped) HOMEBREW_REQUIRED_RUBY_VERSION = ::T.let(nil, ::T.untyped)
HOMEBREW_RUBY_EXEC_ARGS = ::T.let(nil, ::T.untyped) HOMEBREW_RUBY_EXEC_ARGS = ::T.let(nil, ::T.untyped)
HOMEBREW_SHIMS_PATH = ::T.let(nil, ::T.untyped) HOMEBREW_SHIMS_PATH = ::T.let(nil, ::T.untyped)
HOMEBREW_SYSTEM = ::T.let(nil, ::T.untyped)
HOMEBREW_TAP_CASK_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_TAP_CASK_REGEX = ::T.let(nil, ::T.untyped)
HOMEBREW_TAP_DIR_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_TAP_DIR_REGEX = ::T.let(nil, ::T.untyped)
HOMEBREW_TAP_FORMULA_REGEX = ::T.let(nil, ::T.untyped) HOMEBREW_TAP_FORMULA_REGEX = ::T.let(nil, ::T.untyped)
@ -3620,7 +3607,7 @@ class Object
def self.yaml_tag(url); end def self.yaml_tag(url); end
end end
module OnOS module OnSystem
extend ::T::Private::Methods::MethodHooks extend ::T::Private::Methods::MethodHooks
extend ::T::Private::Methods::SingletonMethodHooks extend ::T::Private::Methods::SingletonMethodHooks
end end
@ -4341,6 +4328,29 @@ end
class Resource class Resource
include ::FileUtils::StreamUtils_ include ::FileUtils::StreamUtils_
def on_arm(&block); end
def on_big_sur(or_condition=T.unsafe(nil), &block); end
def on_catalina(or_condition=T.unsafe(nil), &block); end
def on_el_capitan(or_condition=T.unsafe(nil), &block); end
def on_high_sierra(or_condition=T.unsafe(nil), &block); end
def on_intel(&block); end
def on_linux(&block); end
def on_macos(&block); end
def on_mojave(or_condition=T.unsafe(nil), &block); end
def on_monterey(or_condition=T.unsafe(nil), &block); end
def on_sierra(or_condition=T.unsafe(nil), &block); end
def on_ventura(or_condition=T.unsafe(nil), &block); end
end end
class Resource::Partial class Resource::Partial
@ -4939,9 +4949,16 @@ end
module RuboCop::AST::NodePattern::Sets module RuboCop::AST::NodePattern::Sets
SET_BUILD_RECOMMENDED_TEST_OPTIONAL = ::T.let(nil, ::T.untyped) SET_BUILD_RECOMMENDED_TEST_OPTIONAL = ::T.let(nil, ::T.untyped)
SET_DEPENDS_ON_USES_FROM_MACOS = ::T.let(nil, ::T.untyped) SET_DEPENDS_ON_USES_FROM_MACOS = ::T.let(nil, ::T.untyped)
SET_EXIST_EXISTS = ::T.let(nil, ::T.untyped)
SET_FILETEST_FILE_DIR_SHELL = ::T.let(nil, ::T.untyped)
SET_INCLUDE_WITH_WITHOUT = ::T.let(nil, ::T.untyped) SET_INCLUDE_WITH_WITHOUT = ::T.let(nil, ::T.untyped)
SET_SYSTEM_SHELL_OUTPUT_PIPE_OUTPUT = ::T.let(nil, ::T.untyped) SET_SYSTEM_SHELL_OUTPUT_PIPE_OUTPUT = ::T.let(nil, ::T.untyped)
SET_WITH_WITHOUT = ::T.let(nil, ::T.untyped) SET_WITH_WITHOUT = ::T.let(nil, ::T.untyped)
SET__EQL_ = ::T.let(nil, ::T.untyped)
SET__FETCH = ::T.let(nil, ::T.untyped)
SET___EQL_ETC = ::T.let(nil, ::T.untyped)
SET___EQL_INCLUDE = ::T.let(nil, ::T.untyped)
SET_____2 = ::T.let(nil, ::T.untyped)
end end
class RuboCop::Cask::AST::CaskHeader class RuboCop::Cask::AST::CaskHeader

View File

@ -129,13 +129,6 @@ module Cask
def token_conflicts?; end def token_conflicts?; end
end end
class DSL
class Caveats < Base
sig { returns(T::Boolean) }
def discontinued?; end
end
end
class Installer class Installer
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def binaries?; end def binaries?; end
@ -170,4 +163,14 @@ module Cask
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def quiet?; end def quiet?; end
end end
class DSL
class Caveats < Base
sig { returns(T::Boolean) }
def discontinued?; end
end
sig { returns(T::Boolean) }
def on_system_blocks_exist?; end
end
end end

View File

@ -1,11 +1,11 @@
# typed: false # typed: false
# frozen_string_literal: true # frozen_string_literal: true
homebrew_bootsnap_enabled = !ENV["HOMEBREW_NO_BOOTSNAP"] && ENV["HOMEBREW_BOOTSNAP"] homebrew_bootsnap_enabled = ENV["HOMEBREW_NO_BOOTSNAP"].nil? && !ENV["HOMEBREW_BOOTSNAP"].nil?
# portable ruby doesn't play nice with bootsnap # portable ruby doesn't play nice with bootsnap
# Can't use .exclude? here because we haven't required active_support yet. # Can't use .exclude? here because we haven't required active_support yet.
homebrew_bootsnap_enabled &&= !ENV["HOMEBREW_RUBY_PATH"].to_s.include?("/vendor/portable-ruby/") # rubocop:disable Rails/NegateInclude homebrew_bootsnap_enabled &&= !RUBY_PATH.to_s.include?("/vendor/portable-ruby/") # rubocop:disable Rails/NegateInclude
homebrew_bootsnap_enabled &&= if ENV["HOMEBREW_MACOS_VERSION"] homebrew_bootsnap_enabled &&= if ENV["HOMEBREW_MACOS_VERSION"]
# Apple Silicon doesn't play nice with bootsnap # Apple Silicon doesn't play nice with bootsnap
@ -24,14 +24,14 @@ if homebrew_bootsnap_enabled
Homebrew.install_bundler_gems!(only_warn_on_failure: true) Homebrew.install_bundler_gems!(only_warn_on_failure: true)
ENV["HOMEBREW_BOOTSNAP_RETRY"] = "1" ENV["HOMEBREW_BOOTSNAP_RETRY"] = "1"
exec ENV["HOMEBREW_BREW_FILE"], *ARGV exec ENV.fetch("HOMEBREW_BREW_FILE"), *ARGV
end end
end end
ENV.delete("HOMEBREW_BOOTSNAP_RETRY") ENV.delete("HOMEBREW_BOOTSNAP_RETRY")
if defined?(Bootsnap) if defined?(Bootsnap)
cache = ENV["HOMEBREW_CACHE"] || ENV["HOMEBREW_DEFAULT_CACHE"] cache = ENV.fetch("HOMEBREW_CACHE", nil) || ENV.fetch("HOMEBREW_DEFAULT_CACHE", nil)
# Can't use .blank? here because we haven't required active_support yet. # Can't use .blank? here because we haven't required active_support yet.
raise "Needs HOMEBREW_CACHE or HOMEBREW_DEFAULT_CACHE!" if cache.nil? || cache.empty? # rubocop:disable Rails/Blank raise "Needs HOMEBREW_CACHE or HOMEBREW_DEFAULT_CACHE!" if cache.nil? || cache.empty? # rubocop:disable Rails/Blank

View File

@ -4,29 +4,16 @@
raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!" unless ENV["HOMEBREW_BREW_FILE"] raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!" unless ENV["HOMEBREW_BREW_FILE"]
# Path to `bin/brew` main executable in `HOMEBREW_PREFIX` # Path to `bin/brew` main executable in `HOMEBREW_PREFIX`
HOMEBREW_BREW_FILE = Pathname(ENV["HOMEBREW_BREW_FILE"]).freeze HOMEBREW_BREW_FILE = Pathname(ENV.fetch("HOMEBREW_BREW_FILE")).freeze
class MissingEnvironmentVariables < RuntimeError; end
# Helper module for getting environment variables which must be set.
#
# @api private
module EnvVar
def self.[](env)
raise MissingEnvironmentVariables, "#{env} was not exported!" unless ENV[env]
ENV.fetch(env)
end
end
# Where we link under # Where we link under
HOMEBREW_PREFIX = Pathname(EnvVar["HOMEBREW_PREFIX"]).freeze HOMEBREW_PREFIX = Pathname(ENV.fetch("HOMEBREW_PREFIX")).freeze
# Where `.git` is found # Where `.git` is found
HOMEBREW_REPOSITORY = Pathname(EnvVar["HOMEBREW_REPOSITORY"]).freeze HOMEBREW_REPOSITORY = Pathname(ENV.fetch("HOMEBREW_REPOSITORY")).freeze
# Where we store most of Homebrew, taps, and various metadata # Where we store most of Homebrew, taps, and various metadata
HOMEBREW_LIBRARY = Pathname(EnvVar["HOMEBREW_LIBRARY"]).freeze HOMEBREW_LIBRARY = Pathname(ENV.fetch("HOMEBREW_LIBRARY")).freeze
# Where shim scripts for various build and SCM tools are stored # Where shim scripts for various build and SCM tools are stored
HOMEBREW_SHIMS_PATH = (HOMEBREW_LIBRARY/"Homebrew/shims").freeze HOMEBREW_SHIMS_PATH = (HOMEBREW_LIBRARY/"Homebrew/shims").freeze
@ -44,19 +31,19 @@ HOMEBREW_PINNED_KEGS = (HOMEBREW_PREFIX/"var/homebrew/pinned").freeze
HOMEBREW_LOCKS = (HOMEBREW_PREFIX/"var/homebrew/locks").freeze HOMEBREW_LOCKS = (HOMEBREW_PREFIX/"var/homebrew/locks").freeze
# Where we store built products # Where we store built products
HOMEBREW_CELLAR = Pathname(EnvVar["HOMEBREW_CELLAR"]).freeze HOMEBREW_CELLAR = Pathname(ENV.fetch("HOMEBREW_CELLAR")).freeze
# Where downloads (bottles, source tarballs, etc.) are cached # Where downloads (bottles, source tarballs, etc.) are cached
HOMEBREW_CACHE = Pathname(EnvVar["HOMEBREW_CACHE"]).freeze HOMEBREW_CACHE = Pathname(ENV.fetch("HOMEBREW_CACHE")).freeze
# Where formulae installed via URL are cached # Where formulae installed via URL are cached
HOMEBREW_CACHE_FORMULA = (HOMEBREW_CACHE/"Formula").freeze HOMEBREW_CACHE_FORMULA = (HOMEBREW_CACHE/"Formula").freeze
# Where build, postinstall, and test logs of formulae are written to # Where build, postinstall, and test logs of formulae are written to
HOMEBREW_LOGS = Pathname(EnvVar["HOMEBREW_LOGS"]).expand_path.freeze HOMEBREW_LOGS = Pathname(ENV.fetch("HOMEBREW_LOGS")).expand_path.freeze
# Must use `/tmp` instead of `TMPDIR` because long paths break Unix domain sockets # Must use `/tmp` instead of `TMPDIR` because long paths break Unix domain sockets
HOMEBREW_TEMP = Pathname(EnvVar["HOMEBREW_TEMP"]).yield_self do |tmp| HOMEBREW_TEMP = Pathname(ENV.fetch("HOMEBREW_TEMP")).then do |tmp|
tmp.mkpath unless tmp.exist? tmp.mkpath unless tmp.exist?
tmp.realpath tmp.realpath
end.freeze end.freeze
@ -64,5 +51,5 @@ end.freeze
# The Ruby path and args to use for forked Ruby calls # The Ruby path and args to use for forked Ruby calls
HOMEBREW_RUBY_EXEC_ARGS = [ HOMEBREW_RUBY_EXEC_ARGS = [
RUBY_PATH, RUBY_PATH,
ENV["HOMEBREW_RUBY_WARNINGS"], ENV.fetch("HOMEBREW_RUBY_WARNINGS"),
].freeze ].freeze

View File

@ -97,7 +97,7 @@ module Homebrew
--force-exclusion --force-exclusion
] ]
args << if fix args << if fix
"--auto-correct-all" "--autocorrect-all"
else else
"--parallel" "--parallel"
end end

View File

@ -34,7 +34,7 @@ describe Cask::Artifact::Installer, :cask do
expect(command).to receive(:run!).with( expect(command).to receive(:run!).with(
executable, executable,
a_hash_including( a_hash_including(
env: { "PATH" => PATH.new("#{HOMEBREW_PREFIX}/bin", "#{HOMEBREW_PREFIX}/sbin", ENV["PATH"]) }, env: { "PATH" => PATH.new("#{HOMEBREW_PREFIX}/bin", "#{HOMEBREW_PREFIX}/sbin", ENV.fetch("PATH")) },
), ),
) )

View File

@ -19,9 +19,9 @@ describe Cask::Artifact::Pkg, :cask do
sudo: true, sudo: true,
print_stdout: true, print_stdout: true,
env: { env: {
"LOGNAME" => ENV["USER"], "LOGNAME" => ENV.fetch("USER"),
"USER" => ENV["USER"], "USER" => ENV.fetch("USER"),
"USERNAME" => ENV["USER"], "USERNAME" => ENV.fetch("USER"),
}, },
) )
@ -68,9 +68,9 @@ describe Cask::Artifact::Pkg, :cask do
sudo: true, sudo: true,
print_stdout: true, print_stdout: true,
env: { env: {
"LOGNAME" => ENV["USER"], "LOGNAME" => ENV.fetch("USER"),
"USER" => ENV["USER"], "USER" => ENV.fetch("USER"),
"USERNAME" => ENV["USER"], "USERNAME" => ENV.fetch("USER"),
}, },
) )

View File

@ -120,7 +120,9 @@ describe Cask::Cmd::List, :cask do
}, },
"conflicts_with": null, "conflicts_with": null,
"container": null, "container": null,
"auto_updates": null "auto_updates": null,
"variations": {
}
}, },
{ {
"token": "local-transmission", "token": "local-transmission",
@ -149,7 +151,9 @@ describe Cask::Cmd::List, :cask do
}, },
"conflicts_with": null, "conflicts_with": null,
"container": null, "container": null,
"auto_updates": null "auto_updates": null,
"variations": {
}
}, },
{ {
"token": "multiple-versions", "token": "multiple-versions",
@ -160,11 +164,13 @@ describe Cask::Cmd::List, :cask do
], ],
"desc": null, "desc": null,
"homepage": "https://brew.sh/", "homepage": "https://brew.sh/",
"url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip", "url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine/1.2.3/arm.zip",
"appcast": null, "appcast": null,
"version": "1.2.3", "version": "1.2.3",
"versions": { "versions": {
"test_os": "1.2.0" "big_sur": "1.2.0",
"catalina": "1.0.0",
"mojave": "1.0.0"
}, },
"installed": "1.2.3", "installed": "1.2.3",
"outdated": false, "outdated": false,
@ -179,7 +185,32 @@ describe Cask::Cmd::List, :cask do
}, },
"conflicts_with": null, "conflicts_with": null,
"container": null, "container": null,
"auto_updates": null "auto_updates": null,
"variations": {
"arm_big_sur": {
"url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine/1.2.0/arm.zip",
"version": "1.2.0",
"sha256": "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"
},
"intel_monterey": {
"url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine/1.2.3/intel.zip"
},
"intel_big_sur": {
"url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine/1.2.0/intel.zip",
"version": "1.2.0",
"sha256": "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"
},
"intel_catalina": {
"url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine/1.0.0/intel.zip",
"version": "1.0.0",
"sha256": "1866dfa833b123bb8fe7fa7185ebf24d28d300d0643d75798bc23730af734216"
},
"intel_mojave": {
"url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine/1.0.0/intel.zip",
"version": "1.0.0",
"sha256": "1866dfa833b123bb8fe7fa7185ebf24d28d300d0643d75798bc23730af734216"
}
}
}, },
{ {
"token": "third-party-cask", "token": "third-party-cask",
@ -208,19 +239,34 @@ describe Cask::Cmd::List, :cask do
}, },
"conflicts_with": null, "conflicts_with": null,
"container": null, "container": null,
"auto_updates": null "auto_updates": null,
"variations": {
}
} }
] ]
EOS EOS
} }
let(:original_macos_version) { MacOS.full_version.to_s }
before do before do
casks.map(&Cask::CaskLoader.method(:load)).each(&InstallHelper.method(:install_with_caskfile)) # Use a more limited symbols list to shorten the variations hash
symbols = {
monterey: "12",
big_sur: "11",
catalina: "10.15",
mojave: "10.14",
}
stub_const("MacOSVersions::SYMBOLS", symbols)
# Add a test OS to ensure that all cask versions are listed regardless of OS. # For consistency, always run on Monterey and ARM
symbols = MacOS::Version::SYMBOLS.dup MacOS.full_version = "12"
symbols[:test_os] = "10.9" allow(Hardware::CPU).to receive(:type).and_return(:arm)
stub_const("MacOS::Version::SYMBOLS", symbols)
casks.map(&Cask::CaskLoader.method(:load)).each(&InstallHelper.method(:install_with_caskfile))
end
after do
MacOS.full_version = original_macos_version
end end
it "of all installed Casks" do it "of all installed Casks" do

View File

@ -8,7 +8,7 @@ describe "brew --caskroom" do
it "prints Homebrew's Caskroom", :integration_test do it "prints Homebrew's Caskroom", :integration_test do
expect { brew_sh "--caskroom" } expect { brew_sh "--caskroom" }
.to output("#{ENV["HOMEBREW_PREFIX"]}/Caskroom\n").to_stdout .to output("#{ENV.fetch("HOMEBREW_PREFIX")}/Caskroom\n").to_stdout
.and not_to_output.to_stderr .and not_to_output.to_stderr
.and be_a_success .and be_a_success
end end

View File

@ -8,7 +8,7 @@ describe "brew --cellar" do
it "prints Homebrew's Cellar", :integration_test do it "prints Homebrew's Cellar", :integration_test do
expect { brew_sh "--cellar" } expect { brew_sh "--cellar" }
.to output("#{ENV["HOMEBREW_CELLAR"]}\n").to_stdout .to output("#{ENV.fetch("HOMEBREW_CELLAR")}\n").to_stdout
.and not_to_output.to_stderr .and not_to_output.to_stderr
.and be_a_success .and be_a_success
end end

View File

@ -8,14 +8,14 @@ describe "brew --prefix" do
it "prints Homebrew's prefix", :integration_test do it "prints Homebrew's prefix", :integration_test do
expect { brew_sh "--prefix" } expect { brew_sh "--prefix" }
.to output("#{ENV["HOMEBREW_PREFIX"]}\n").to_stdout .to output("#{ENV.fetch("HOMEBREW_PREFIX")}\n").to_stdout
.and not_to_output.to_stderr .and not_to_output.to_stderr
.and be_a_success .and be_a_success
end end
it "prints the prefix for a Formula", :integration_test do it "prints the prefix for a Formula", :integration_test do
expect { brew_sh "--prefix", "wget" } expect { brew_sh "--prefix", "wget" }
.to output("#{ENV["HOMEBREW_PREFIX"]}/opt/wget\n").to_stdout .to output("#{ENV.fetch("HOMEBREW_PREFIX")}/opt/wget\n").to_stdout
.and not_to_output.to_stderr .and not_to_output.to_stderr
.and be_a_success .and be_a_success
end end

View File

@ -8,7 +8,7 @@ describe "brew --repository" do
it "prints Homebrew's repository", :integration_test do it "prints Homebrew's repository", :integration_test do
expect { brew_sh "--repository" } expect { brew_sh "--repository" }
.to output("#{ENV["HOMEBREW_REPOSITORY"]}\n").to_stdout .to output("#{ENV.fetch("HOMEBREW_REPOSITORY")}\n").to_stdout
.and not_to_output.to_stderr .and not_to_output.to_stderr
.and be_a_success .and be_a_success
end end

View File

@ -13,7 +13,7 @@ describe "brew custom-external-command", :integration_test do
SH SH
FileUtils.chmod "+x", file FileUtils.chmod "+x", file
expect { brew cmd, "PATH" => "#{path}#{File::PATH_SEPARATOR}#{ENV["PATH"]}" } expect { brew cmd, "PATH" => "#{path}#{File::PATH_SEPARATOR}#{ENV.fetch("PATH")}" }
.to output("I am #{cmd}.\n").to_stdout .to output("I am #{cmd}.\n").to_stdout
.and not_to_output.to_stderr .and not_to_output.to_stderr
.and be_a_success .and be_a_success

View File

@ -20,7 +20,7 @@ describe Homebrew::Diagnostic::Checks do
FileUtils.chmod 0755, anaconda FileUtils.chmod 0755, anaconda
FileUtils.chmod 0755, python FileUtils.chmod 0755, python
ENV["PATH"] = "#{path}#{File::PATH_SEPARATOR}#{ENV["PATH"]}" ENV["PATH"] = "#{path}#{File::PATH_SEPARATOR}#{ENV.fetch("PATH")}"
expect(checks.check_for_anaconda).to match("Anaconda") expect(checks.check_for_anaconda).to match("Anaconda")
end end
@ -75,10 +75,12 @@ describe Homebrew::Diagnostic::Checks do
specify "#check_user_path_3" do specify "#check_user_path_3" do
sbin = HOMEBREW_PREFIX/"sbin" sbin = HOMEBREW_PREFIX/"sbin"
ENV["HOMEBREW_PATH"] = (sbin/"something").mkpath
homebrew_path =
"#{HOMEBREW_PREFIX}/bin#{File::PATH_SEPARATOR}" + "#{HOMEBREW_PREFIX}/bin#{File::PATH_SEPARATOR}" +
ENV["HOMEBREW_PATH"].gsub(/(?:^|#{Regexp.escape(File::PATH_SEPARATOR)})#{Regexp.escape(sbin)}/, "") ENV["HOMEBREW_PATH"].gsub(/(?:^|#{Regexp.escape(File::PATH_SEPARATOR)})#{Regexp.escape(sbin)}/, "")
(sbin/"something").mkpath stub_const("ORIGINAL_PATHS", PATH.new(homebrew_path).map { |path| Pathname.new(path).expand_path }.compact)
expect(checks.check_user_path_1).to be_nil expect(checks.check_user_path_1).to be_nil
expect(checks.check_user_path_2).to be_nil expect(checks.check_user_path_2).to be_nil
@ -93,8 +95,7 @@ describe Homebrew::Diagnostic::Checks do
file = "#{path}/foo-config" file = "#{path}/foo-config"
FileUtils.touch file FileUtils.touch file
FileUtils.chmod 0755, file FileUtils.chmod 0755, file
ENV["HOMEBREW_PATH"] = ENV["PATH"] = ENV["PATH"] = "#{path}#{File::PATH_SEPARATOR}#{ENV.fetch("PATH")}"
"#{path}#{File::PATH_SEPARATOR}#{ENV["PATH"]}"
expect(checks.check_for_config_scripts) expect(checks.check_for_config_scripts)
.to match('"config" scripts exist') .to match('"config" scripts exist')

View File

@ -1580,4 +1580,117 @@ describe Formula do
expect(f.test).to eq(2) expect(f.test).to eq(2)
end end
end end
describe "on_{os_version} blocks", :needs_macos do
before do
Homebrew::SimulateSystem.os = :monterey
end
after do
Homebrew::SimulateSystem.clear
end
let(:f) do
Class.new(Testball) do
@test = 0
attr_reader :test
def install
on_monterey :or_newer do
@test = 1
end
on_big_sur do
@test = 2
end
on_catalina :or_older do
@test = 3
end
end
end.new
end
it "only calls code within `on_monterey`" do
Homebrew::SimulateSystem.os = :monterey
f.brew { f.install }
expect(f.test).to eq(1)
end
it "only calls code within `on_monterey :or_newer`" do
Homebrew::SimulateSystem.os = :ventura
f.brew { f.install }
expect(f.test).to eq(1)
end
it "only calls code within `on_big_sur`" do
Homebrew::SimulateSystem.os = :big_sur
f.brew { f.install }
expect(f.test).to eq(2)
end
it "only calls code within `on_catalina`" do
Homebrew::SimulateSystem.os = :catalina
f.brew { f.install }
expect(f.test).to eq(3)
end
it "only calls code within `on_catalina :or_older`" do
Homebrew::SimulateSystem.os = :mojave
f.brew { f.install }
expect(f.test).to eq(3)
end
end
describe "#on_arm" do
before do
allow(Hardware::CPU).to receive(:type).and_return(:arm)
end
let(:f) do
Class.new(Testball) do
@test = 0
attr_reader :test
def install
on_arm do
@test = 1
end
on_intel do
@test = 2
end
end
end.new
end
it "only calls code within on_arm" do
f.brew { f.install }
expect(f.test).to eq(1)
end
end
describe "#on_intel" do
before do
allow(Hardware::CPU).to receive(:type).and_return(:intel)
end
let(:f) do
Class.new(Testball) do
@test = 0
attr_reader :test
def install
on_arm do
@test = 1
end
on_intel do
@test = 2
end
end
end.new
end
it "only calls code within on_intel" do
f.brew { f.install }
expect(f.test).to eq(2)
end
end
end end

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