Merge branch 'master' into move-cask/cmd/uninstall
This commit is contained in:
commit
da6f48dbd0
@ -189,14 +189,7 @@ Naming/MethodParameterName:
|
||||
- AllowedNames
|
||||
AllowedNames:
|
||||
[
|
||||
"a",
|
||||
"b",
|
||||
"c1",
|
||||
"c2",
|
||||
"e",
|
||||
"f",
|
||||
"o",
|
||||
"pr",
|
||||
"pr", # TODO: Remove if https://github.com/rubocop/rubocop/pull/11690 is merged or we change the variable names.
|
||||
]
|
||||
|
||||
# Both styles are used depending on context,
|
||||
@ -324,7 +317,6 @@ Style/AutoResourceCleanup:
|
||||
Style/BarePercentLiterals:
|
||||
EnforcedStyle: percent_q
|
||||
|
||||
# make rspec formatting more flexible
|
||||
Style/BlockDelimiters:
|
||||
BracesRequiredMethods:
|
||||
- "sig"
|
||||
|
||||
@ -58,7 +58,8 @@ module Homebrew
|
||||
|
||||
skip_download = target.exist? &&
|
||||
!target.empty? &&
|
||||
(Homebrew::EnvConfig.no_auto_update? ||
|
||||
(!Homebrew.auto_update_command? ||
|
||||
Homebrew::EnvConfig.no_auto_update? ||
|
||||
((Time.now - Homebrew::EnvConfig.api_auto_update_secs.to_i) < target.mtime))
|
||||
skip_download ||= Homebrew.running_as_root_but_not_owned_by_root?
|
||||
|
||||
|
||||
@ -269,17 +269,7 @@ auto-update() {
|
||||
# If we've checked for updates, we don't need to check again.
|
||||
export HOMEBREW_AUTO_UPDATE_CHECKED="1"
|
||||
|
||||
AUTO_UPDATE_COMMANDS=(
|
||||
install
|
||||
upgrade
|
||||
bump-formula-pr
|
||||
bump-cask-pr
|
||||
bundle
|
||||
release
|
||||
)
|
||||
|
||||
if check-array-membership "${HOMEBREW_COMMAND}" "${AUTO_UPDATE_COMMANDS[@]}" ||
|
||||
[[ "${HOMEBREW_COMMAND}" == "tap" && "${HOMEBREW_ARG_COUNT}" -gt 1 ]]
|
||||
if [[ -n "${HOMEBREW_AUTO_UPDATE_COMMAND}" ]]
|
||||
then
|
||||
export HOMEBREW_AUTO_UPDATING="1"
|
||||
|
||||
@ -816,6 +806,22 @@ then
|
||||
unset HOMEBREW_RUBY_WARNINGS
|
||||
fi
|
||||
|
||||
# Check for commands that should call `brew update --auto-update` first.
|
||||
AUTO_UPDATE_COMMANDS=(
|
||||
install
|
||||
outdated
|
||||
upgrade
|
||||
bump-formula-pr
|
||||
bump-cask-pr
|
||||
bundle
|
||||
release
|
||||
)
|
||||
if check-array-membership "${HOMEBREW_COMMAND}" "${AUTO_UPDATE_COMMANDS[@]}" ||
|
||||
[[ "${HOMEBREW_COMMAND}" == "tap" && "${HOMEBREW_ARG_COUNT}" -gt 1 ]]
|
||||
then
|
||||
export HOMEBREW_AUTO_UPDATE_COMMAND="1"
|
||||
fi
|
||||
|
||||
# Disable Ruby options we don't need.
|
||||
export HOMEBREW_RUBY_DISABLE_OPTIONS="--disable=gems,rubyopt"
|
||||
|
||||
|
||||
@ -198,19 +198,19 @@ class Build
|
||||
keg.detect_cxx_stdlibs(skip_executables: true)
|
||||
end
|
||||
|
||||
def fixopt(f)
|
||||
path = if f.linked_keg.directory? && f.linked_keg.symlink?
|
||||
f.linked_keg.resolved_path
|
||||
elsif f.prefix.directory?
|
||||
f.prefix
|
||||
elsif (kids = f.rack.children).size == 1 && kids.first.directory?
|
||||
def fixopt(formula)
|
||||
path = if formula.linked_keg.directory? && formula.linked_keg.symlink?
|
||||
formula.linked_keg.resolved_path
|
||||
elsif formula.prefix.directory?
|
||||
formula.prefix
|
||||
elsif (kids = formula.rack.children).size == 1 && kids.first.directory?
|
||||
kids.first
|
||||
else
|
||||
raise
|
||||
end
|
||||
Keg.new(path).optlink(verbose: args.verbose?)
|
||||
rescue
|
||||
raise "#{f.opt_prefix} not present or broken\nPlease reinstall #{f.full_name}. Sorry :("
|
||||
raise "#{formula.opt_prefix} not present or broken\nPlease reinstall #{formula.full_name}. Sorry :("
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -18,9 +18,9 @@ class BuildEnvironment
|
||||
self
|
||||
end
|
||||
|
||||
sig { params(o: Symbol).returns(T.self_type) }
|
||||
def <<(o)
|
||||
@settings << o
|
||||
sig { params(option: Symbol).returns(T.self_type) }
|
||||
def <<(option)
|
||||
@settings << option
|
||||
self
|
||||
end
|
||||
|
||||
@ -68,21 +68,21 @@ class BuildEnvironment
|
||||
KEYS & env.keys
|
||||
end
|
||||
|
||||
sig { params(env: T::Hash[String, T.nilable(T.any(String, Pathname))], f: IO).void }
|
||||
def self.dump(env, f = $stdout)
|
||||
sig { params(env: T::Hash[String, T.nilable(T.any(String, Pathname))], out: IO).void }
|
||||
def self.dump(env, out = $stdout)
|
||||
keys = self.keys(env)
|
||||
keys -= %w[CC CXX OBJC OBJCXX] if env["CC"] == env["HOMEBREW_CC"]
|
||||
|
||||
keys.each do |key|
|
||||
value = env.fetch(key)
|
||||
|
||||
s = +"#{key}: #{value}"
|
||||
string = +"#{key}: #{value}"
|
||||
case key
|
||||
when "CC", "CXX", "LD"
|
||||
s << " => #{Pathname.new(value).realpath}" if value.present? && File.symlink?(value)
|
||||
string << " => #{Pathname.new(value).realpath}" if value.present? && File.symlink?(value)
|
||||
end
|
||||
s.freeze
|
||||
f.puts s
|
||||
string.freeze
|
||||
out.puts string
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -14,7 +14,6 @@ require "cask/cmd/audit"
|
||||
require "cask/cmd/fetch"
|
||||
require "cask/cmd/install"
|
||||
require "cask/cmd/reinstall"
|
||||
require "cask/cmd/upgrade"
|
||||
|
||||
module Cask
|
||||
# Implementation of the `brew cask` command-line interface.
|
||||
|
||||
@ -1,257 +0,0 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "env_config"
|
||||
require "cask/config"
|
||||
|
||||
module Cask
|
||||
class Cmd
|
||||
# Cask implementation of the `brew upgrade` command.
|
||||
#
|
||||
# @api private
|
||||
class Upgrade < AbstractCommand
|
||||
extend T::Sig
|
||||
|
||||
OPTIONS = [
|
||||
[:switch, "--skip-cask-deps", {
|
||||
description: "Skip installing cask dependencies.",
|
||||
}],
|
||||
[:switch, "-g", "--greedy", {
|
||||
description: "Also include casks with `auto_updates true` or `version :latest`.",
|
||||
}],
|
||||
[:switch, "--greedy-latest", {
|
||||
description: "Also include casks with `version :latest`.",
|
||||
}],
|
||||
[:switch, "--greedy-auto-updates", {
|
||||
description: "Also include casks with `auto_updates true`.",
|
||||
}],
|
||||
].freeze
|
||||
|
||||
sig { returns(Homebrew::CLI::Parser) }
|
||||
def self.parser
|
||||
super do
|
||||
switch "--force",
|
||||
description: "Force overwriting existing files."
|
||||
switch "--dry-run",
|
||||
description: "Show what would be upgraded, but do not actually upgrade anything."
|
||||
|
||||
OPTIONS.map(&:dup).each do |option|
|
||||
kwargs = option.pop
|
||||
send(*option, **kwargs)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def run
|
||||
verbose = ($stdout.tty? || args.verbose?) && !args.quiet?
|
||||
self.class.upgrade_casks(
|
||||
*casks,
|
||||
force: args.force?,
|
||||
greedy: args.greedy?,
|
||||
greedy_latest: args.greedy_latest?,
|
||||
greedy_auto_updates: args.greedy_auto_updates?,
|
||||
dry_run: args.dry_run?,
|
||||
binaries: args.binaries?,
|
||||
quarantine: args.quarantine?,
|
||||
require_sha: args.require_sha?,
|
||||
skip_cask_deps: args.skip_cask_deps?,
|
||||
verbose: verbose,
|
||||
args: args,
|
||||
)
|
||||
end
|
||||
|
||||
sig {
|
||||
params(
|
||||
casks: Cask,
|
||||
args: Homebrew::CLI::Args,
|
||||
force: T.nilable(T::Boolean),
|
||||
greedy: T.nilable(T::Boolean),
|
||||
greedy_latest: T.nilable(T::Boolean),
|
||||
greedy_auto_updates: T.nilable(T::Boolean),
|
||||
dry_run: T.nilable(T::Boolean),
|
||||
skip_cask_deps: T.nilable(T::Boolean),
|
||||
verbose: T.nilable(T::Boolean),
|
||||
binaries: T.nilable(T::Boolean),
|
||||
quarantine: T.nilable(T::Boolean),
|
||||
require_sha: T.nilable(T::Boolean),
|
||||
).returns(T::Boolean)
|
||||
}
|
||||
def self.upgrade_casks(
|
||||
*casks,
|
||||
args:,
|
||||
force: false,
|
||||
greedy: false,
|
||||
greedy_latest: false,
|
||||
greedy_auto_updates: false,
|
||||
dry_run: false,
|
||||
skip_cask_deps: false,
|
||||
verbose: false,
|
||||
binaries: nil,
|
||||
quarantine: nil,
|
||||
require_sha: nil
|
||||
)
|
||||
|
||||
quarantine = true if quarantine.nil?
|
||||
|
||||
outdated_casks = if casks.empty?
|
||||
Caskroom.casks(config: Config.from_args(args)).select do |cask|
|
||||
cask.outdated?(greedy: greedy, greedy_latest: greedy_latest,
|
||||
greedy_auto_updates: greedy_auto_updates)
|
||||
end
|
||||
else
|
||||
casks.select do |cask|
|
||||
raise CaskNotInstalledError, cask if !cask.installed? && !force
|
||||
|
||||
if cask.outdated?(greedy: true)
|
||||
true
|
||||
elsif cask.version.latest?
|
||||
opoo "Not upgrading #{cask.token}, the downloaded artifact has not changed"
|
||||
false
|
||||
else
|
||||
opoo "Not upgrading #{cask.token}, the latest version is already installed"
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
manual_installer_casks = outdated_casks.select do |cask|
|
||||
cask.artifacts.any?(Artifact::Installer::ManualInstaller)
|
||||
end
|
||||
|
||||
if manual_installer_casks.present?
|
||||
count = manual_installer_casks.count
|
||||
ofail "Not upgrading #{count} `installer manual` #{::Utils.pluralize("cask", count)}."
|
||||
puts manual_installer_casks.map(&:to_s)
|
||||
outdated_casks -= manual_installer_casks
|
||||
end
|
||||
|
||||
return false if outdated_casks.empty?
|
||||
|
||||
if casks.empty? && !greedy
|
||||
if !greedy_auto_updates && !greedy_latest
|
||||
ohai "Casks with 'auto_updates true' or 'version :latest' " \
|
||||
"will not be upgraded; pass `--greedy` to upgrade them."
|
||||
end
|
||||
if greedy_auto_updates && !greedy_latest
|
||||
ohai "Casks with 'version :latest' will not be upgraded; pass `--greedy-latest` to upgrade them."
|
||||
end
|
||||
if !greedy_auto_updates && greedy_latest
|
||||
ohai "Casks with 'auto_updates true' will not be upgraded; pass `--greedy-auto-updates` to upgrade them."
|
||||
end
|
||||
end
|
||||
|
||||
verb = dry_run ? "Would upgrade" : "Upgrading"
|
||||
oh1 "#{verb} #{outdated_casks.count} outdated #{::Utils.pluralize("package", outdated_casks.count)}:"
|
||||
|
||||
caught_exceptions = []
|
||||
|
||||
upgradable_casks = outdated_casks.map do |c|
|
||||
if !c.installed_caskfile.exist? && c.tap.to_s == "homebrew/cask" &&
|
||||
Homebrew::API::Cask.all_casks.key?(c.token)
|
||||
odie <<~EOS
|
||||
The cask '#{c.token}' was affected by a bug and cannot be upgraded as-is. To fix this, run:
|
||||
brew reinstall --cask --force #{c.token}
|
||||
EOS
|
||||
end
|
||||
|
||||
[CaskLoader.load(c.installed_caskfile), c]
|
||||
end
|
||||
|
||||
puts upgradable_casks
|
||||
.map { |(old_cask, new_cask)| "#{new_cask.full_name} #{old_cask.version} -> #{new_cask.version}" }
|
||||
.join("\n")
|
||||
return true if dry_run
|
||||
|
||||
upgradable_casks.each do |(old_cask, new_cask)|
|
||||
upgrade_cask(
|
||||
old_cask, new_cask,
|
||||
binaries: binaries, force: force, skip_cask_deps: skip_cask_deps, verbose: verbose,
|
||||
quarantine: quarantine, require_sha: require_sha
|
||||
)
|
||||
rescue => e
|
||||
caught_exceptions << e.exception("#{new_cask.full_name}: #{e}")
|
||||
next
|
||||
end
|
||||
|
||||
return true if caught_exceptions.empty?
|
||||
raise MultipleCaskErrors, caught_exceptions if caught_exceptions.count > 1
|
||||
raise caught_exceptions.first if caught_exceptions.count == 1
|
||||
end
|
||||
|
||||
def self.upgrade_cask(
|
||||
old_cask, new_cask,
|
||||
binaries:, force:, quarantine:, require_sha:, skip_cask_deps:, verbose:
|
||||
)
|
||||
require "cask/installer"
|
||||
|
||||
start_time = Time.now
|
||||
odebug "Started upgrade process for Cask #{old_cask}"
|
||||
old_config = old_cask.config
|
||||
|
||||
old_options = {
|
||||
binaries: binaries,
|
||||
verbose: verbose,
|
||||
force: force,
|
||||
upgrade: true,
|
||||
}.compact
|
||||
|
||||
old_cask_installer =
|
||||
Installer.new(old_cask, **old_options)
|
||||
|
||||
new_cask.config = new_cask.default_config.merge(old_config)
|
||||
|
||||
new_options = {
|
||||
binaries: binaries,
|
||||
verbose: verbose,
|
||||
force: force,
|
||||
skip_cask_deps: skip_cask_deps,
|
||||
require_sha: require_sha,
|
||||
upgrade: true,
|
||||
quarantine: quarantine,
|
||||
}.compact
|
||||
|
||||
new_cask_installer =
|
||||
Installer.new(new_cask, **new_options)
|
||||
|
||||
started_upgrade = false
|
||||
new_artifacts_installed = false
|
||||
|
||||
begin
|
||||
oh1 "Upgrading #{Formatter.identifier(old_cask)}"
|
||||
|
||||
# Start new cask's installation steps
|
||||
new_cask_installer.check_conflicts
|
||||
|
||||
if (caveats = new_cask_installer.caveats)
|
||||
puts caveats
|
||||
end
|
||||
|
||||
new_cask_installer.fetch
|
||||
|
||||
# Move the old cask's artifacts back to staging
|
||||
old_cask_installer.start_upgrade
|
||||
# And flag it so in case of error
|
||||
started_upgrade = true
|
||||
|
||||
# Install the new cask
|
||||
new_cask_installer.stage
|
||||
|
||||
new_cask_installer.install_artifacts
|
||||
new_artifacts_installed = true
|
||||
|
||||
# If successful, wipe the old cask from staging
|
||||
old_cask_installer.finalize_upgrade
|
||||
rescue => e
|
||||
new_cask_installer.uninstall_artifacts if new_artifacts_installed
|
||||
new_cask_installer.purge_versioned_files
|
||||
old_cask_installer.revert_upgrade if started_upgrade
|
||||
raise e
|
||||
end
|
||||
|
||||
end_time = Time.now
|
||||
Homebrew.messages.package_installed(new_cask.token, end_time - start_time)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Cask
|
||||
|
||||
7
Library/Homebrew/cask/metdata.rbi
Normal file
7
Library/Homebrew/cask/metdata.rbi
Normal file
@ -0,0 +1,7 @@
|
||||
# typed: strict
|
||||
|
||||
module Cask
|
||||
module Metadata
|
||||
requires_ancestor { Cask }
|
||||
end
|
||||
end
|
||||
204
Library/Homebrew/cask/upgrade.rb
Normal file
204
Library/Homebrew/cask/upgrade.rb
Normal file
@ -0,0 +1,204 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "env_config"
|
||||
require "cask/config"
|
||||
|
||||
module Cask
|
||||
# @api private
|
||||
class Upgrade
|
||||
extend T::Sig
|
||||
|
||||
sig {
|
||||
params(
|
||||
casks: Cask,
|
||||
args: Homebrew::CLI::Args,
|
||||
force: T.nilable(T::Boolean),
|
||||
greedy: T.nilable(T::Boolean),
|
||||
greedy_latest: T.nilable(T::Boolean),
|
||||
greedy_auto_updates: T.nilable(T::Boolean),
|
||||
dry_run: T.nilable(T::Boolean),
|
||||
skip_cask_deps: T.nilable(T::Boolean),
|
||||
verbose: T.nilable(T::Boolean),
|
||||
binaries: T.nilable(T::Boolean),
|
||||
quarantine: T.nilable(T::Boolean),
|
||||
require_sha: T.nilable(T::Boolean),
|
||||
).returns(T::Boolean)
|
||||
}
|
||||
def self.upgrade_casks(
|
||||
*casks,
|
||||
args:,
|
||||
force: false,
|
||||
greedy: false,
|
||||
greedy_latest: false,
|
||||
greedy_auto_updates: false,
|
||||
dry_run: false,
|
||||
skip_cask_deps: false,
|
||||
verbose: false,
|
||||
binaries: nil,
|
||||
quarantine: nil,
|
||||
require_sha: nil
|
||||
)
|
||||
|
||||
quarantine = true if quarantine.nil?
|
||||
|
||||
outdated_casks = if casks.empty?
|
||||
Caskroom.casks(config: Config.from_args(args)).select do |cask|
|
||||
cask.outdated?(greedy: greedy, greedy_latest: greedy_latest,
|
||||
greedy_auto_updates: greedy_auto_updates)
|
||||
end
|
||||
else
|
||||
casks.select do |cask|
|
||||
raise CaskNotInstalledError, cask if !cask.installed? && !force
|
||||
|
||||
if cask.outdated?(greedy: true)
|
||||
true
|
||||
elsif cask.version.latest?
|
||||
opoo "Not upgrading #{cask.token}, the downloaded artifact has not changed"
|
||||
false
|
||||
else
|
||||
opoo "Not upgrading #{cask.token}, the latest version is already installed"
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
manual_installer_casks = outdated_casks.select do |cask|
|
||||
cask.artifacts.any?(Artifact::Installer::ManualInstaller)
|
||||
end
|
||||
|
||||
if manual_installer_casks.present?
|
||||
count = manual_installer_casks.count
|
||||
ofail "Not upgrading #{count} `installer manual` #{::Utils.pluralize("cask", count)}."
|
||||
puts manual_installer_casks.map(&:to_s)
|
||||
outdated_casks -= manual_installer_casks
|
||||
end
|
||||
|
||||
return false if outdated_casks.empty?
|
||||
|
||||
if casks.empty? && !greedy
|
||||
if !greedy_auto_updates && !greedy_latest
|
||||
ohai "Casks with 'auto_updates true' or 'version :latest' " \
|
||||
"will not be upgraded; pass `--greedy` to upgrade them."
|
||||
end
|
||||
if greedy_auto_updates && !greedy_latest
|
||||
ohai "Casks with 'version :latest' will not be upgraded; pass `--greedy-latest` to upgrade them."
|
||||
end
|
||||
if !greedy_auto_updates && greedy_latest
|
||||
ohai "Casks with 'auto_updates true' will not be upgraded; pass `--greedy-auto-updates` to upgrade them."
|
||||
end
|
||||
end
|
||||
|
||||
verb = dry_run ? "Would upgrade" : "Upgrading"
|
||||
oh1 "#{verb} #{outdated_casks.count} outdated #{::Utils.pluralize("package", outdated_casks.count)}:"
|
||||
|
||||
caught_exceptions = []
|
||||
|
||||
upgradable_casks = outdated_casks.map do |c|
|
||||
if !c.installed_caskfile.exist? && c.tap.to_s == "homebrew/cask" &&
|
||||
Homebrew::API::Cask.all_casks.key?(c.token)
|
||||
odie <<~EOS
|
||||
The cask '#{c.token}' was affected by a bug and cannot be upgraded as-is. To fix this, run:
|
||||
brew reinstall --cask --force #{c.token}
|
||||
EOS
|
||||
end
|
||||
|
||||
[CaskLoader.load(c.installed_caskfile), c]
|
||||
end
|
||||
|
||||
puts upgradable_casks
|
||||
.map { |(old_cask, new_cask)| "#{new_cask.full_name} #{old_cask.version} -> #{new_cask.version}" }
|
||||
.join("\n")
|
||||
return true if dry_run
|
||||
|
||||
upgradable_casks.each do |(old_cask, new_cask)|
|
||||
upgrade_cask(
|
||||
old_cask, new_cask,
|
||||
binaries: binaries, force: force, skip_cask_deps: skip_cask_deps, verbose: verbose,
|
||||
quarantine: quarantine, require_sha: require_sha
|
||||
)
|
||||
rescue => e
|
||||
caught_exceptions << e.exception("#{new_cask.full_name}: #{e}")
|
||||
next
|
||||
end
|
||||
|
||||
return true if caught_exceptions.empty?
|
||||
raise MultipleCaskErrors, caught_exceptions if caught_exceptions.count > 1
|
||||
raise caught_exceptions.first if caught_exceptions.count == 1
|
||||
end
|
||||
|
||||
def self.upgrade_cask(
|
||||
old_cask, new_cask,
|
||||
binaries:, force:, quarantine:, require_sha:, skip_cask_deps:, verbose:
|
||||
)
|
||||
require "cask/installer"
|
||||
|
||||
start_time = Time.now
|
||||
odebug "Started upgrade process for Cask #{old_cask}"
|
||||
old_config = old_cask.config
|
||||
|
||||
old_options = {
|
||||
binaries: binaries,
|
||||
verbose: verbose,
|
||||
force: force,
|
||||
upgrade: true,
|
||||
}.compact
|
||||
|
||||
old_cask_installer =
|
||||
Installer.new(old_cask, **old_options)
|
||||
|
||||
new_cask.config = new_cask.default_config.merge(old_config)
|
||||
|
||||
new_options = {
|
||||
binaries: binaries,
|
||||
verbose: verbose,
|
||||
force: force,
|
||||
skip_cask_deps: skip_cask_deps,
|
||||
require_sha: require_sha,
|
||||
upgrade: true,
|
||||
quarantine: quarantine,
|
||||
}.compact
|
||||
|
||||
new_cask_installer =
|
||||
Installer.new(new_cask, **new_options)
|
||||
|
||||
started_upgrade = false
|
||||
new_artifacts_installed = false
|
||||
|
||||
begin
|
||||
oh1 "Upgrading #{Formatter.identifier(old_cask)}"
|
||||
|
||||
# Start new cask's installation steps
|
||||
new_cask_installer.check_conflicts
|
||||
|
||||
if (caveats = new_cask_installer.caveats)
|
||||
puts caveats
|
||||
end
|
||||
|
||||
new_cask_installer.fetch
|
||||
|
||||
# Move the old cask's artifacts back to staging
|
||||
old_cask_installer.start_upgrade
|
||||
# And flag it so in case of error
|
||||
started_upgrade = true
|
||||
|
||||
# Install the new cask
|
||||
new_cask_installer.stage
|
||||
|
||||
new_cask_installer.install_artifacts
|
||||
new_artifacts_installed = true
|
||||
|
||||
# If successful, wipe the old cask from staging
|
||||
old_cask_installer.finalize_upgrade
|
||||
rescue => e
|
||||
new_cask_installer.uninstall_artifacts if new_artifacts_installed
|
||||
new_cask_installer.purge_versioned_files
|
||||
old_cask_installer.revert_upgrade if started_upgrade
|
||||
raise e
|
||||
end
|
||||
|
||||
end_time = Time.now
|
||||
Homebrew.messages.package_installed(new_cask.token, end_time - start_time)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,5 +1,4 @@
|
||||
# typed: strict
|
||||
# typed: false
|
||||
|
||||
class URL
|
||||
include Kernel
|
||||
|
||||
@ -9,21 +9,21 @@ require "language/python"
|
||||
class Caveats
|
||||
extend Forwardable
|
||||
|
||||
attr_reader :f
|
||||
attr_reader :formula
|
||||
|
||||
def initialize(f)
|
||||
@f = f
|
||||
def initialize(formula)
|
||||
@formula = formula
|
||||
end
|
||||
|
||||
def caveats
|
||||
caveats = []
|
||||
begin
|
||||
build = f.build
|
||||
f.build = Tab.for_formula(f)
|
||||
s = f.caveats.to_s
|
||||
caveats << "#{s.chomp}\n" unless s.empty?
|
||||
build = formula.build
|
||||
formula.build = Tab.for_formula(formula)
|
||||
string = formula.caveats.to_s
|
||||
caveats << "#{string.chomp}\n" unless string.empty?
|
||||
ensure
|
||||
f.build = build
|
||||
formula.build = build
|
||||
end
|
||||
caveats << keg_only_text
|
||||
|
||||
@ -48,49 +48,49 @@ class Caveats
|
||||
delegate [:empty?, :to_s] => :caveats
|
||||
|
||||
def keg_only_text(skip_reason: false)
|
||||
return unless f.keg_only?
|
||||
return unless formula.keg_only?
|
||||
|
||||
s = if skip_reason
|
||||
""
|
||||
else
|
||||
<<~EOS
|
||||
#{f.name} is keg-only, which means it was not symlinked into #{HOMEBREW_PREFIX},
|
||||
because #{f.keg_only_reason.to_s.chomp}.
|
||||
#{formula.name} is keg-only, which means it was not symlinked into #{HOMEBREW_PREFIX},
|
||||
because #{formula.keg_only_reason.to_s.chomp}.
|
||||
EOS
|
||||
end.dup
|
||||
|
||||
if f.bin.directory? || f.sbin.directory?
|
||||
if formula.bin.directory? || formula.sbin.directory?
|
||||
s << <<~EOS
|
||||
|
||||
If you need to have #{f.name} first in your PATH, run:
|
||||
If you need to have #{formula.name} first in your PATH, run:
|
||||
EOS
|
||||
s << " #{Utils::Shell.prepend_path_in_profile(f.opt_bin.to_s)}\n" if f.bin.directory?
|
||||
s << " #{Utils::Shell.prepend_path_in_profile(f.opt_sbin.to_s)}\n" if f.sbin.directory?
|
||||
s << " #{Utils::Shell.prepend_path_in_profile(formula.opt_bin.to_s)}\n" if formula.bin.directory?
|
||||
s << " #{Utils::Shell.prepend_path_in_profile(formula.opt_sbin.to_s)}\n" if formula.sbin.directory?
|
||||
end
|
||||
|
||||
if f.lib.directory? || f.include.directory?
|
||||
if formula.lib.directory? || formula.include.directory?
|
||||
s << <<~EOS
|
||||
|
||||
For compilers to find #{f.name} you may need to set:
|
||||
For compilers to find #{formula.name} you may need to set:
|
||||
EOS
|
||||
|
||||
s << " #{Utils::Shell.export_value("LDFLAGS", "-L#{f.opt_lib}")}\n" if f.lib.directory?
|
||||
s << " #{Utils::Shell.export_value("LDFLAGS", "-L#{formula.opt_lib}")}\n" if formula.lib.directory?
|
||||
|
||||
s << " #{Utils::Shell.export_value("CPPFLAGS", "-I#{f.opt_include}")}\n" if f.include.directory?
|
||||
s << " #{Utils::Shell.export_value("CPPFLAGS", "-I#{formula.opt_include}")}\n" if formula.include.directory?
|
||||
|
||||
if which("pkg-config", ORIGINAL_PATHS) &&
|
||||
((f.lib/"pkgconfig").directory? || (f.share/"pkgconfig").directory?)
|
||||
((formula.lib/"pkgconfig").directory? || (formula.share/"pkgconfig").directory?)
|
||||
s << <<~EOS
|
||||
|
||||
For pkg-config to find #{f.name} you may need to set:
|
||||
For pkg-config to find #{formula.name} you may need to set:
|
||||
EOS
|
||||
|
||||
if (f.lib/"pkgconfig").directory?
|
||||
s << " #{Utils::Shell.export_value("PKG_CONFIG_PATH", "#{f.opt_lib}/pkgconfig")}\n"
|
||||
if (formula.lib/"pkgconfig").directory?
|
||||
s << " #{Utils::Shell.export_value("PKG_CONFIG_PATH", "#{formula.opt_lib}/pkgconfig")}\n"
|
||||
end
|
||||
|
||||
if (f.share/"pkgconfig").directory?
|
||||
s << " #{Utils::Shell.export_value("PKG_CONFIG_PATH", "#{f.opt_share}/pkgconfig")}\n"
|
||||
if (formula.share/"pkgconfig").directory?
|
||||
s << " #{Utils::Shell.export_value("PKG_CONFIG_PATH", "#{formula.opt_share}/pkgconfig")}\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -100,7 +100,7 @@ class Caveats
|
||||
private
|
||||
|
||||
def keg
|
||||
@keg ||= [f.prefix, f.opt_prefix, f.linked_keg].map do |d|
|
||||
@keg ||= [formula.prefix, formula.opt_prefix, formula.linked_keg].map do |d|
|
||||
Keg.new(d.resolved_path)
|
||||
rescue
|
||||
nil
|
||||
@ -119,7 +119,7 @@ class Caveats
|
||||
installed << "completions" if completion_installed
|
||||
installed << "functions" if functions_installed
|
||||
|
||||
root_dir = f.keg_only? ? f.opt_prefix : HOMEBREW_PREFIX
|
||||
root_dir = formula.keg_only? ? formula.opt_prefix : HOMEBREW_PREFIX
|
||||
|
||||
case shell
|
||||
when :bash
|
||||
@ -141,55 +141,55 @@ class Caveats
|
||||
end
|
||||
|
||||
def elisp_caveats
|
||||
return if f.keg_only?
|
||||
return if formula.keg_only?
|
||||
return unless keg
|
||||
return unless keg.elisp_installed?
|
||||
|
||||
<<~EOS
|
||||
Emacs Lisp files have been installed to:
|
||||
#{HOMEBREW_PREFIX}/share/emacs/site-lisp/#{f.name}
|
||||
#{HOMEBREW_PREFIX}/share/emacs/site-lisp/#{formula.name}
|
||||
EOS
|
||||
end
|
||||
|
||||
def service_caveats
|
||||
return if !f.plist && !f.service? && !keg&.plist_installed?
|
||||
return if f.service? && f.service.command.blank?
|
||||
return if !formula.plist && !formula.service? && !keg&.plist_installed?
|
||||
return if formula.service? && formula.service.command.blank?
|
||||
|
||||
s = []
|
||||
|
||||
command = if f.service?
|
||||
f.service.manual_command
|
||||
command = if formula.service?
|
||||
formula.service.manual_command
|
||||
else
|
||||
f.plist_manual
|
||||
formula.plist_manual
|
||||
end
|
||||
|
||||
return <<~EOS if !which("launchctl") && f.plist
|
||||
#{Formatter.warning("Warning:")} #{f.name} provides a launchd plist which can only be used on macOS!
|
||||
return <<~EOS if !which("launchctl") && formula.plist
|
||||
#{Formatter.warning("Warning:")} #{formula.name} provides a launchd plist which can only be used on macOS!
|
||||
You can manually execute the service instead with:
|
||||
#{command}
|
||||
EOS
|
||||
|
||||
# Brew services only works with these two tools
|
||||
return <<~EOS if !which("systemctl") && !which("launchctl") && f.service?
|
||||
#{Formatter.warning("Warning:")} #{f.name} provides a service which can only be used on macOS or systemd!
|
||||
return <<~EOS if !which("systemctl") && !which("launchctl") && formula.service?
|
||||
#{Formatter.warning("Warning:")} #{formula.name} provides a service which can only be used on macOS or systemd!
|
||||
You can manually execute the service instead with:
|
||||
#{command}
|
||||
EOS
|
||||
|
||||
is_running_service = f.service? && quiet_system("ps aux | grep #{f.service.command&.first}")
|
||||
startup = f.service&.requires_root? || f.plist_startup
|
||||
if is_running_service || (f.plist && quiet_system("/bin/launchctl list #{f.plist_name} &>/dev/null"))
|
||||
s << "To restart #{f.full_name} after an upgrade:"
|
||||
s << " #{startup ? "sudo " : ""}brew services restart #{f.full_name}"
|
||||
is_running_service = formula.service? && quiet_system("ps aux | grep #{formula.service.command&.first}")
|
||||
startup = formula.service&.requires_root? || formula.plist_startup
|
||||
if is_running_service || (formula.plist && quiet_system("/bin/launchctl list #{formula.plist_name} &>/dev/null"))
|
||||
s << "To restart #{formula.full_name} after an upgrade:"
|
||||
s << " #{startup ? "sudo " : ""}brew services restart #{formula.full_name}"
|
||||
elsif startup
|
||||
s << "To start #{f.full_name} now and restart at startup:"
|
||||
s << " sudo brew services start #{f.full_name}"
|
||||
s << "To start #{formula.full_name} now and restart at startup:"
|
||||
s << " sudo brew services start #{formula.full_name}"
|
||||
else
|
||||
s << "To start #{f.full_name} now and restart at login:"
|
||||
s << " brew services start #{f.full_name}"
|
||||
s << "To start #{formula.full_name} now and restart at login:"
|
||||
s << " brew services start #{formula.full_name}"
|
||||
end
|
||||
|
||||
if f.plist_manual || f.service?
|
||||
if formula.plist_manual || formula.service?
|
||||
s << "Or, if you don't want/need a background service you can just run:"
|
||||
s << " #{command}"
|
||||
end
|
||||
|
||||
@ -14,8 +14,8 @@ class Cleaner
|
||||
include Context
|
||||
|
||||
# Create a cleaner for the given formula.
|
||||
def initialize(f)
|
||||
@f = f
|
||||
def initialize(formula)
|
||||
@formula = formula
|
||||
end
|
||||
|
||||
# Clean the keg of the formula.
|
||||
@ -24,9 +24,9 @@ class Cleaner
|
||||
|
||||
# Many formulae include 'lib/charset.alias', but it is not strictly needed
|
||||
# and will conflict if more than one formula provides it
|
||||
observe_file_removal @f.lib/"charset.alias"
|
||||
observe_file_removal @formula.lib/"charset.alias"
|
||||
|
||||
[@f.bin, @f.sbin, @f.lib].each { |d| clean_dir(d) if d.exist? }
|
||||
[@formula.bin, @formula.sbin, @formula.lib].each { |dir| clean_dir(dir) if dir.exist? }
|
||||
|
||||
# Get rid of any info 'dir' files, so they don't conflict at the link stage
|
||||
#
|
||||
@ -47,11 +47,11 @@ class Cleaner
|
||||
# [1]: https://github.com/Homebrew/brew/pull/11597
|
||||
# [2]: https://github.com/Homebrew/homebrew-core/issues/100190
|
||||
# [3]: https://github.com/Homebrew/brew/pull/13215
|
||||
Dir.glob(@f.info/"**/dir").each do |f|
|
||||
info_dir_file = Pathname(f)
|
||||
Dir.glob(@formula.info/"**/dir").each do |file|
|
||||
info_dir_file = Pathname(file)
|
||||
next unless info_dir_file.file?
|
||||
next if info_dir_file == @f.info/@f.name/"dir"
|
||||
next if @f.skip_clean?(info_dir_file)
|
||||
next if info_dir_file == @formula.info/@formula.name/"dir"
|
||||
next if @formula.skip_clean?(info_dir_file)
|
||||
|
||||
observe_file_removal info_dir_file
|
||||
end
|
||||
@ -73,8 +73,8 @@ class Cleaner
|
||||
def prune
|
||||
dirs = []
|
||||
symlinks = []
|
||||
@f.prefix.find do |path|
|
||||
if path == @f.libexec || @f.skip_clean?(path)
|
||||
@formula.prefix.find do |path|
|
||||
if path == @formula.libexec || @formula.skip_clean?(path)
|
||||
Find.prune
|
||||
elsif path.symlink?
|
||||
symlinks << path
|
||||
@ -121,7 +121,7 @@ class Cleaner
|
||||
directory.find do |path|
|
||||
path.extend(ObserverPathnameExtension)
|
||||
|
||||
Find.prune if @f.skip_clean? path
|
||||
Find.prune if @formula.skip_clean? path
|
||||
|
||||
next if path.directory?
|
||||
|
||||
@ -149,14 +149,14 @@ class Cleaner
|
||||
require "language/perl"
|
||||
require "utils/shebang"
|
||||
|
||||
basepath = @f.prefix.realpath
|
||||
basepath = @formula.prefix.realpath
|
||||
basepath.find do |path|
|
||||
Find.prune if @f.skip_clean? path
|
||||
Find.prune if @formula.skip_clean? path
|
||||
|
||||
next if path.directory? || path.symlink?
|
||||
|
||||
begin
|
||||
Utils::Shebang.rewrite_shebang Language::Perl::Shebang.detected_perl_shebang(@f), path
|
||||
Utils::Shebang.rewrite_shebang Language::Perl::Shebang.detected_perl_shebang(@formula), path
|
||||
rescue ShebangDetectionError
|
||||
break
|
||||
end
|
||||
|
||||
@ -155,21 +155,21 @@ module Homebrew
|
||||
@cleaned_up_paths = Set.new
|
||||
end
|
||||
|
||||
def self.install_formula_clean!(f, dry_run: false)
|
||||
def self.install_formula_clean!(formula, dry_run: false)
|
||||
return if Homebrew::EnvConfig.no_install_cleanup?
|
||||
return unless f.latest_version_installed?
|
||||
return if skip_clean_formula?(f)
|
||||
return unless formula.latest_version_installed?
|
||||
return if skip_clean_formula?(formula)
|
||||
|
||||
if dry_run
|
||||
ohai "Would run `brew cleanup #{f}`"
|
||||
ohai "Would run `brew cleanup #{formula}`"
|
||||
else
|
||||
ohai "Running `brew cleanup #{f}`..."
|
||||
ohai "Running `brew cleanup #{formula}`..."
|
||||
end
|
||||
|
||||
puts_no_install_cleanup_disable_message_if_not_already!
|
||||
return if dry_run
|
||||
|
||||
Cleanup.new.cleanup_formula(f)
|
||||
Cleanup.new.cleanup_formula(formula)
|
||||
end
|
||||
|
||||
def self.puts_no_install_cleanup_disable_message
|
||||
@ -187,11 +187,11 @@ module Homebrew
|
||||
@puts_no_install_cleanup_disable_message_if_not_already = true
|
||||
end
|
||||
|
||||
def self.skip_clean_formula?(f)
|
||||
def self.skip_clean_formula?(formula)
|
||||
return false if Homebrew::EnvConfig.no_cleanup_formulae.blank?
|
||||
|
||||
@skip_clean_formulae ||= Homebrew::EnvConfig.no_cleanup_formulae.split(",")
|
||||
@skip_clean_formulae.include?(f.name) || (@skip_clean_formulae & f.aliases).present?
|
||||
@skip_clean_formulae.include?(formula.name) || (@skip_clean_formulae & formula.aliases).present?
|
||||
end
|
||||
|
||||
def self.periodic_clean_due?
|
||||
|
||||
@ -249,11 +249,11 @@ module Homebrew
|
||||
"digraph {\n#{dot_code}\n}"
|
||||
end
|
||||
|
||||
def self.graph_deps(f, dep_graph:, recursive:, args:)
|
||||
return if dep_graph.key?(f)
|
||||
def self.graph_deps(formula, dep_graph:, recursive:, args:)
|
||||
return if dep_graph.key?(formula)
|
||||
|
||||
dependables = dependables(f, args: args)
|
||||
dep_graph[f] = dependables
|
||||
dependables = dependables(formula, args: args)
|
||||
dep_graph[formula] = dependables
|
||||
return unless recursive
|
||||
|
||||
dependables.each do |dep|
|
||||
@ -274,19 +274,19 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def self.dependables(f, args:)
|
||||
def self.dependables(formula, args:)
|
||||
includes, ignores = args_includes_ignores(args)
|
||||
deps = @use_runtime_dependencies ? f.runtime_dependencies : f.deps
|
||||
deps = @use_runtime_dependencies ? formula.runtime_dependencies : formula.deps
|
||||
deps = reject_ignores(deps, ignores, includes)
|
||||
reqs = reject_ignores(f.requirements, ignores, includes) if args.include_requirements?
|
||||
reqs = reject_ignores(formula.requirements, ignores, includes) if args.include_requirements?
|
||||
reqs ||= []
|
||||
reqs + deps
|
||||
end
|
||||
|
||||
def self.recursive_deps_tree(f, dep_stack:, prefix:, recursive:, args:)
|
||||
dependables = dependables(f, args: args)
|
||||
def self.recursive_deps_tree(formula, dep_stack:, prefix:, recursive:, args:)
|
||||
dependables = dependables(formula, args: args)
|
||||
max = dependables.length - 1
|
||||
dep_stack.push f.name
|
||||
dep_stack.push formula.name
|
||||
dependables.each_with_index do |dep, i|
|
||||
tree_lines = if i == max
|
||||
"└──"
|
||||
|
||||
@ -138,10 +138,10 @@ module Homebrew
|
||||
opoo "Resource #{resource.name} reports different sha256: #{e.expected}"
|
||||
end
|
||||
|
||||
def self.fetch_formula(f, args:)
|
||||
fetch_fetchable f, args: args
|
||||
def self.fetch_formula(formula, args:)
|
||||
fetch_fetchable formula, args: args
|
||||
rescue ChecksumMismatchError => e
|
||||
retry if retry_fetch?(f, args: args)
|
||||
retry if retry_fetch?(formula, args: args)
|
||||
opoo "Formula reports different sha256: #{e.expected}"
|
||||
end
|
||||
|
||||
@ -159,18 +159,18 @@ module Homebrew
|
||||
Homebrew.failed = true
|
||||
end
|
||||
|
||||
def self.retry_fetch?(f, args:)
|
||||
def self.retry_fetch?(formula, args:)
|
||||
@fetch_tries ||= Hash.new { |h, k| h[k] = 1 }
|
||||
if args.retry? && (@fetch_tries[f] < FETCH_MAX_TRIES)
|
||||
wait = 2 ** @fetch_tries[f]
|
||||
remaining = FETCH_MAX_TRIES - @fetch_tries[f]
|
||||
if args.retry? && (@fetch_tries[formula] < FETCH_MAX_TRIES)
|
||||
wait = 2 ** @fetch_tries[formula]
|
||||
remaining = FETCH_MAX_TRIES - @fetch_tries[formula]
|
||||
what = Utils.pluralize("tr", remaining, plural: "ies", singular: "y")
|
||||
|
||||
ohai "Retrying download in #{wait}s... (#{remaining} #{what} left)"
|
||||
sleep wait
|
||||
|
||||
f.clear_cache
|
||||
@fetch_tries[f] += 1
|
||||
formula.clear_cache
|
||||
@fetch_tries[formula] += 1
|
||||
true
|
||||
else
|
||||
Homebrew.failed = true
|
||||
@ -178,15 +178,15 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def self.fetch_fetchable(f, args:)
|
||||
f.clear_cache if args.force?
|
||||
def self.fetch_fetchable(formula, args:)
|
||||
formula.clear_cache if args.force?
|
||||
|
||||
already_fetched = f.cached_download.exist?
|
||||
already_fetched = formula.cached_download.exist?
|
||||
|
||||
begin
|
||||
download = f.fetch(verify_download_integrity: false)
|
||||
download = formula.fetch(verify_download_integrity: false)
|
||||
rescue DownloadError
|
||||
retry if retry_fetch?(f, args: args)
|
||||
retry if retry_fetch?(formula, args: args)
|
||||
raise
|
||||
end
|
||||
|
||||
@ -195,6 +195,6 @@ module Homebrew
|
||||
puts "Downloaded to: #{download}" unless already_fetched
|
||||
puts "SHA256: #{download.sha256}"
|
||||
|
||||
f.verify_download_integrity(download)
|
||||
formula.verify_download_integrity(download)
|
||||
end
|
||||
end
|
||||
|
||||
@ -35,22 +35,24 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def gistify_logs(f, args:)
|
||||
files = load_logs(f.logs)
|
||||
build_time = f.logs.ctime
|
||||
def gistify_logs(formula, args:)
|
||||
files = load_logs(formula.logs)
|
||||
build_time = formula.logs.ctime
|
||||
timestamp = build_time.strftime("%Y-%m-%d_%H-%M-%S")
|
||||
|
||||
s = StringIO.new
|
||||
SystemConfig.dump_verbose_config s
|
||||
# Dummy summary file, asciibetically first, to control display title of gist
|
||||
files["# #{f.name} - #{timestamp}.txt"] = { content: brief_build_info(f, with_hostname: args.with_hostname?) }
|
||||
files["# #{formula.name} - #{timestamp}.txt"] = {
|
||||
content: brief_build_info(formula, with_hostname: args.with_hostname?),
|
||||
}
|
||||
files["00.config.out"] = { content: s.string }
|
||||
files["00.doctor.out"] = { content: Utils.popen_read("#{HOMEBREW_PREFIX}/bin/brew", "doctor", err: :out) }
|
||||
unless f.core_formula?
|
||||
unless formula.core_formula?
|
||||
tap = <<~EOS
|
||||
Formula: #{f.name}
|
||||
Tap: #{f.tap}
|
||||
Path: #{f.path}
|
||||
Formula: #{formula.name}
|
||||
Tap: #{formula.tap}
|
||||
Path: #{formula.path}
|
||||
EOS
|
||||
files["00.tap.out"] = { content: tap }
|
||||
end
|
||||
@ -58,10 +60,10 @@ module Homebrew
|
||||
odie "`brew gist-logs` requires HOMEBREW_GITHUB_API_TOKEN to be set!" if GitHub::API.credentials_type == :none
|
||||
|
||||
# Description formatted to work well as page title when viewing gist
|
||||
descr = if f.core_formula?
|
||||
"#{f.name} on #{OS_VERSION} - Homebrew build logs"
|
||||
descr = if formula.core_formula?
|
||||
"#{formula.name} on #{OS_VERSION} - Homebrew build logs"
|
||||
else
|
||||
"#{f.name} (#{f.full_name}) on #{OS_VERSION} - Homebrew build logs"
|
||||
"#{formula.name} (#{formula.full_name}) on #{OS_VERSION} - Homebrew build logs"
|
||||
end
|
||||
|
||||
begin
|
||||
@ -73,22 +75,24 @@ module Homebrew
|
||||
EOS
|
||||
end
|
||||
|
||||
url = GitHub.create_issue(f.tap, "#{f.name} failed to build on #{MacOS.full_version}", url) if args.new_issue?
|
||||
if args.new_issue?
|
||||
url = GitHub.create_issue(formula.tap, "#{formula.name} failed to build on #{MacOS.full_version}", url)
|
||||
end
|
||||
|
||||
puts url if url
|
||||
end
|
||||
|
||||
def brief_build_info(f, with_hostname:)
|
||||
build_time_str = f.logs.ctime.strftime("%Y-%m-%d %H:%M:%S")
|
||||
s = +<<~EOS
|
||||
Homebrew build logs for #{f.full_name} on #{OS_VERSION}
|
||||
def brief_build_info(formula, with_hostname:)
|
||||
build_time_string = formula.logs.ctime.strftime("%Y-%m-%d %H:%M:%S")
|
||||
string = +<<~EOS
|
||||
Homebrew build logs for #{formula.full_name} on #{OS_VERSION}
|
||||
EOS
|
||||
if with_hostname
|
||||
hostname = Socket.gethostname
|
||||
s << "Host: #{hostname}\n"
|
||||
string << "Host: #{hostname}\n"
|
||||
end
|
||||
s << "Build date: #{build_time_str}\n"
|
||||
s.freeze
|
||||
string << "Build date: #{build_time_string}\n"
|
||||
string.freeze
|
||||
end
|
||||
|
||||
# Causes some terminals to display secure password entry indicators.
|
||||
|
||||
@ -247,40 +247,40 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def github_info(f)
|
||||
return f.path if f.tap.blank? || f.tap.remote.blank?
|
||||
def github_info(formula)
|
||||
return formula.path if formula.tap.blank? || formula.tap.remote.blank?
|
||||
|
||||
path = case f
|
||||
path = case formula
|
||||
when Formula
|
||||
f.path.relative_path_from(f.tap.path)
|
||||
formula.path.relative_path_from(formula.tap.path)
|
||||
when Cask::Cask
|
||||
return "#{f.tap.default_remote}/blob/HEAD/Casks/#{f.token}.rb" if f.sourcefile_path.blank?
|
||||
return "#{formula.tap.default_remote}/blob/HEAD/Casks/#{formula.token}.rb" if formula.sourcefile_path.blank?
|
||||
|
||||
f.sourcefile_path.relative_path_from(f.tap.path)
|
||||
formula.sourcefile_path.relative_path_from(formula.tap.path)
|
||||
end
|
||||
github_remote_path(f.tap.remote, path)
|
||||
github_remote_path(formula.tap.remote, path)
|
||||
end
|
||||
|
||||
def info_formula(f, args:)
|
||||
def info_formula(formula, args:)
|
||||
specs = []
|
||||
|
||||
if (stable = f.stable)
|
||||
s = "stable #{stable.version}"
|
||||
s += " (bottled)" if stable.bottled? && f.pour_bottle?
|
||||
specs << s
|
||||
if (stable = formula.stable)
|
||||
string = "stable #{stable.version}"
|
||||
string += " (bottled)" if stable.bottled? && formula.pour_bottle?
|
||||
specs << string
|
||||
end
|
||||
|
||||
specs << "HEAD" if f.head
|
||||
specs << "HEAD" if formula.head
|
||||
|
||||
attrs = []
|
||||
attrs << "pinned at #{f.pinned_version}" if f.pinned?
|
||||
attrs << "keg-only" if f.keg_only?
|
||||
attrs << "pinned at #{formula.pinned_version}" if formula.pinned?
|
||||
attrs << "keg-only" if formula.keg_only?
|
||||
|
||||
puts "#{oh1_title(f.full_name)}: #{specs * ", "}#{" [#{attrs * ", "}]" unless attrs.empty?}"
|
||||
puts f.desc if f.desc
|
||||
puts Formatter.url(f.homepage) if f.homepage
|
||||
puts "#{oh1_title(formula.full_name)}: #{specs * ", "}#{" [#{attrs * ", "}]" unless attrs.empty?}"
|
||||
puts formula.desc if formula.desc
|
||||
puts Formatter.url(formula.homepage) if formula.homepage
|
||||
|
||||
deprecate_disable_type, deprecate_disable_reason = DeprecateDisable.deprecate_disable_info f
|
||||
deprecate_disable_type, deprecate_disable_reason = DeprecateDisable.deprecate_disable_info formula
|
||||
if deprecate_disable_type.present?
|
||||
if deprecate_disable_reason.present?
|
||||
puts "#{deprecate_disable_type.capitalize} because it #{deprecate_disable_reason}!"
|
||||
@ -289,9 +289,9 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
conflicts = f.conflicts.map do |c|
|
||||
reason = " (because #{c.reason})" if c.reason
|
||||
"#{c.name}#{reason}"
|
||||
conflicts = formula.conflicts.map do |conflict|
|
||||
reason = " (because #{conflict.reason})" if conflict.reason
|
||||
"#{conflict.name}#{reason}"
|
||||
end.sort!
|
||||
unless conflicts.empty?
|
||||
puts <<~EOS
|
||||
@ -300,7 +300,7 @@ module Homebrew
|
||||
EOS
|
||||
end
|
||||
|
||||
kegs = f.installed_kegs
|
||||
kegs = formula.installed_kegs
|
||||
heads, versioned = kegs.partition { |k| k.version.head? }
|
||||
kegs = [
|
||||
*heads.sort_by { |k| -Tab.for_keg(k).time.to_i },
|
||||
@ -316,37 +316,37 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
puts "From: #{Formatter.url(github_info(f))}"
|
||||
puts "From: #{Formatter.url(github_info(formula))}"
|
||||
|
||||
puts "License: #{SPDX.license_expression_to_string f.license}" if f.license.present?
|
||||
puts "License: #{SPDX.license_expression_to_string formula.license}" if formula.license.present?
|
||||
|
||||
unless f.deps.empty?
|
||||
unless formula.deps.empty?
|
||||
ohai "Dependencies"
|
||||
%w[build required recommended optional].map do |type|
|
||||
deps = f.deps.send(type).uniq
|
||||
deps = formula.deps.send(type).uniq
|
||||
puts "#{type.capitalize}: #{decorate_dependencies deps}" unless deps.empty?
|
||||
end
|
||||
end
|
||||
|
||||
unless f.requirements.to_a.empty?
|
||||
unless formula.requirements.to_a.empty?
|
||||
ohai "Requirements"
|
||||
%w[build required recommended optional].map do |type|
|
||||
reqs = f.requirements.select(&:"#{type}?")
|
||||
reqs = formula.requirements.select(&:"#{type}?")
|
||||
next if reqs.to_a.empty?
|
||||
|
||||
puts "#{type.capitalize}: #{decorate_requirements(reqs)}"
|
||||
end
|
||||
end
|
||||
|
||||
if !f.options.empty? || f.head
|
||||
if !formula.options.empty? || formula.head
|
||||
ohai "Options"
|
||||
Options.dump_for_formula f
|
||||
Options.dump_for_formula formula
|
||||
end
|
||||
|
||||
caveats = Caveats.new(f)
|
||||
caveats = Caveats.new(formula)
|
||||
ohai "Caveats", caveats.to_s unless caveats.empty?
|
||||
|
||||
Utils::Analytics.formula_output(f, args: args)
|
||||
Utils::Analytics.formula_output(formula, args: args)
|
||||
end
|
||||
|
||||
def decorate_dependencies(dependencies)
|
||||
|
||||
@ -7,6 +7,7 @@ require "install"
|
||||
require "upgrade"
|
||||
require "cask/cmd"
|
||||
require "cask/utils"
|
||||
require "cask/upgrade"
|
||||
require "cask/macos"
|
||||
require "api"
|
||||
|
||||
@ -87,8 +88,19 @@ module Homebrew
|
||||
description: "Treat all named arguments as casks. If no named arguments " \
|
||||
"are specified, upgrade only outdated casks.",
|
||||
}],
|
||||
[:switch, "--skip-cask-deps", {
|
||||
description: "Skip installing cask dependencies.",
|
||||
}],
|
||||
[:switch, "-g", "--greedy", {
|
||||
description: "Also include casks with `auto_updates true` or `version :latest`.",
|
||||
}],
|
||||
[:switch, "--greedy-latest", {
|
||||
description: "Also include casks with `version :latest`.",
|
||||
}],
|
||||
[:switch, "--greedy-auto-updates", {
|
||||
description: "Also include casks with `auto_updates true`.",
|
||||
}],
|
||||
*Cask::Cmd::AbstractCommand::OPTIONS.map(&:dup),
|
||||
*Cask::Cmd::Upgrade::OPTIONS.map(&:dup),
|
||||
].each do |args|
|
||||
options = args.pop
|
||||
send(*args, **options)
|
||||
@ -230,7 +242,7 @@ module Homebrew
|
||||
def upgrade_outdated_casks(casks, args:)
|
||||
return false if args.formula?
|
||||
|
||||
Cask::Cmd::Upgrade.upgrade_casks(
|
||||
Cask::Upgrade.upgrade_casks(
|
||||
*casks,
|
||||
force: args.force?,
|
||||
greedy: args.greedy?,
|
||||
|
||||
@ -98,22 +98,22 @@ module Debrew
|
||||
end
|
||||
end
|
||||
|
||||
def self.debug(e)
|
||||
raise(e) if !active? || !debugged_exceptions.add?(e) || !try_lock
|
||||
def self.debug(exception)
|
||||
raise(exception) if !active? || !debugged_exceptions.add?(exception) || !try_lock
|
||||
|
||||
begin
|
||||
puts e.backtrace.first.to_s
|
||||
puts Formatter.error(e, label: e.class.name)
|
||||
puts exception.backtrace.first.to_s
|
||||
puts Formatter.error(exception, label: exception.class.name)
|
||||
|
||||
loop do
|
||||
Menu.choose do |menu|
|
||||
menu.prompt = "Choose an action: "
|
||||
|
||||
menu.choice(:raise) { raise(e) }
|
||||
menu.choice(:ignore) { return :ignore } if e.is_a?(Ignorable::ExceptionMixin)
|
||||
menu.choice(:backtrace) { puts e.backtrace }
|
||||
menu.choice(:ignore) { return :ignore } if exception.is_a?(Ignorable::ExceptionMixin)
|
||||
menu.choice(:backtrace) { puts exception.backtrace }
|
||||
|
||||
if e.is_a?(Ignorable::ExceptionMixin)
|
||||
if exception.is_a?(Ignorable::ExceptionMixin)
|
||||
menu.choice(:irb) do
|
||||
puts "When you exit this IRB session, execution will continue."
|
||||
set_trace_func proc { |event, _, _, id, binding, klass|
|
||||
|
||||
@ -82,8 +82,6 @@ class DescriptionCacheStore < CacheStore
|
||||
end
|
||||
alias delete_from_cask_tokens! delete_from_formula_names!
|
||||
|
||||
private
|
||||
|
||||
# `select` from the underlying database.
|
||||
def select(&block)
|
||||
database.select(&block)
|
||||
|
||||
@ -102,8 +102,8 @@ module Homebrew
|
||||
return merge(args: args)
|
||||
end
|
||||
|
||||
args.named.to_resolved_formulae(uniq: false).each do |f|
|
||||
bottle_formula f, args: args
|
||||
args.named.to_resolved_formulae(uniq: false).each do |formula|
|
||||
bottle_formula formula, args: args
|
||||
end
|
||||
end
|
||||
|
||||
@ -261,13 +261,13 @@ module Homebrew
|
||||
["#{gnu_tar.opt_bin}/gtar", gnutar_args].freeze
|
||||
end
|
||||
|
||||
def formula_ignores(f)
|
||||
def formula_ignores(formula)
|
||||
ignores = []
|
||||
cellar_regex = Regexp.escape(HOMEBREW_CELLAR)
|
||||
prefix_regex = Regexp.escape(HOMEBREW_PREFIX)
|
||||
|
||||
# Ignore matches to go keg, because all go binaries are statically linked.
|
||||
any_go_deps = f.deps.any? do |dep|
|
||||
any_go_deps = formula.deps.any? do |dep|
|
||||
dep.name =~ Version.formula_optionally_versioned_regex(:go)
|
||||
end
|
||||
if any_go_deps
|
||||
@ -277,7 +277,7 @@ module Homebrew
|
||||
|
||||
# TODO: Refactor and move to extend/os
|
||||
# rubocop:disable Homebrew/MoveToExtendOS
|
||||
ignores << case f.name
|
||||
ignores << case formula.name
|
||||
# On Linux, GCC installation can be moved so long as the whole directory tree is moved together:
|
||||
# https://gcc-help.gcc.gnu.narkive.com/GnwuCA7l/moving-gcc-from-the-installation-path-is-it-allowed.
|
||||
when Version.formula_optionally_versioned_regex(:gcc)
|
||||
@ -291,25 +291,29 @@ module Homebrew
|
||||
ignores.compact
|
||||
end
|
||||
|
||||
def bottle_formula(f, args:)
|
||||
local_bottle_json = args.json? && f.local_bottle_path.present?
|
||||
def bottle_formula(formula, args:)
|
||||
local_bottle_json = args.json? && formula.local_bottle_path.present?
|
||||
|
||||
unless local_bottle_json
|
||||
return ofail "Formula not installed or up-to-date: #{f.full_name}" unless f.latest_version_installed?
|
||||
return ofail "Formula was not installed with --build-bottle: #{f.full_name}" unless Utils::Bottles.built_as? f
|
||||
unless formula.latest_version_installed?
|
||||
return ofail "Formula not installed or up-to-date: #{formula.full_name}"
|
||||
end
|
||||
unless Utils::Bottles.built_as? formula
|
||||
return ofail "Formula was not installed with --build-bottle: #{formula.full_name}"
|
||||
end
|
||||
end
|
||||
|
||||
tap = f.tap
|
||||
tap = formula.tap
|
||||
if tap.nil?
|
||||
return ofail "Formula not from core or any installed taps: #{f.full_name}" unless args.force_core_tap?
|
||||
return ofail "Formula not from core or any installed taps: #{formula.full_name}" unless args.force_core_tap?
|
||||
|
||||
tap = CoreTap.instance
|
||||
end
|
||||
|
||||
return ofail "Formula has no stable version: #{f.full_name}" unless f.stable
|
||||
return ofail "Formula has no stable version: #{formula.full_name}" unless formula.stable
|
||||
|
||||
bottle_tag, rebuild = if local_bottle_json
|
||||
_, tag_string, rebuild_string = Utils::Bottles.extname_tag_rebuild(f.local_bottle_path.to_s)
|
||||
_, tag_string, rebuild_string = Utils::Bottles.extname_tag_rebuild(formula.local_bottle_path.to_s)
|
||||
[tag_string.to_sym, rebuild_string.to_i]
|
||||
end
|
||||
|
||||
@ -322,19 +326,19 @@ module Homebrew
|
||||
rebuild ||= if args.no_rebuild? || !tap
|
||||
0
|
||||
elsif args.keep_old?
|
||||
f.bottle_specification.rebuild
|
||||
formula.bottle_specification.rebuild
|
||||
else
|
||||
ohai "Determining #{f.full_name} bottle rebuild..."
|
||||
FormulaVersions.new(f).formula_at_revision("origin/HEAD") do |upstream_f|
|
||||
if f.pkg_version == upstream_f.pkg_version
|
||||
upstream_f.bottle_specification.rebuild + 1
|
||||
ohai "Determining #{formula.full_name} bottle rebuild..."
|
||||
FormulaVersions.new(formula).formula_at_revision("origin/HEAD") do |upstream_formula|
|
||||
if formula.pkg_version == upstream_formula.pkg_version
|
||||
upstream_formula.bottle_specification.rebuild + 1
|
||||
else
|
||||
0
|
||||
end
|
||||
end || 0
|
||||
end
|
||||
|
||||
filename = Bottle::Filename.create(f, bottle_tag.to_sym, rebuild)
|
||||
filename = Bottle::Filename.create(formula, bottle_tag.to_sym, rebuild)
|
||||
local_filename = filename.to_s
|
||||
bottle_path = Pathname.pwd/filename
|
||||
|
||||
@ -354,7 +358,7 @@ module Homebrew
|
||||
cellar = HOMEBREW_CELLAR.to_s
|
||||
|
||||
if local_bottle_json
|
||||
bottle_path = f.local_bottle_path
|
||||
bottle_path = formula.local_bottle_path
|
||||
local_filename = bottle_path.basename.to_s
|
||||
|
||||
tab_path = Utils::Bottles.receipt_path(bottle_path)
|
||||
@ -363,7 +367,7 @@ module Homebrew
|
||||
tab_json = Utils::Bottles.file_from_bottle(bottle_path, tab_path)
|
||||
tab = Tab.from_file_content(tab_json, tab_path)
|
||||
|
||||
tag_spec = Formula[f.name].bottle_specification.tag_specification_for(bottle_tag, no_older_versions: true)
|
||||
tag_spec = Formula[formula.name].bottle_specification.tag_specification_for(bottle_tag, no_older_versions: true)
|
||||
relocatable = [:any, :any_skip_relocation].include?(tag_spec.cellar)
|
||||
skip_relocation = tag_spec.cellar == :any_skip_relocation
|
||||
|
||||
@ -373,12 +377,12 @@ module Homebrew
|
||||
tar_filename = filename.to_s.sub(/.gz$/, "")
|
||||
tar_path = Pathname.pwd/tar_filename
|
||||
|
||||
keg = Keg.new(f.prefix)
|
||||
keg = Keg.new(formula.prefix)
|
||||
end
|
||||
|
||||
ohai "Bottling #{local_filename}..."
|
||||
|
||||
formula_and_runtime_deps_names = [f.name] + f.runtime_dependencies.map(&:name)
|
||||
formula_and_runtime_deps_names = [formula.name] + formula.runtime_dependencies.map(&:name)
|
||||
|
||||
# this will be nil when using a local bottle
|
||||
keg&.lock do
|
||||
@ -417,10 +421,10 @@ module Homebrew
|
||||
tar, tar_args = setup_tar_and_args!(args, tar_mtime)
|
||||
safe_system tar, "--create", "--numeric-owner",
|
||||
*tar_args,
|
||||
"--file", tar_path, "#{f.name}/#{f.pkg_version}"
|
||||
"--file", tar_path, "#{formula.name}/#{formula.pkg_version}"
|
||||
sudo_purge
|
||||
# Set filename as it affects the tarball checksum.
|
||||
relocatable_tar_path = "#{f}-bottle.tar"
|
||||
relocatable_tar_path = "#{formula}-bottle.tar"
|
||||
mv tar_path, relocatable_tar_path
|
||||
# Use gzip, faster to compress than bzip2, faster to uncompress than bzip2
|
||||
# or an uncompressed tarball (and more bandwidth friendly).
|
||||
@ -444,7 +448,7 @@ module Homebrew
|
||||
ignores = [%r{/include/|\.(c|cc|cpp|h|hpp)$}]
|
||||
|
||||
# Add additional workarounds to ignore
|
||||
ignores += formula_ignores(f)
|
||||
ignores += formula_ignores(formula)
|
||||
|
||||
repository_reference = if HOMEBREW_PREFIX == HOMEBREW_REPOSITORY
|
||||
HOMEBREW_LIBRARY
|
||||
@ -500,7 +504,7 @@ module Homebrew
|
||||
sha256 = bottle_path.sha256
|
||||
bottle.sha256 cellar: bottle_cellar, bottle_tag.to_sym => sha256
|
||||
|
||||
old_spec = f.bottle_specification
|
||||
old_spec = formula.bottle_specification
|
||||
if args.keep_old? && !old_spec.checksums.empty?
|
||||
mismatches = [:root_url, :rebuild].reject do |key|
|
||||
old_spec.send(key) == bottle.send(key)
|
||||
@ -529,21 +533,21 @@ module Homebrew
|
||||
return unless args.json?
|
||||
|
||||
json = {
|
||||
f.full_name => {
|
||||
formula.full_name => {
|
||||
"formula" => {
|
||||
"name" => f.name,
|
||||
"pkg_version" => f.pkg_version.to_s,
|
||||
"path" => f.path.to_s.delete_prefix("#{HOMEBREW_REPOSITORY}/"),
|
||||
"tap_git_path" => f.path.to_s.delete_prefix("#{tap_path}/"),
|
||||
"name" => formula.name,
|
||||
"pkg_version" => formula.pkg_version.to_s,
|
||||
"path" => formula.path.to_s.delete_prefix("#{HOMEBREW_REPOSITORY}/"),
|
||||
"tap_git_path" => formula.path.to_s.delete_prefix("#{tap_path}/"),
|
||||
"tap_git_revision" => tap_git_revision,
|
||||
"tap_git_remote" => tap_git_remote,
|
||||
# descriptions can contain emoji. sigh.
|
||||
"desc" => f.desc.to_s.encode(
|
||||
"desc" => formula.desc.to_s.encode(
|
||||
Encoding.find("ASCII"),
|
||||
invalid: :replace, undef: :replace, replace: "",
|
||||
).strip,
|
||||
"license" => SPDX.license_expression_to_string(f.license),
|
||||
"homepage" => f.homepage,
|
||||
"license" => SPDX.license_expression_to_string(formula.license),
|
||||
"homepage" => formula.homepage,
|
||||
},
|
||||
"bottle" => {
|
||||
"root_url" => bottle.root_url,
|
||||
@ -603,8 +607,8 @@ module Homebrew
|
||||
|
||||
old_bottle_spec = formula.bottle_specification
|
||||
old_pkg_version = formula.pkg_version
|
||||
FormulaVersions.new(formula).formula_at_revision("origin/HEAD") do |upstream_f|
|
||||
old_pkg_version = upstream_f.pkg_version
|
||||
FormulaVersions.new(formula).formula_at_revision("origin/HEAD") do |upstream_formula|
|
||||
old_pkg_version = upstream_formula.pkg_version
|
||||
end
|
||||
|
||||
old_bottle_spec_matches = old_bottle_spec &&
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "formula"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "timeout"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "formulary"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cli/parser"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cli/parser"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cli/parser"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cli/parser"
|
||||
|
||||
@ -114,11 +114,11 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def retry_test?(f, args:)
|
||||
def retry_test?(formula, args:)
|
||||
@test_failed ||= Set.new
|
||||
if args.retry? && @test_failed.add?(f)
|
||||
oh1 "Testing #{f.full_name} (again)"
|
||||
f.clear_cache
|
||||
if args.retry? && @test_failed.add?(formula)
|
||||
oh1 "Testing #{formula.full_name} (again)"
|
||||
formula.clear_cache
|
||||
ENV["RUST_BACKTRACE"] = "full"
|
||||
true
|
||||
else
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cli/parser"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "keg"
|
||||
@ -31,7 +31,7 @@ module Homebrew
|
||||
|
||||
def self.checks(type, fatal: true)
|
||||
@checks ||= Checks.new
|
||||
failed = false
|
||||
failed = T.let(false, T::Boolean)
|
||||
@checks.public_send(type).each do |check|
|
||||
out = @checks.public_send(check)
|
||||
next if out.nil?
|
||||
@ -64,6 +64,7 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(list: T::Array[String], string: String).returns(String) }
|
||||
def inject_file_list(list, string)
|
||||
list.reduce(string.dup) { |acc, elem| acc << " #{elem}\n" }
|
||||
.freeze
|
||||
@ -569,8 +570,8 @@ module Homebrew
|
||||
EOS
|
||||
end
|
||||
|
||||
def __check_linked_brew(f)
|
||||
f.installed_prefixes.each do |prefix|
|
||||
def __check_linked_brew(formula)
|
||||
formula.installed_prefixes.each do |prefix|
|
||||
prefix.find do |src|
|
||||
next if src == prefix
|
||||
|
||||
@ -642,10 +643,11 @@ module Homebrew
|
||||
EOS
|
||||
end
|
||||
|
||||
sig { returns(T.nilable(String)) }
|
||||
def check_git_status
|
||||
return unless Utils::Git.available?
|
||||
|
||||
message = nil
|
||||
message = T.let(nil, T.nilable(String))
|
||||
|
||||
repos = {
|
||||
"Homebrew/brew" => HOMEBREW_REPOSITORY,
|
||||
|
||||
@ -162,33 +162,33 @@ module Kernel
|
||||
odeprecated(method, replacement, options)
|
||||
end
|
||||
|
||||
def pretty_installed(f)
|
||||
def pretty_installed(formula)
|
||||
if !$stdout.tty?
|
||||
f.to_s
|
||||
formula.to_s
|
||||
elsif Homebrew::EnvConfig.no_emoji?
|
||||
Formatter.success("#{Tty.bold}#{f} (installed)#{Tty.reset}")
|
||||
Formatter.success("#{Tty.bold}#{formula} (installed)#{Tty.reset}")
|
||||
else
|
||||
"#{Tty.bold}#{f} #{Formatter.success("✔")}#{Tty.reset}"
|
||||
"#{Tty.bold}#{formula} #{Formatter.success("✔")}#{Tty.reset}"
|
||||
end
|
||||
end
|
||||
|
||||
def pretty_outdated(f)
|
||||
def pretty_outdated(formula)
|
||||
if !$stdout.tty?
|
||||
f.to_s
|
||||
formula.to_s
|
||||
elsif Homebrew::EnvConfig.no_emoji?
|
||||
Formatter.error("#{Tty.bold}#{f} (outdated)#{Tty.reset}")
|
||||
Formatter.error("#{Tty.bold}#{formula} (outdated)#{Tty.reset}")
|
||||
else
|
||||
"#{Tty.bold}#{f} #{Formatter.warning("⚠")}#{Tty.reset}"
|
||||
"#{Tty.bold}#{formula} #{Formatter.warning("⚠")}#{Tty.reset}"
|
||||
end
|
||||
end
|
||||
|
||||
def pretty_uninstalled(f)
|
||||
def pretty_uninstalled(formula)
|
||||
if !$stdout.tty?
|
||||
f.to_s
|
||||
formula.to_s
|
||||
elsif Homebrew::EnvConfig.no_emoji?
|
||||
Formatter.error("#{Tty.bold}#{f} (uninstalled)#{Tty.reset}")
|
||||
Formatter.error("#{Tty.bold}#{formula} (uninstalled)#{Tty.reset}")
|
||||
else
|
||||
"#{Tty.bold}#{f} #{Formatter.error("✘")}#{Tty.reset}"
|
||||
"#{Tty.bold}#{formula} #{Formatter.error("✘")}#{Tty.reset}"
|
||||
end
|
||||
end
|
||||
|
||||
@ -209,10 +209,10 @@ module Kernel
|
||||
res.freeze
|
||||
end
|
||||
|
||||
def interactive_shell(f = nil)
|
||||
unless f.nil?
|
||||
ENV["HOMEBREW_DEBUG_PREFIX"] = f.prefix
|
||||
ENV["HOMEBREW_DEBUG_INSTALL"] = f.full_name
|
||||
def interactive_shell(formula = nil)
|
||||
unless formula.nil?
|
||||
ENV["HOMEBREW_DEBUG_PREFIX"] = formula.prefix
|
||||
ENV["HOMEBREW_DEBUG_INSTALL"] = formula.full_name
|
||||
end
|
||||
|
||||
if Utils::Shell.preferred == :zsh && (home = Dir.home).start_with?(HOMEBREW_TEMP.resolved_path.to_s)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Stdenv
|
||||
@ -7,7 +7,7 @@ module Stdenv
|
||||
undef homebrew_extra_pkg_config_paths
|
||||
|
||||
def homebrew_extra_pkg_config_paths
|
||||
["#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}"]
|
||||
[Pathname("#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}")]
|
||||
end
|
||||
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Superenv
|
||||
@ -29,7 +29,7 @@ module Superenv
|
||||
|
||||
# @private
|
||||
def homebrew_extra_pkg_config_paths
|
||||
["/usr/lib/pkgconfig", "#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}"]
|
||||
[Pathname("/usr/lib/pkgconfig"), Pathname("#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}")]
|
||||
end
|
||||
|
||||
# @private
|
||||
@ -68,7 +68,7 @@ module Superenv
|
||||
end
|
||||
|
||||
def homebrew_extra_cmake_library_paths
|
||||
["#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries"]
|
||||
[Pathname("#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries")]
|
||||
end
|
||||
|
||||
def homebrew_extra_cmake_frameworks_paths
|
||||
@ -96,7 +96,7 @@ module Superenv
|
||||
end
|
||||
|
||||
self["HOMEBREW_DEVELOPER_DIR"] = if is_xcode_sdk
|
||||
MacOS::Xcode.prefix
|
||||
MacOS::Xcode.prefix.to_s
|
||||
else
|
||||
MacOS::CLT::PKG_PATH
|
||||
end
|
||||
|
||||
@ -38,12 +38,12 @@ module SystemConfig
|
||||
@clt ||= MacOS::CLT.version if MacOS::CLT.installed?
|
||||
end
|
||||
|
||||
def dump_verbose_config(f = $stdout)
|
||||
dump_generic_verbose_config(f)
|
||||
f.puts "macOS: #{MacOS.full_version}-#{kernel}"
|
||||
f.puts "CLT: #{clt || "N/A"}"
|
||||
f.puts "Xcode: #{xcode || "N/A"}"
|
||||
f.puts "Rosetta 2: #{Hardware::CPU.in_rosetta2?}" if Hardware::CPU.physical_cpu_arm64?
|
||||
def dump_verbose_config(out = $stdout)
|
||||
dump_generic_verbose_config(out)
|
||||
out.puts "macOS: #{MacOS.full_version}-#{kernel}"
|
||||
out.puts "CLT: #{clt || "N/A"}"
|
||||
out.puts "Xcode: #{xcode || "N/A"}"
|
||||
out.puts "Rosetta 2: #{Hardware::CPU.in_rosetta2?}" if Hardware::CPU.physical_cpu_arm64?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -6,16 +6,16 @@ module Homebrew
|
||||
module Fetch
|
||||
extend T::Sig
|
||||
|
||||
sig { params(f: Formula, args: CLI::Args).returns(T::Boolean) }
|
||||
def fetch_bottle?(f, args:)
|
||||
bottle = f.bottle
|
||||
sig { params(formula: Formula, args: CLI::Args).returns(T::Boolean) }
|
||||
def fetch_bottle?(formula, args:)
|
||||
bottle = formula.bottle
|
||||
|
||||
return true if args.force_bottle? && bottle.present?
|
||||
return true if args.bottle_tag.present? && f.bottled?(args.bottle_tag)
|
||||
return true if args.bottle_tag.present? && formula.bottled?(args.bottle_tag)
|
||||
|
||||
bottle.present? &&
|
||||
f.pour_bottle? &&
|
||||
args.build_from_source_formulae.exclude?(f.full_name) &&
|
||||
formula.pour_bottle? &&
|
||||
args.build_from_source_formulae.exclude?(formula.full_name) &&
|
||||
bottle.compatible_locations?
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Homebrew
|
||||
|
||||
5
Library/Homebrew/formula_assertions.rbi
Normal file
5
Library/Homebrew/formula_assertions.rbi
Normal file
@ -0,0 +1,5 @@
|
||||
# typed: strict
|
||||
|
||||
module Homebrew::Assertions
|
||||
include Kernel
|
||||
end
|
||||
@ -7,22 +7,22 @@ require "keg"
|
||||
#
|
||||
# @api private
|
||||
class FormulaPin
|
||||
def initialize(f)
|
||||
@f = f
|
||||
def initialize(formula)
|
||||
@formula = formula
|
||||
end
|
||||
|
||||
def path
|
||||
HOMEBREW_PINNED_KEGS/@f.name
|
||||
HOMEBREW_PINNED_KEGS/@formula.name
|
||||
end
|
||||
|
||||
def pin_at(version)
|
||||
HOMEBREW_PINNED_KEGS.mkpath
|
||||
version_path = @f.rack/version
|
||||
version_path = @formula.rack/version
|
||||
path.make_relative_symlink(version_path) if !pinned? && version_path.exist?
|
||||
end
|
||||
|
||||
def pin
|
||||
pin_at(@f.installed_kegs.map(&:version).max)
|
||||
pin_at(@formula.installed_kegs.map(&:version).max)
|
||||
end
|
||||
|
||||
def unpin
|
||||
@ -35,7 +35,7 @@ class FormulaPin
|
||||
end
|
||||
|
||||
def pinnable?
|
||||
!@f.installed_prefixes.empty?
|
||||
!@formula.installed_prefixes.empty?
|
||||
end
|
||||
|
||||
def pinned_version
|
||||
|
||||
@ -124,6 +124,10 @@ module Homebrew
|
||||
def running_as_root_but_not_owned_by_root?
|
||||
running_as_root? && !owner_uid.zero?
|
||||
end
|
||||
|
||||
def auto_update_command?
|
||||
ENV.fetch("HOMEBREW_AUTO_UPDATE_COMMAND", false).present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -97,7 +97,7 @@ module Homebrew
|
||||
private_class_method :check_cc_argv
|
||||
|
||||
def install_formula?(
|
||||
f,
|
||||
formula,
|
||||
head: false,
|
||||
fetch_head: false,
|
||||
only_dependencies: false,
|
||||
@ -105,49 +105,51 @@ module Homebrew
|
||||
quiet: false
|
||||
)
|
||||
# head-only without --HEAD is an error
|
||||
if !head && f.stable.nil?
|
||||
if !head && formula.stable.nil?
|
||||
odie <<~EOS
|
||||
#{f.full_name} is a head-only formula.
|
||||
#{formula.full_name} is a head-only formula.
|
||||
To install it, run:
|
||||
brew install --HEAD #{f.full_name}
|
||||
brew install --HEAD #{formula.full_name}
|
||||
EOS
|
||||
end
|
||||
|
||||
# --HEAD, fail with no head defined
|
||||
odie "No head is defined for #{f.full_name}" if head && f.head.nil?
|
||||
odie "No head is defined for #{formula.full_name}" if head && formula.head.nil?
|
||||
|
||||
installed_head_version = f.latest_head_version
|
||||
installed_head_version = formula.latest_head_version
|
||||
if installed_head_version &&
|
||||
!f.head_version_outdated?(installed_head_version, fetch_head: fetch_head)
|
||||
!formula.head_version_outdated?(installed_head_version, fetch_head: fetch_head)
|
||||
new_head_installed = true
|
||||
end
|
||||
prefix_installed = f.prefix.exist? && !f.prefix.children.empty?
|
||||
prefix_installed = formula.prefix.exist? && !formula.prefix.children.empty?
|
||||
|
||||
if f.keg_only? && f.any_version_installed? && f.optlinked? && !force
|
||||
if formula.keg_only? && formula.any_version_installed? && formula.optlinked? && !force
|
||||
# keg-only install is only possible when no other version is
|
||||
# linked to opt, because installing without any warnings can break
|
||||
# dependencies. Therefore before performing other checks we need to be
|
||||
# sure --force flag is passed.
|
||||
if f.outdated?
|
||||
if !Homebrew::EnvConfig.no_install_upgrade? && !f.pinned?
|
||||
puts "#{f.name} #{f.linked_version} is already installed but outdated (so it will be upgraded)."
|
||||
if formula.outdated?
|
||||
if !Homebrew::EnvConfig.no_install_upgrade? && !formula.pinned?
|
||||
name = formula.name
|
||||
version = formula.linked_version
|
||||
puts "#{name} #{version} is already installed but outdated (so it will be upgraded)."
|
||||
return true
|
||||
end
|
||||
|
||||
unpin_cmd_if_needed = ("brew unpin #{f.full_name} && " if f.pinned?)
|
||||
optlinked_version = Keg.for(f.opt_prefix).version
|
||||
unpin_cmd_if_needed = ("brew unpin #{formula.full_name} && " if formula.pinned?)
|
||||
optlinked_version = Keg.for(formula.opt_prefix).version
|
||||
onoe <<~EOS
|
||||
#{f.full_name} #{optlinked_version} is already installed.
|
||||
To upgrade to #{f.version}, run:
|
||||
#{unpin_cmd_if_needed}brew upgrade #{f.full_name}
|
||||
#{formula.full_name} #{optlinked_version} is already installed.
|
||||
To upgrade to #{formula.version}, run:
|
||||
#{unpin_cmd_if_needed}brew upgrade #{formula.full_name}
|
||||
EOS
|
||||
elsif only_dependencies
|
||||
return true
|
||||
elsif !quiet
|
||||
opoo <<~EOS
|
||||
#{f.full_name} #{f.pkg_version} is already installed and up-to-date.
|
||||
To reinstall #{f.pkg_version}, run:
|
||||
brew reinstall #{f.name}
|
||||
#{formula.full_name} #{formula.pkg_version} is already installed and up-to-date.
|
||||
To reinstall #{formula.pkg_version}, run:
|
||||
brew reinstall #{formula.name}
|
||||
EOS
|
||||
end
|
||||
elsif (head && new_head_installed) || prefix_installed
|
||||
@ -156,27 +158,27 @@ module Homebrew
|
||||
# install is not already installed.
|
||||
|
||||
installed_version = if head
|
||||
f.latest_head_version
|
||||
formula.latest_head_version
|
||||
else
|
||||
f.pkg_version
|
||||
formula.pkg_version
|
||||
end
|
||||
|
||||
msg = "#{f.full_name} #{installed_version} is already installed"
|
||||
linked_not_equals_installed = f.linked_version != installed_version
|
||||
if f.linked? && linked_not_equals_installed
|
||||
msg = "#{formula.full_name} #{installed_version} is already installed"
|
||||
linked_not_equals_installed = formula.linked_version != installed_version
|
||||
if formula.linked? && linked_not_equals_installed
|
||||
msg = if quiet
|
||||
nil
|
||||
else
|
||||
<<~EOS
|
||||
#{msg}.
|
||||
The currently linked version is: #{f.linked_version}
|
||||
The currently linked version is: #{formula.linked_version}
|
||||
EOS
|
||||
end
|
||||
elsif !f.linked? || f.keg_only?
|
||||
elsif !formula.linked? || formula.keg_only?
|
||||
msg = <<~EOS
|
||||
#{msg}, it's just not linked.
|
||||
To link this version, run:
|
||||
brew link #{f}
|
||||
brew link #{formula}
|
||||
EOS
|
||||
elsif only_dependencies
|
||||
msg = nil
|
||||
@ -187,13 +189,13 @@ module Homebrew
|
||||
else
|
||||
<<~EOS
|
||||
#{msg} and up-to-date.
|
||||
To reinstall #{f.pkg_version}, run:
|
||||
brew reinstall #{f.name}
|
||||
To reinstall #{formula.pkg_version}, run:
|
||||
brew reinstall #{formula.name}
|
||||
EOS
|
||||
end
|
||||
end
|
||||
opoo msg if msg
|
||||
elsif !f.any_version_installed? && (old_formula = f.old_installed_formulae.first)
|
||||
elsif !formula.any_version_installed? && (old_formula = formula.old_installed_formulae.first)
|
||||
msg = "#{old_formula.full_name} #{old_formula.any_installed_version} already installed"
|
||||
msg = if !old_formula.linked? && !old_formula.keg_only?
|
||||
<<~EOS
|
||||
@ -207,37 +209,37 @@ module Homebrew
|
||||
"#{msg}."
|
||||
end
|
||||
opoo msg if msg
|
||||
elsif f.migration_needed? && !force
|
||||
elsif formula.migration_needed? && !force
|
||||
# Check if the formula we try to install is the same as installed
|
||||
# but not migrated one. If --force is passed then install anyway.
|
||||
opoo <<~EOS
|
||||
#{f.oldname} is already installed, it's just not migrated.
|
||||
#{formula.oldname} is already installed, it's just not migrated.
|
||||
To migrate this formula, run:
|
||||
brew migrate #{f}
|
||||
brew migrate #{formula}
|
||||
Or to force-install it, run:
|
||||
brew install #{f} --force
|
||||
brew install #{formula} --force
|
||||
EOS
|
||||
elsif f.linked?
|
||||
message = "#{f.name} #{f.linked_version} is already installed"
|
||||
if f.outdated? && !head
|
||||
if !Homebrew::EnvConfig.no_install_upgrade? && !f.pinned?
|
||||
elsif formula.linked?
|
||||
message = "#{formula.name} #{formula.linked_version} is already installed"
|
||||
if formula.outdated? && !head
|
||||
if !Homebrew::EnvConfig.no_install_upgrade? && !formula.pinned?
|
||||
puts "#{message} but outdated (so it will be upgraded)."
|
||||
return true
|
||||
end
|
||||
|
||||
unpin_cmd_if_needed = ("brew unpin #{f.full_name} && " if f.pinned?)
|
||||
unpin_cmd_if_needed = ("brew unpin #{formula.full_name} && " if formula.pinned?)
|
||||
onoe <<~EOS
|
||||
#{message}
|
||||
To upgrade to #{f.pkg_version}, run:
|
||||
#{unpin_cmd_if_needed}brew upgrade #{f.full_name}
|
||||
To upgrade to #{formula.pkg_version}, run:
|
||||
#{unpin_cmd_if_needed}brew upgrade #{formula.full_name}
|
||||
EOS
|
||||
elsif only_dependencies
|
||||
return true
|
||||
else
|
||||
onoe <<~EOS
|
||||
#{message}
|
||||
To install #{f.pkg_version}, first run:
|
||||
brew unlink #{f.name}
|
||||
To install #{formula.pkg_version}, first run:
|
||||
brew unlink #{formula.name}
|
||||
EOS
|
||||
end
|
||||
else
|
||||
@ -248,9 +250,9 @@ module Homebrew
|
||||
|
||||
# Even if we don't install this formula mark it as no longer just
|
||||
# installed as a dependency.
|
||||
return false unless f.opt_prefix.directory?
|
||||
return false unless formula.opt_prefix.directory?
|
||||
|
||||
keg = Keg.new(f.opt_prefix.resolved_path)
|
||||
keg = Keg.new(formula.opt_prefix.resolved_path)
|
||||
tab = Tab.for_keg(keg)
|
||||
unless tab.installed_on_request
|
||||
tab.installed_on_request = true
|
||||
@ -281,12 +283,12 @@ module Homebrew
|
||||
verbose: false,
|
||||
dry_run: false
|
||||
)
|
||||
formula_installers = formulae_to_install.map do |f|
|
||||
Migrator.migrate_if_needed(f, force: force, dry_run: dry_run)
|
||||
build_options = f.build
|
||||
formula_installers = formulae_to_install.map do |formula|
|
||||
Migrator.migrate_if_needed(formula, force: force, dry_run: dry_run)
|
||||
build_options = formula.build
|
||||
|
||||
fi = FormulaInstaller.new(
|
||||
f,
|
||||
formula_installer = FormulaInstaller.new(
|
||||
formula,
|
||||
options: build_options.used_options,
|
||||
build_bottle: build_bottle,
|
||||
force_bottle: force_bottle,
|
||||
@ -309,15 +311,15 @@ module Homebrew
|
||||
|
||||
begin
|
||||
unless dry_run
|
||||
fi.prelude
|
||||
fi.fetch
|
||||
formula_installer.prelude
|
||||
formula_installer.fetch
|
||||
end
|
||||
fi
|
||||
formula_installer
|
||||
rescue CannotInstallFormulaError => e
|
||||
ofail e.message
|
||||
nil
|
||||
rescue UnsatisfiedRequirements, DownloadError, ChecksumMismatchError => e
|
||||
ofail "#{f}: #{e}"
|
||||
ofail "#{formula}: #{e}"
|
||||
nil
|
||||
end
|
||||
end.compact
|
||||
@ -329,8 +331,7 @@ module Homebrew
|
||||
puts formulae_name_to_install.join(" ")
|
||||
|
||||
formula_installers.each do |fi|
|
||||
f = fi.formula
|
||||
print_dry_run_dependencies(f, fi.compute_dependencies, &:name)
|
||||
print_dry_run_dependencies(fi.formula, fi.compute_dependencies, &:name)
|
||||
end
|
||||
end
|
||||
return
|
||||
@ -343,9 +344,9 @@ module Homebrew
|
||||
end
|
||||
|
||||
def install_formula(formula_installer)
|
||||
f = formula_installer.formula
|
||||
formula = formula_installer.formula
|
||||
|
||||
upgrade = f.linked? && f.outdated? && !f.head? && !Homebrew::EnvConfig.no_install_upgrade?
|
||||
upgrade = formula.linked? && formula.outdated? && !formula.head? && !Homebrew::EnvConfig.no_install_upgrade?
|
||||
|
||||
Upgrade.install_formula(formula_installer, upgrade: upgrade)
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Keg
|
||||
@ -44,7 +44,7 @@ class Keg
|
||||
key.is_a?(String) ? key.length : 999
|
||||
end.reverse
|
||||
|
||||
any_changed = false
|
||||
any_changed = T.let(nil, T.nilable(String))
|
||||
sorted_keys.each do |key|
|
||||
changed = text.gsub!(key, replacements[key])
|
||||
any_changed ||= changed
|
||||
@ -144,7 +144,7 @@ class Keg
|
||||
def replace_text_in_files(relocation, files: nil)
|
||||
files ||= text_files | libtool_files
|
||||
|
||||
changed_files = []
|
||||
changed_files = T.let([], Array)
|
||||
files.map(&path.method(:join)).group_by { |f| f.stat.ino }.each_value do |first, *rest|
|
||||
s = first.open("rb", &:read)
|
||||
|
||||
@ -179,11 +179,11 @@ class Keg
|
||||
binary = File.binread file
|
||||
odebug "Replacing build prefix in: #{file}"
|
||||
binary_strings = binary.split(/#{NULL_BYTE}/o, -1)
|
||||
match_indices = binary_strings.each_index.select { |i| binary_strings[i].include?(old_prefix) }
|
||||
match_indices = binary_strings.each_index.select { |i| binary_strings.fetch(i).include?(old_prefix) }
|
||||
|
||||
# Only perform substitution on strings which match prefix regex.
|
||||
match_indices.each do |i|
|
||||
s = binary_strings[i]
|
||||
s = binary_strings.fetch(i)
|
||||
binary_strings[i] = s.gsub(old_prefix, new_prefix)
|
||||
.ljust(s.size, NULL_BYTE)
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Language
|
||||
|
||||
11
Library/Homebrew/language/python.rbi
Normal file
11
Library/Homebrew/language/python.rbi
Normal file
@ -0,0 +1,11 @@
|
||||
# typed: strict
|
||||
|
||||
module Language::Python
|
||||
module Shebang
|
||||
include Kernel
|
||||
end
|
||||
|
||||
module Virtualenv
|
||||
requires_ancestor { Formula }
|
||||
end
|
||||
end
|
||||
@ -139,8 +139,8 @@ class Options
|
||||
map(&:flag)
|
||||
end
|
||||
|
||||
def include?(o)
|
||||
any? { |opt| opt == o || opt.name == o || opt.flag == o }
|
||||
def include?(option)
|
||||
any? { |opt| opt == option || opt.name == option || opt.flag == option }
|
||||
end
|
||||
|
||||
alias to_ary to_a
|
||||
@ -155,10 +155,10 @@ class Options
|
||||
"#<#{self.class.name}: #{to_a.inspect}>"
|
||||
end
|
||||
|
||||
def self.dump_for_formula(f)
|
||||
f.options.sort_by(&:flag).each do |opt|
|
||||
def self.dump_for_formula(formula)
|
||||
formula.options.sort_by(&:flag).each do |opt|
|
||||
puts "#{opt.flag}\n\t#{opt.description}"
|
||||
end
|
||||
puts "--HEAD\n\tInstall HEAD version" if f.head
|
||||
puts "--HEAD\n\tInstall HEAD version" if formula.head
|
||||
end
|
||||
end
|
||||
|
||||
@ -117,11 +117,11 @@ module OS
|
||||
sdk_locator.sdk_if_applicable(version)
|
||||
end
|
||||
|
||||
def sdk_for_formula(f, version = nil, check_only_runtime_requirements: false)
|
||||
def sdk_for_formula(formula, version = nil, check_only_runtime_requirements: false)
|
||||
# If the formula requires Xcode, don't return the CLT SDK
|
||||
# If check_only_runtime_requirements is true, don't necessarily return the
|
||||
# Xcode SDK if the XcodeRequirement is only a build or test requirement.
|
||||
return Xcode.sdk if f.requirements.any? do |req|
|
||||
return Xcode.sdk if formula.requirements.any? do |req|
|
||||
next false unless req.is_a? XcodeRequirement
|
||||
next false if check_only_runtime_requirements && req.build? && !req.test?
|
||||
|
||||
|
||||
@ -214,13 +214,13 @@ module RuboCop
|
||||
end
|
||||
|
||||
# Method to report and correct component precedence violations.
|
||||
def component_problem(c1, c2)
|
||||
def component_problem(component1, component2)
|
||||
return if tap_style_exception? :components_order_exceptions
|
||||
|
||||
problem "`#{format_component(c1)}` (line #{line_number(c1)}) " \
|
||||
"should be put before `#{format_component(c2)}` " \
|
||||
"(line #{line_number(c2)})" do |corrector|
|
||||
reorder_components(corrector, c1, c2)
|
||||
problem "`#{format_component(component1)}` (line #{line_number(component1)}) " \
|
||||
"should be put before `#{format_component(component2)}` " \
|
||||
"(line #{line_number(component2)})" do |corrector|
|
||||
reorder_components(corrector, component1, component2)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -170,12 +170,12 @@ module Homebrew
|
||||
[all_formulae, all_casks]
|
||||
end
|
||||
|
||||
def search(array, string_or_regex, &block)
|
||||
def search(selectable, string_or_regex, &block)
|
||||
case string_or_regex
|
||||
when Regexp
|
||||
search_regex(array, string_or_regex, &block)
|
||||
search_regex(selectable, string_or_regex, &block)
|
||||
else
|
||||
search_string(array, string_or_regex.to_str, &block)
|
||||
search_string(selectable, string_or_regex.to_str, &block)
|
||||
end
|
||||
end
|
||||
|
||||
@ -183,17 +183,17 @@ module Homebrew
|
||||
string.downcase.gsub(/[^a-z\d]/i, "")
|
||||
end
|
||||
|
||||
def search_regex(array, regex)
|
||||
array.select do |*args|
|
||||
def search_regex(selectable, regex)
|
||||
selectable.select do |*args|
|
||||
args = yield(*args) if block_given?
|
||||
args = Array(args).flatten.compact
|
||||
args.any? { |arg| arg.match?(regex) }
|
||||
end
|
||||
end
|
||||
|
||||
def search_string(array, string)
|
||||
def search_string(selectable, string)
|
||||
simplified_string = simplify_string(string)
|
||||
array.select do |*args|
|
||||
selectable.select do |*args|
|
||||
args = yield(*args) if block_given?
|
||||
args = Array(args).flatten.compact
|
||||
args.any? { |arg| simplify_string(arg).include?(simplified_string) }
|
||||
|
||||
@ -139,43 +139,43 @@ module SystemConfig
|
||||
end
|
||||
end
|
||||
|
||||
def core_tap_config(f = $stdout)
|
||||
def core_tap_config(out = $stdout)
|
||||
if CoreTap.instance.installed?
|
||||
f.puts "Core tap origin: #{core_tap_origin}"
|
||||
f.puts "Core tap HEAD: #{core_tap_head}"
|
||||
f.puts "Core tap last commit: #{core_tap_last_commit}"
|
||||
f.puts "Core tap branch: #{core_tap_branch}"
|
||||
out.puts "Core tap origin: #{core_tap_origin}"
|
||||
out.puts "Core tap HEAD: #{core_tap_head}"
|
||||
out.puts "Core tap last commit: #{core_tap_last_commit}"
|
||||
out.puts "Core tap branch: #{core_tap_branch}"
|
||||
end
|
||||
|
||||
if (formula_json = Homebrew::API::HOMEBREW_CACHE_API/"formula.jws.json") && formula_json.exist?
|
||||
f.puts "Core tap JSON: #{formula_json.mtime.utc.strftime("%d %b %H:%M UTC")}"
|
||||
out.puts "Core tap JSON: #{formula_json.mtime.utc.strftime("%d %b %H:%M UTC")}"
|
||||
elsif !CoreTap.instance.installed?
|
||||
f.puts "Core tap: N/A"
|
||||
out.puts "Core tap: N/A"
|
||||
end
|
||||
end
|
||||
|
||||
def homebrew_config(f = $stdout)
|
||||
f.puts "HOMEBREW_VERSION: #{HOMEBREW_VERSION}"
|
||||
f.puts "ORIGIN: #{origin}"
|
||||
f.puts "HEAD: #{head}"
|
||||
f.puts "Last commit: #{last_commit}"
|
||||
def homebrew_config(out = $stdout)
|
||||
out.puts "HOMEBREW_VERSION: #{HOMEBREW_VERSION}"
|
||||
out.puts "ORIGIN: #{origin}"
|
||||
out.puts "HEAD: #{head}"
|
||||
out.puts "Last commit: #{last_commit}"
|
||||
end
|
||||
|
||||
def homebrew_env_config(f = $stdout)
|
||||
f.puts "HOMEBREW_PREFIX: #{HOMEBREW_PREFIX}"
|
||||
def homebrew_env_config(out = $stdout)
|
||||
out.puts "HOMEBREW_PREFIX: #{HOMEBREW_PREFIX}"
|
||||
{
|
||||
HOMEBREW_REPOSITORY: Homebrew::DEFAULT_REPOSITORY,
|
||||
HOMEBREW_CELLAR: Homebrew::DEFAULT_CELLAR,
|
||||
}.freeze.each do |key, default|
|
||||
value = Object.const_get(key)
|
||||
f.puts "#{key}: #{value}" if value.to_s != default.to_s
|
||||
out.puts "#{key}: #{value}" if value.to_s != default.to_s
|
||||
end
|
||||
|
||||
Homebrew::EnvConfig::ENVS.each do |env, hash|
|
||||
method_name = Homebrew::EnvConfig.env_method_name(env, hash)
|
||||
|
||||
if hash[:boolean]
|
||||
f.puts "#{env}: set" if Homebrew::EnvConfig.send(method_name)
|
||||
out.puts "#{env}: set" if Homebrew::EnvConfig.send(method_name)
|
||||
next
|
||||
end
|
||||
|
||||
@ -184,26 +184,26 @@ module SystemConfig
|
||||
next if (default = hash[:default].presence) && value.to_s == default.to_s
|
||||
|
||||
if ENV.sensitive?(env)
|
||||
f.puts "#{env}: set"
|
||||
out.puts "#{env}: set"
|
||||
else
|
||||
f.puts "#{env}: #{value}"
|
||||
out.puts "#{env}: #{value}"
|
||||
end
|
||||
end
|
||||
f.puts "Homebrew Ruby: #{describe_homebrew_ruby}"
|
||||
out.puts "Homebrew Ruby: #{describe_homebrew_ruby}"
|
||||
end
|
||||
|
||||
def host_software_config(f = $stdout)
|
||||
f.puts "Clang: #{describe_clang}"
|
||||
f.puts "Git: #{describe_git}"
|
||||
f.puts "Curl: #{describe_curl}"
|
||||
def host_software_config(out = $stdout)
|
||||
out.puts "Clang: #{describe_clang}"
|
||||
out.puts "Git: #{describe_git}"
|
||||
out.puts "Curl: #{describe_curl}"
|
||||
end
|
||||
|
||||
def dump_verbose_config(f = $stdout)
|
||||
homebrew_config(f)
|
||||
core_tap_config(f)
|
||||
homebrew_env_config(f)
|
||||
f.puts hardware if hardware
|
||||
host_software_config(f)
|
||||
def dump_verbose_config(out = $stdout)
|
||||
homebrew_config(out)
|
||||
core_tap_config(out)
|
||||
homebrew_env_config(out)
|
||||
out.puts hardware if hardware
|
||||
host_software_config(out)
|
||||
end
|
||||
alias dump_generic_verbose_config dump_verbose_config
|
||||
end
|
||||
|
||||
@ -143,37 +143,37 @@ class Tab < OpenStruct
|
||||
|
||||
# Returns a {Tab} for an already installed formula,
|
||||
# or a fake one if the formula is not installed.
|
||||
def self.for_formula(f)
|
||||
def self.for_formula(formula)
|
||||
paths = []
|
||||
|
||||
paths << f.opt_prefix.resolved_path if f.opt_prefix.symlink? && f.opt_prefix.directory?
|
||||
paths << formula.opt_prefix.resolved_path if formula.opt_prefix.symlink? && formula.opt_prefix.directory?
|
||||
|
||||
paths << f.linked_keg.resolved_path if f.linked_keg.symlink? && f.linked_keg.directory?
|
||||
paths << formula.linked_keg.resolved_path if formula.linked_keg.symlink? && formula.linked_keg.directory?
|
||||
|
||||
if (dirs = f.installed_prefixes).length == 1
|
||||
if (dirs = formula.installed_prefixes).length == 1
|
||||
paths << dirs.first
|
||||
end
|
||||
|
||||
paths << f.latest_installed_prefix
|
||||
paths << formula.latest_installed_prefix
|
||||
|
||||
path = paths.map { |pn| pn/FILENAME }.find(&:file?)
|
||||
path = paths.map { |pathname| pathname/FILENAME }.find(&:file?)
|
||||
|
||||
if path
|
||||
tab = from_file(path)
|
||||
used_options = remap_deprecated_options(f.deprecated_options, tab.used_options)
|
||||
used_options = remap_deprecated_options(formula.deprecated_options, tab.used_options)
|
||||
tab.used_options = used_options.as_flags
|
||||
else
|
||||
# Formula is not installed. Return a fake tab.
|
||||
tab = empty
|
||||
tab.unused_options = f.options.as_flags
|
||||
tab.unused_options = formula.options.as_flags
|
||||
tab.source = {
|
||||
"path" => f.specified_path.to_s,
|
||||
"tap" => f.tap&.name,
|
||||
"spec" => f.active_spec_sym.to_s,
|
||||
"path" => formula.specified_path.to_s,
|
||||
"tap" => formula.tap&.name,
|
||||
"spec" => formula.active_spec_sym.to_s,
|
||||
"versions" => {
|
||||
"stable" => f.stable&.version.to_s,
|
||||
"head" => f.head&.version.to_s,
|
||||
"version_scheme" => f.version_scheme,
|
||||
"stable" => formula.stable&.version.to_s,
|
||||
"head" => formula.head&.version.to_s,
|
||||
"version_scheme" => formula.version_scheme,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
raise "#{__FILE__} must not be loaded via `require`." if $PROGRAM_NAME != __FILE__
|
||||
@ -38,12 +38,10 @@ begin
|
||||
formula.extend(Debrew::Formula) if args.debug?
|
||||
|
||||
ENV.extend(Stdenv)
|
||||
T.cast(ENV, Stdenv).setup_build_environment(formula: formula, testing_formula: true)
|
||||
ENV.setup_build_environment(formula: formula, testing_formula: true)
|
||||
|
||||
# tests can also return false to indicate failure
|
||||
run_test = proc do
|
||||
raise "test returned false" if formula.run_test(keep_tmp: args.keep_tmp?) == false
|
||||
end
|
||||
run_test = proc { |_ = nil| raise "test returned false" if formula.run_test(keep_tmp: args.keep_tmp?) == false }
|
||||
if args.debug? # --debug is interactive
|
||||
run_test.call
|
||||
else
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe Cask::Cmd::Upgrade, :cask do
|
||||
require "cask/upgrade"
|
||||
|
||||
describe Cask::Upgrade, :cask do
|
||||
let(:version_latest_path_2) { version_latest.config.appdir.join("Caffeine Pro.app") }
|
||||
let(:version_latest_path_1) { version_latest.config.appdir.join("Caffeine Mini.app") }
|
||||
let(:version_latest) { Cask::CaskLoader.load("version-latest") }
|
||||
@ -11,6 +13,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
let(:local_transmission) { Cask::CaskLoader.load("local-transmission") }
|
||||
let(:local_caffeine_path) { local_caffeine.config.appdir.join("Caffeine.app") }
|
||||
let(:local_caffeine) { Cask::CaskLoader.load("local-caffeine") }
|
||||
let(:args) { Homebrew::CLI::Args.new }
|
||||
|
||||
context "when the upgrade is successful" do
|
||||
let(:installed) do
|
||||
@ -38,7 +41,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(local_transmission_path).to be_a_directory
|
||||
expect(local_transmission.versions).to include("2.60")
|
||||
|
||||
described_class.run
|
||||
described_class.upgrade_casks(args: args)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
@ -58,7 +61,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(local_transmission_path).to be_a_directory
|
||||
expect(local_transmission.versions).to include("2.60")
|
||||
|
||||
described_class.run("local-caffeine")
|
||||
described_class.upgrade_casks(local_caffeine, args: args)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
@ -78,7 +81,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(auto_updates_path).to be_a_directory
|
||||
expect(auto_updates.versions).to include("2.57")
|
||||
|
||||
described_class.run("local-caffeine", "auto-updates")
|
||||
described_class.upgrade_casks(local_caffeine, auto_updates, args: args)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
@ -111,7 +114,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
version_latest.download_sha_path.write("fake download sha")
|
||||
expect(version_latest.outdated_download_sha?).to be(true)
|
||||
|
||||
described_class.run("--greedy")
|
||||
described_class.upgrade_casks(greedy: true, args: args)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
@ -136,13 +139,13 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(auto_updates_path).to be_a_directory
|
||||
expect(auto_updates.versions).to include("2.57")
|
||||
|
||||
described_class.run("auto-updates", "--greedy")
|
||||
described_class.upgrade_casks(auto_updates, greedy: true, args: args)
|
||||
|
||||
expect(auto_updates).to be_installed
|
||||
expect(auto_updates_path).to be_a_directory
|
||||
expect(auto_updates.versions).to include("2.61")
|
||||
|
||||
described_class.run("auto-updates", "--greedy")
|
||||
described_class.upgrade_casks(auto_updates, greedy: true, args: args)
|
||||
|
||||
expect(auto_updates).to be_installed
|
||||
expect(auto_updates_path).to be_a_directory
|
||||
@ -158,7 +161,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
version_latest.download_sha_path.write("fake download sha")
|
||||
expect(version_latest.outdated_download_sha?).to be(true)
|
||||
|
||||
described_class.run("version-latest", "--greedy")
|
||||
described_class.upgrade_casks(version_latest, greedy: true, args: args)
|
||||
|
||||
expect(version_latest).to be_installed
|
||||
expect(version_latest_path_1).to be_a_directory
|
||||
@ -166,7 +169,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(version_latest.versions).to include("latest")
|
||||
expect(version_latest.outdated_download_sha?).to be(false)
|
||||
|
||||
described_class.run("version-latest", "--greedy")
|
||||
described_class.upgrade_casks(version_latest, greedy: true, args: args)
|
||||
|
||||
expect(version_latest).to be_installed
|
||||
expect(version_latest_path_1).to be_a_directory
|
||||
@ -205,7 +208,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(local_transmission_path).to be_a_directory
|
||||
expect(local_transmission.versions).to include("2.60")
|
||||
|
||||
described_class.run("--dry-run")
|
||||
described_class.upgrade_casks(dry_run: true, args: args)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
@ -229,7 +232,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(local_transmission_path).to be_a_directory
|
||||
expect(local_transmission.versions).to include("2.60")
|
||||
|
||||
described_class.run("--dry-run", "local-caffeine")
|
||||
described_class.upgrade_casks(local_caffeine, dry_run: true, args: args)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
@ -253,7 +256,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(auto_updates_path).to be_a_directory
|
||||
expect(auto_updates.versions).to include("2.57")
|
||||
|
||||
described_class.run("--dry-run", "local-caffeine", "auto-updates")
|
||||
described_class.upgrade_casks(local_caffeine, auto_updates, dry_run: true, args: args)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
@ -288,7 +291,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
version_latest.download_sha_path.write("fake download sha")
|
||||
expect(version_latest.outdated_download_sha?).to be(true)
|
||||
|
||||
described_class.run("--greedy", "--dry-run")
|
||||
described_class.upgrade_casks(greedy: true, dry_run: true, args: args)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
@ -316,7 +319,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(auto_updates_path).to be_a_directory
|
||||
expect(auto_updates.versions).to include("2.57")
|
||||
|
||||
described_class.run("--dry-run", "auto-updates", "--greedy")
|
||||
described_class.upgrade_casks(auto_updates, dry_run: true, greedy: true, args: args)
|
||||
|
||||
expect(auto_updates).to be_installed
|
||||
expect(auto_updates_path).to be_a_directory
|
||||
@ -335,7 +338,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
version_latest.download_sha_path.write("fake download sha")
|
||||
expect(version_latest.outdated_download_sha?).to be(true)
|
||||
|
||||
described_class.run("--dry-run", "version-latest", "--greedy")
|
||||
described_class.upgrade_casks(version_latest, dry_run: true, greedy: true, args: args)
|
||||
|
||||
expect(version_latest).to be_installed
|
||||
expect(version_latest_path_1).to be_a_directory
|
||||
@ -373,7 +376,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(will_fail_if_upgraded.versions).to include("1.2.2")
|
||||
|
||||
expect do
|
||||
described_class.run("will-fail-if-upgraded")
|
||||
described_class.upgrade_casks(will_fail_if_upgraded, args: args)
|
||||
end.to raise_error(Cask::CaskError).and output(output_reverted).to_stderr
|
||||
|
||||
expect(will_fail_if_upgraded).to be_installed
|
||||
@ -391,7 +394,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(bad_checksum.versions).to include("1.2.2")
|
||||
|
||||
expect do
|
||||
described_class.run("bad-checksum")
|
||||
described_class.upgrade_casks(bad_checksum, args: args)
|
||||
end.to raise_error(ChecksumMismatchError).and(not_to_output(output_reverted).to_stderr)
|
||||
|
||||
expect(bad_checksum).to be_installed
|
||||
@ -436,7 +439,7 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(bad_checksum_2.versions).to include("1.2.2")
|
||||
|
||||
expect do
|
||||
described_class.run
|
||||
described_class.upgrade_casks(args: args)
|
||||
end.to raise_error(Cask::MultipleCaskErrors)
|
||||
|
||||
expect(bad_checksum).to be_installed
|
||||
@ -10,7 +10,7 @@ describe Caveats do
|
||||
let(:f) { formula { url "foo-1.0" } }
|
||||
|
||||
specify "#f" do
|
||||
expect(caveats.f).to eq(f)
|
||||
expect(caveats.formula).to eq(f)
|
||||
end
|
||||
|
||||
describe "#empty?" do
|
||||
|
||||
@ -6,19 +6,29 @@ require "cmd/shared_examples/args_parse"
|
||||
describe "brew irb" do
|
||||
it_behaves_like "parseable arguments"
|
||||
|
||||
it "starts an interactive Homebrew shell session", :integration_test do
|
||||
setup_test_formula "testball"
|
||||
describe "integration test" do
|
||||
let(:history_file) { Pathname("#{Dir.home}/.brew_irb_history") }
|
||||
|
||||
irb_test = HOMEBREW_TEMP/"irb-test.rb"
|
||||
irb_test.write <<~RUBY
|
||||
"testball".f
|
||||
:testball.f
|
||||
exit
|
||||
RUBY
|
||||
after do
|
||||
history_file.delete if history_file.exist?
|
||||
end
|
||||
|
||||
expect { brew "irb", irb_test }
|
||||
.to output(/Interactive Homebrew Shell/).to_stdout
|
||||
.and not_to_output.to_stderr
|
||||
.and be_a_success
|
||||
it "starts an interactive Homebrew shell session", :integration_test do
|
||||
setup_test_formula "testball"
|
||||
|
||||
irb_test = HOMEBREW_TEMP/"irb-test.rb"
|
||||
irb_test.write <<~RUBY
|
||||
"testball".f
|
||||
:testball.f
|
||||
exit
|
||||
RUBY
|
||||
|
||||
expect { brew "irb", irb_test }
|
||||
.to output(/Interactive Homebrew Shell/).to_stdout
|
||||
.and not_to_output.to_stderr
|
||||
.and be_a_success
|
||||
|
||||
expect(history_file).to exist
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -49,22 +49,22 @@ describe FormulaInstaller do
|
||||
expect(formula).not_to be_latest_version_installed
|
||||
end
|
||||
|
||||
def test_basic_formula_setup(f)
|
||||
def test_basic_formula_setup(formula)
|
||||
# Test that things made it into the Keg
|
||||
expect(f.bin).to be_a_directory
|
||||
expect(formula.bin).to be_a_directory
|
||||
|
||||
expect(f.libexec).to be_a_directory
|
||||
expect(formula.libexec).to be_a_directory
|
||||
|
||||
expect(f.prefix/"main.c").not_to exist
|
||||
expect(formula.prefix/"main.c").not_to exist
|
||||
|
||||
# Test that things made it into the Cellar
|
||||
keg = Keg.new f.prefix
|
||||
keg = Keg.new formula.prefix
|
||||
keg.link
|
||||
|
||||
bin = HOMEBREW_PREFIX/"bin"
|
||||
expect(bin).to be_a_directory
|
||||
|
||||
expect(f.libexec).to be_a_directory
|
||||
expect(formula.libexec).to be_a_directory
|
||||
end
|
||||
|
||||
# This test wraps expect() calls in `test_basic_formula_setup`
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Homebrew
|
||||
# Provides helper methods for unlinking formulae and kegs with consistent output.
|
||||
module Unlink
|
||||
module_function
|
||||
|
||||
def unlink_versioned_formulae(formula, verbose: false)
|
||||
def self.unlink_versioned_formulae(formula, verbose: false)
|
||||
formula.versioned_formulae
|
||||
.select(&:keg_only?)
|
||||
.select(&:linked?)
|
||||
@ -18,7 +16,7 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def unlink(keg, dry_run: false, verbose: false)
|
||||
def self.unlink(keg, dry_run: false, verbose: false)
|
||||
options = { dry_run: dry_run, verbose: verbose }
|
||||
|
||||
keg.lock do
|
||||
|
||||
@ -423,13 +423,13 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def depends_on(a, b)
|
||||
if a.any_installed_keg
|
||||
def depends_on(one, two)
|
||||
if one.any_installed_keg
|
||||
&.runtime_dependencies
|
||||
&.any? { |d| d["full_name"] == b.full_name }
|
||||
&.any? { |dependency| dependency["full_name"] == two.full_name }
|
||||
1
|
||||
else
|
||||
a <=> b
|
||||
one <=> two
|
||||
end
|
||||
end
|
||||
private_class_method :depends_on
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "context"
|
||||
@ -42,7 +42,6 @@ module Utils
|
||||
--data av=#{HOMEBREW_VERSION}
|
||||
]
|
||||
metadata.each do |key, value|
|
||||
next unless key
|
||||
next unless value
|
||||
|
||||
key = ERB::Util.url_encode key
|
||||
@ -146,13 +145,13 @@ module Utils
|
||||
report_influx(measurement, package_and_options, on_request, additional_tags_influx)
|
||||
end
|
||||
|
||||
sig { params(exception: Exception).void }
|
||||
sig { params(exception: BuildError).void }
|
||||
def report_build_error(exception)
|
||||
report_google_build_error(exception)
|
||||
report_influx_error(exception)
|
||||
end
|
||||
|
||||
sig { params(exception: Exception).void }
|
||||
sig { params(exception: BuildError).void }
|
||||
def report_google_build_error(exception)
|
||||
return if not_this_run? || disabled?
|
||||
|
||||
@ -165,10 +164,10 @@ module Utils
|
||||
else
|
||||
formula_full_name
|
||||
end
|
||||
report_google_event("BuildError", package_and_options)
|
||||
report_google_event(:BuildError, package_and_options)
|
||||
end
|
||||
|
||||
sig { params(exception: Exception).void }
|
||||
sig { params(exception: BuildError).void }
|
||||
def report_influx_error(exception)
|
||||
return if not_this_run? || disabled?
|
||||
|
||||
@ -283,10 +282,10 @@ module Utils
|
||||
end
|
||||
end
|
||||
|
||||
def formula_output(f, args:)
|
||||
def formula_output(formula, args:)
|
||||
return if Homebrew::EnvConfig.no_analytics? || Homebrew::EnvConfig.no_github_api?
|
||||
|
||||
json = Homebrew::API::Formula.fetch f.name
|
||||
json = Homebrew::API::Formula.fetch formula.name
|
||||
return if json.blank? || json["analytics"].blank?
|
||||
|
||||
get_analytics(json, args: args)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Utils
|
||||
@ -25,7 +25,7 @@ module Utils
|
||||
def formulae_with_no_formula_dependents(formulae)
|
||||
return [] if formulae.blank?
|
||||
|
||||
dependents = []
|
||||
dependents = T.let([], T::Array[Formula])
|
||||
formulae.each do |formula|
|
||||
dependents += formula.runtime_formula_dependencies
|
||||
|
||||
@ -33,7 +33,7 @@ module Utils
|
||||
next if Tab.for_keg(formula.any_installed_keg).poured_from_bottle
|
||||
|
||||
formula.deps.select(&:build?).each do |dep|
|
||||
suppress(FormulaUnavailableError) { dependents << dep.to_formula }
|
||||
Kernel.suppress(FormulaUnavailableError) { dependents << dep.to_formula }
|
||||
end
|
||||
end
|
||||
formulae - dependents
|
||||
|
||||
@ -19,22 +19,22 @@ module Utils
|
||||
arch: HOMEBREW_PROCESSOR.downcase.to_sym)
|
||||
end
|
||||
|
||||
def built_as?(f)
|
||||
return false unless f.latest_version_installed?
|
||||
def built_as?(formula)
|
||||
return false unless formula.latest_version_installed?
|
||||
|
||||
tab = Tab.for_keg(f.latest_installed_prefix)
|
||||
tab = Tab.for_keg(formula.latest_installed_prefix)
|
||||
tab.built_as_bottle
|
||||
end
|
||||
|
||||
def file_outdated?(f, file)
|
||||
def file_outdated?(formula, file)
|
||||
filename = file.basename.to_s
|
||||
return false if f.bottle.blank?
|
||||
return false if formula.bottle.blank?
|
||||
|
||||
bottle_ext, bottle_tag, = extname_tag_rebuild(filename)
|
||||
return false if bottle_ext.blank?
|
||||
return false if bottle_tag != tag.to_s
|
||||
|
||||
bottle_url_ext, = extname_tag_rebuild(f.bottle.url)
|
||||
bottle_url_ext, = extname_tag_rebuild(formula.bottle.url)
|
||||
|
||||
bottle_ext && bottle_url_ext && bottle_ext != bottle_url_ext
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "open3"
|
||||
@ -243,8 +243,8 @@ module Utils
|
||||
return unless url.start_with? "http"
|
||||
|
||||
secure_url = url.sub(/\Ahttp:/, "https:")
|
||||
secure_details = nil
|
||||
hash_needed = false
|
||||
secure_details = T.let(nil, T.nilable(T::Hash[Symbol, T.untyped]))
|
||||
hash_needed = T.let(false, T::Boolean)
|
||||
if url != secure_url
|
||||
user_agents.each do |user_agent|
|
||||
secure_details = begin
|
||||
@ -267,7 +267,7 @@ module Utils
|
||||
end
|
||||
end
|
||||
|
||||
details = nil
|
||||
details = T.let(nil, T.nilable(T::Hash[Symbol, T.untyped]))
|
||||
user_agents.each do |user_agent|
|
||||
details =
|
||||
curl_http_content_headers_and_checksum(
|
||||
@ -414,7 +414,7 @@ module Utils
|
||||
# Unknown charset in Content-Type header
|
||||
end
|
||||
end
|
||||
file_contents = File.read(file.path, **open_args)
|
||||
file_contents = File.read(T.must(file.path), **open_args)
|
||||
file_hash = Digest::SHA2.hexdigest(file_contents) if hash_needed
|
||||
end
|
||||
|
||||
@ -430,7 +430,7 @@ module Utils
|
||||
responses: responses,
|
||||
}
|
||||
ensure
|
||||
file.unlink
|
||||
T.must(file).unlink
|
||||
end
|
||||
|
||||
def curl_supports_tls13?
|
||||
@ -547,7 +547,7 @@ module Utils
|
||||
return response unless response_text.match?(HTTP_STATUS_LINE_REGEX)
|
||||
|
||||
# Parse the status line and remove it
|
||||
match = response_text.match(HTTP_STATUS_LINE_REGEX)
|
||||
match = T.must(response_text.match(HTTP_STATUS_LINE_REGEX))
|
||||
response[:status_code] = match["code"] if match["code"].present?
|
||||
response[:status_text] = match["text"] if match["text"].present?
|
||||
response_text = response_text.sub(%r{^HTTP/.* (\d+).*$\s*}, "")
|
||||
|
||||
6
Library/Homebrew/utils/curl.rbi
Normal file
6
Library/Homebrew/utils/curl.rbi
Normal file
@ -0,0 +1,6 @@
|
||||
# typed: strict
|
||||
|
||||
module Utils::Curl
|
||||
include Kernel
|
||||
requires_ancestor { SystemCommand::Mixin }
|
||||
end
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/tty"
|
||||
@ -91,11 +91,11 @@ module Formatter
|
||||
end
|
||||
|
||||
fallback.call if objects.empty?
|
||||
fallback.call if respond_to?(:tty?) ? !tty? : !$stdout.tty?
|
||||
fallback.call if respond_to?(:tty?) ? !T.unsafe(self).tty? : !$stdout.tty?
|
||||
|
||||
console_width = Tty.width
|
||||
object_lengths = objects.map { |obj| Tty.strip_ansi(obj).length }
|
||||
cols = (console_width + gap_size) / (object_lengths.max + gap_size)
|
||||
cols = (console_width + gap_size) / (T.must(object_lengths.max) + gap_size)
|
||||
|
||||
fallback.call if cols < 2
|
||||
|
||||
@ -109,14 +109,14 @@ module Formatter
|
||||
output = +""
|
||||
|
||||
rows.times do |row_index|
|
||||
item_indices_for_row = row_index.step(objects.size - 1, rows).to_a
|
||||
item_indices_for_row = T.cast(row_index.step(objects.size - 1, rows).to_a, T::Array[Integer])
|
||||
|
||||
first_n = item_indices_for_row[0...-1].map do |index|
|
||||
objects[index] + "".rjust(col_width - object_lengths[index])
|
||||
first_n = T.must(item_indices_for_row[0...-1]).map do |index|
|
||||
objects[index] + "".rjust(col_width - object_lengths.fetch(index))
|
||||
end
|
||||
|
||||
# don't add trailing whitespace to last column
|
||||
last = objects.values_at(item_indices_for_row.last)
|
||||
last = objects.values_at(item_indices_for_row.fetch(-1))
|
||||
|
||||
output.concat((first_n + last)
|
||||
.join(gap_string))
|
||||
|
||||
5
Library/Homebrew/utils/formatter.rbi
Normal file
5
Library/Homebrew/utils/formatter.rbi
Normal file
@ -0,0 +1,5 @@
|
||||
# typed: strict
|
||||
|
||||
module Formatter
|
||||
include Kernel
|
||||
end
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "tempfile"
|
||||
@ -214,7 +214,7 @@ module GitHub
|
||||
|
||||
headers_tmpfile = Tempfile.new("github_api_headers", HOMEBREW_TEMP)
|
||||
begin
|
||||
if data
|
||||
if data_tmpfile
|
||||
data_tmpfile.write data
|
||||
data_tmpfile.close
|
||||
args += ["--data", "@#{data_tmpfile.path}"]
|
||||
@ -222,7 +222,7 @@ module GitHub
|
||||
args += ["--request", request_method.to_s] if request_method
|
||||
end
|
||||
|
||||
args += ["--dump-header", headers_tmpfile.path]
|
||||
args += ["--dump-header", T.must(headers_tmpfile.path)]
|
||||
|
||||
output, errors, status = curl_output("--location", url.to_s, *args, secrets: [token])
|
||||
output, _, http_code = output.rpartition("\n")
|
||||
|
||||
5
Library/Homebrew/utils/github/api.rbi
Normal file
5
Library/Homebrew/utils/github/api.rbi
Normal file
@ -0,0 +1,5 @@
|
||||
# typed: strict
|
||||
|
||||
module GitHub::API
|
||||
include Kernel
|
||||
end
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/curl"
|
||||
|
||||
6
Library/Homebrew/utils/repology.rbi
Normal file
6
Library/Homebrew/utils/repology.rbi
Normal file
@ -0,0 +1,6 @@
|
||||
# typed: strict
|
||||
|
||||
module Repology
|
||||
include Kernel
|
||||
requires_ancestor { Utils::Curl }
|
||||
end
|
||||
@ -653,9 +653,9 @@ class Version
|
||||
|
||||
private
|
||||
|
||||
sig { params(a: Integer, b: Integer).returns(Integer) }
|
||||
def max(a, b)
|
||||
(a > b) ? a : b
|
||||
sig { params(first: Integer, second: Integer).returns(Integer) }
|
||||
def max(first, second)
|
||||
(first > second) ? first : second
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Token]) }
|
||||
|
||||
@ -85,4 +85,4 @@ Flaky test detection and tracking is provided by [BuildPulse](https://buildpulse
|
||||
[](https://dnsimple.com/resolving/homebrew#gh-light-mode-only)
|
||||
[](https://dnsimple.com/resolving/homebrew#gh-dark-mode-only)
|
||||
|
||||
Homebrew is generously supported by [Custom Ink](https://github.com/customink), [Randy Reddig](https://github.com/ydnar), [Sentry](https://github.com/getsentry), [Codecademy](https://github.com/Codecademy), [Appwrite](https://github.com/appwrite), [embark-studios](https://github.com/embark-studios), [Agilend](https://github.com/Agilend), and many other users and organisations via [GitHub Sponsors](https://github.com/sponsors/Homebrew).
|
||||
Homebrew is generously supported by [Custom Ink](https://github.com/customink), [Randy Reddig](https://github.com/ydnar), [Sentry](https://github.com/getsentry), [Codecademy](https://github.com/Codecademy), [Appwrite](https://github.com/appwrite), [Mercedes-Benz Group](https://github.com/mercedes-benz), [embark-studios](https://github.com/embark-studios), [Agilend](https://github.com/Agilend), and many other users and organisations via [GitHub Sponsors](https://github.com/sponsors/Homebrew).
|
||||
|
||||
@ -1988,7 +1988,7 @@ _brew_upgrade() {
|
||||
'(--formula)--vst-plugindir[Target location for VST Plugins (default: `~/Library/Audio/Plug-Ins/VST`)]' \
|
||||
'(--formula)--vst3-plugindir[Target location for VST3 Plugins (default: `~/Library/Audio/Plug-Ins/VST3`)]' \
|
||||
- outdated_formula \
|
||||
'(--casks --binaries --require-sha --quarantine --skip-cask-deps --greedy --greedy-latest --greedy-auto-updates --appdir --colorpickerdir --prefpanedir --qlplugindir --mdimporterdir --dictionarydir --fontdir --servicedir --input-methoddir --internet-plugindir --audio-unit-plugindir --vst-plugindir --vst3-plugindir --screen-saverdir --language)--formula[Treat all named arguments as formulae. If no named arguments are specified, upgrade only outdated formulae]' \
|
||||
'(--casks --skip-cask-deps --greedy --greedy-latest --greedy-auto-updates --binaries --require-sha --quarantine --appdir --colorpickerdir --prefpanedir --qlplugindir --mdimporterdir --dictionarydir --fontdir --servicedir --input-methoddir --internet-plugindir --audio-unit-plugindir --vst-plugindir --vst3-plugindir --screen-saverdir --language)--formula[Treat all named arguments as formulae. If no named arguments are specified, upgrade only outdated formulae]' \
|
||||
'*::outdated_formula:__brew_outdated_formulae' \
|
||||
- outdated_cask \
|
||||
'(--formulae --build-from-source --interactive --force-bottle --fetch-HEAD --ignore-pinned --keep-tmp --debug-symbols --display-times)--cask[Treat all named arguments as casks. If no named arguments are specified, upgrade only outdated casks]' \
|
||||
|
||||
@ -755,12 +755,6 @@ upgraded formulae or, every 30 days, for all formulae.
|
||||
Print install times for each package at the end of the run.
|
||||
* `--cask`:
|
||||
Treat all named arguments as casks. If no named arguments are specified, upgrade only outdated casks.
|
||||
* `--[no-]binaries`:
|
||||
Disable/enable linking of helper executables (default: enabled).
|
||||
* `--require-sha`:
|
||||
Require all casks to have a checksum.
|
||||
* `--[no-]quarantine`:
|
||||
Disable/enable quarantining of downloads (default: enabled).
|
||||
* `--skip-cask-deps`:
|
||||
Skip installing cask dependencies.
|
||||
* `-g`, `--greedy`:
|
||||
@ -769,6 +763,12 @@ upgraded formulae or, every 30 days, for all formulae.
|
||||
Also include casks with `version :latest`.
|
||||
* `--greedy-auto-updates`:
|
||||
Also include casks with `auto_updates true`.
|
||||
* `--[no-]binaries`:
|
||||
Disable/enable linking of helper executables (default: enabled).
|
||||
* `--require-sha`:
|
||||
Require all casks to have a checksum.
|
||||
* `--[no-]quarantine`:
|
||||
Disable/enable quarantining of downloads (default: enabled).
|
||||
|
||||
### `uses` [*`options`*] *`formula`* [...]
|
||||
|
||||
|
||||
@ -1058,18 +1058,6 @@ Print install times for each package at the end of the run\.
|
||||
Treat all named arguments as casks\. If no named arguments are specified, upgrade only outdated casks\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-[no\-]binaries\fR
|
||||
Disable/enable linking of helper executables (default: enabled)\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-require\-sha\fR
|
||||
Require all casks to have a checksum\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-[no\-]quarantine\fR
|
||||
Disable/enable quarantining of downloads (default: enabled)\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-skip\-cask\-deps\fR
|
||||
Skip installing cask dependencies\.
|
||||
.
|
||||
@ -1085,6 +1073,18 @@ Also include casks with \fBversion :latest\fR\.
|
||||
\fB\-\-greedy\-auto\-updates\fR
|
||||
Also include casks with \fBauto_updates true\fR\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-[no\-]binaries\fR
|
||||
Disable/enable linking of helper executables (default: enabled)\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-require\-sha\fR
|
||||
Require all casks to have a checksum\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-[no\-]quarantine\fR
|
||||
Disable/enable quarantining of downloads (default: enabled)\.
|
||||
.
|
||||
.SS "\fBuses\fR [\fIoptions\fR] \fIformula\fR [\.\.\.]"
|
||||
Show formulae and casks that specify \fIformula\fR as a dependency; that is, show dependents of \fIformula\fR\. When given multiple formula arguments, show the intersection of formulae that use \fIformula\fR\. By default, \fBuses\fR shows all formulae and casks that specify \fIformula\fR as a required or recommended dependency for their stable builds\.
|
||||
.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user