2019-04-19 15:38:03 +09:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2015-08-03 13:09:07 +01:00
|
|
|
require "cxxstdlib"
|
|
|
|
require "formula"
|
|
|
|
require "keg"
|
|
|
|
require "tab"
|
2016-04-25 17:57:51 +01:00
|
|
|
require "utils/bottles"
|
2015-08-03 13:09:07 +01:00
|
|
|
require "caveats"
|
|
|
|
require "cleaner"
|
|
|
|
require "formula_cellar_checks"
|
|
|
|
require "install_renamed"
|
|
|
|
require "debrew"
|
|
|
|
require "sandbox"
|
2016-07-09 13:51:43 +01:00
|
|
|
require "emoji"
|
2016-07-29 20:31:32 -06:00
|
|
|
require "development_tools"
|
2018-05-15 12:49:48 -04:00
|
|
|
require "cache_store"
|
|
|
|
require "linkage_checker"
|
2018-06-11 20:45:06 -04:00
|
|
|
require "install"
|
2018-06-20 02:10:54 -04:00
|
|
|
require "messages"
|
2019-03-27 09:45:48 +00:00
|
|
|
require "cask/cask_loader"
|
2019-11-06 17:24:56 +00:00
|
|
|
require "find"
|
2009-10-26 18:13:38 +00:00
|
|
|
|
|
|
|
class FormulaInstaller
|
2013-07-15 19:28:10 -07:00
|
|
|
include FormulaCellarChecks
|
2017-06-26 07:30:28 +02:00
|
|
|
extend Predicable
|
2013-07-15 19:28:10 -07:00
|
|
|
|
2014-03-13 10:11:00 -05:00
|
|
|
def self.mode_attr_accessor(*names)
|
|
|
|
attr_accessor(*names)
|
2014-11-03 21:36:45 -06:00
|
|
|
private(*names)
|
2014-11-02 19:11:18 -06:00
|
|
|
names.each do |name|
|
|
|
|
predicate = "#{name}?"
|
2016-09-20 22:24:31 +02:00
|
|
|
define_method(predicate) do
|
|
|
|
send(name) ? true : false
|
|
|
|
end
|
2014-11-02 19:11:18 -06:00
|
|
|
private(predicate)
|
|
|
|
end
|
2014-03-13 10:11:00 -05:00
|
|
|
end
|
|
|
|
|
2014-10-29 22:38:49 -05:00
|
|
|
attr_reader :formula
|
2019-01-29 08:31:45 +00:00
|
|
|
attr_accessor :options, :build_bottle
|
2018-01-10 16:43:21 +00:00
|
|
|
attr_accessor :installed_as_dependency, :installed_on_request, :link_keg
|
2014-03-13 10:11:00 -05:00
|
|
|
mode_attr_accessor :show_summary_heading, :show_header
|
2018-03-15 13:37:34 +00:00
|
|
|
mode_attr_accessor :build_from_source, :force_bottle, :include_test
|
2014-11-03 21:34:41 -06:00
|
|
|
mode_attr_accessor :ignore_deps, :only_deps, :interactive, :git
|
2020-02-05 19:43:59 +00:00
|
|
|
mode_attr_accessor :verbose, :debug, :quiet
|
2009-10-26 18:13:38 +00:00
|
|
|
|
2014-10-29 22:38:49 -05:00
|
|
|
def initialize(formula)
|
|
|
|
@formula = formula
|
2017-07-30 21:44:43 +01:00
|
|
|
@link_keg = !formula.keg_only?
|
2012-08-22 19:49:17 -05:00
|
|
|
@show_header = false
|
2014-03-04 14:06:25 -06:00
|
|
|
@ignore_deps = false
|
|
|
|
@only_deps = false
|
2019-01-23 21:57:37 +00:00
|
|
|
@build_from_source = ARGV.build_from_source?
|
2017-08-05 17:51:26 +01:00
|
|
|
@build_bottle = false
|
2017-07-28 15:27:47 +01:00
|
|
|
@force_bottle = ARGV.force_bottle?
|
2018-03-15 13:37:34 +00:00
|
|
|
@include_test = ARGV.include?("--include-test")
|
2014-03-13 10:11:00 -05:00
|
|
|
@interactive = false
|
2014-11-03 21:34:41 -06:00
|
|
|
@git = false
|
2020-02-01 13:32:39 +01:00
|
|
|
@verbose = Homebrew.args.verbose?
|
2020-02-05 19:43:59 +00:00
|
|
|
@quiet = Homebrew.args.quiet?
|
2017-07-28 15:27:47 +01:00
|
|
|
@debug = ARGV.debug?
|
2017-01-09 21:07:55 +00:00
|
|
|
@installed_as_dependency = false
|
|
|
|
@installed_on_request = true
|
2013-01-23 00:26:28 -06:00
|
|
|
@options = Options.new
|
2016-11-20 19:45:33 +09:00
|
|
|
@requirement_messages = []
|
2013-12-12 15:42:31 -06:00
|
|
|
@poured_bottle = false
|
2018-04-07 20:28:56 +01:00
|
|
|
@pour_failed = false
|
|
|
|
@start_time = nil
|
2012-03-07 11:16:27 +00:00
|
|
|
end
|
|
|
|
|
2017-10-07 00:31:28 +02:00
|
|
|
def self.attempted
|
|
|
|
@attempted ||= Set.new
|
|
|
|
end
|
|
|
|
|
2019-03-27 09:45:48 +00:00
|
|
|
def self.clear_attempted
|
|
|
|
@attempted = Set.new
|
|
|
|
end
|
|
|
|
|
2015-08-12 14:57:54 -04:00
|
|
|
# When no build tools are available and build flags are passed through ARGV,
|
|
|
|
# it's necessary to interrupt the user before any sort of installation
|
|
|
|
# can proceed. Only invoked when the user has no developer tools.
|
2015-07-23 00:34:57 -04:00
|
|
|
def self.prevent_build_flags
|
|
|
|
build_flags = ARGV.collect_build_flags
|
2018-01-28 22:44:03 +00:00
|
|
|
return if build_flags.empty?
|
2015-07-23 00:34:57 -04:00
|
|
|
|
2018-01-28 22:44:03 +00:00
|
|
|
all_bottled = ARGV.formulae.all?(&:bottled?)
|
|
|
|
raise BuildFlagsError.new(build_flags, bottled: all_bottled)
|
2015-07-23 00:34:57 -04:00
|
|
|
end
|
|
|
|
|
2015-09-14 19:59:00 +08:00
|
|
|
def build_bottle?
|
2016-09-20 22:24:31 +02:00
|
|
|
return false unless @build_bottle
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-09-20 22:24:31 +02:00
|
|
|
!formula.bottle_disabled?
|
2015-09-14 19:59:00 +08:00
|
|
|
end
|
|
|
|
|
2016-09-17 15:32:44 +01:00
|
|
|
def pour_bottle?(install_bottle_options = { warn: false })
|
2013-11-14 15:25:56 -05:00
|
|
|
return false if @pour_failed
|
2014-10-29 22:38:49 -05:00
|
|
|
|
2017-09-25 11:37:07 -07:00
|
|
|
return false if !formula.bottled? && !formula.local_bottle_path
|
2016-01-09 11:07:07 +00:00
|
|
|
return true if force_bottle?
|
2015-07-24 16:06:26 +08:00
|
|
|
return false if build_from_source? || build_bottle? || interactive?
|
2015-11-19 07:54:27 -05:00
|
|
|
return false if ARGV.cc
|
2014-03-10 14:56:02 -05:00
|
|
|
return false unless options.empty?
|
2015-09-14 19:59:00 +08:00
|
|
|
return false if formula.bottle_disabled?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-01-09 11:07:40 +00:00
|
|
|
unless formula.pour_bottle?
|
|
|
|
if install_bottle_options[:warn] && formula.pour_bottle_check_unsatisfied_reason
|
2017-10-15 02:28:32 +02:00
|
|
|
opoo <<~EOS
|
2016-01-09 11:07:40 +00:00
|
|
|
Building #{formula.full_name} from source:
|
|
|
|
#{formula.pour_bottle_check_unsatisfied_reason}
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
2014-03-10 14:56:02 -05:00
|
|
|
|
2017-09-30 18:23:48 -07:00
|
|
|
bottle = formula.bottle_specification
|
|
|
|
unless bottle.compatible_cellar?
|
2014-03-10 14:56:02 -05:00
|
|
|
if install_bottle_options[:warn]
|
2017-10-15 02:28:32 +02:00
|
|
|
opoo <<~EOS
|
2016-01-09 11:07:28 +00:00
|
|
|
Building #{formula.full_name} from source:
|
2017-09-30 18:23:48 -07:00
|
|
|
The bottle needs a #{bottle.cellar} Cellar (yours is #{HOMEBREW_CELLAR}).
|
2016-01-09 11:07:28 +00:00
|
|
|
EOS
|
2014-03-10 14:56:02 -05:00
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2014-10-29 00:28:29 -05:00
|
|
|
def install_bottle_for?(dep, build)
|
2014-10-29 22:38:49 -05:00
|
|
|
return pour_bottle? if dep == formula
|
2016-10-16 19:10:46 -04:00
|
|
|
return false if ARGV.build_formula_from_source?(dep)
|
2016-01-19 10:14:59 +00:00
|
|
|
return false unless dep.bottle && dep.pour_bottle?
|
2014-03-10 14:56:02 -05:00
|
|
|
return false unless build.used_options.empty?
|
|
|
|
return false unless dep.bottle.compatible_cellar?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2015-08-03 13:09:07 +01:00
|
|
|
true
|
2013-01-23 00:26:27 -06:00
|
|
|
end
|
|
|
|
|
2014-03-04 14:06:25 -06:00
|
|
|
def prelude
|
2016-02-09 12:53:47 +08:00
|
|
|
Tab.clear_cache
|
2016-12-10 19:21:17 +00:00
|
|
|
verify_deps_exist unless ignore_deps?
|
2014-03-04 14:06:25 -06:00
|
|
|
lock
|
|
|
|
check_install_sanity
|
|
|
|
end
|
|
|
|
|
2014-02-28 11:16:55 -06:00
|
|
|
def verify_deps_exist
|
2014-06-17 00:04:21 -05:00
|
|
|
begin
|
2016-03-23 09:20:50 -07:00
|
|
|
compute_dependencies
|
2014-06-17 00:04:21 -05:00
|
|
|
rescue TapFormulaUnavailableError => e
|
2016-09-23 22:02:23 +02:00
|
|
|
raise if e.tap.installed?
|
|
|
|
|
|
|
|
e.tap.install
|
|
|
|
retry
|
2014-06-17 00:04:21 -05:00
|
|
|
end
|
2014-02-28 11:16:55 -06:00
|
|
|
rescue FormulaUnavailableError => e
|
2015-05-27 21:51:48 +08:00
|
|
|
e.dependent = formula.full_name
|
2014-02-28 11:16:55 -06:00
|
|
|
raise
|
|
|
|
end
|
|
|
|
|
2012-03-07 11:16:27 +00:00
|
|
|
def check_install_sanity
|
2017-10-07 00:31:28 +02:00
|
|
|
raise FormulaInstallationAlreadyAttemptedError, formula if self.class.attempted.include?(formula)
|
2013-01-08 19:54:32 -06:00
|
|
|
|
2016-12-10 19:21:17 +00:00
|
|
|
return if ignore_deps?
|
2016-09-04 00:01:01 +03:00
|
|
|
|
2016-09-23 22:02:23 +02:00
|
|
|
recursive_deps = formula.recursive_dependencies
|
2016-12-13 00:37:40 +00:00
|
|
|
recursive_formulae = recursive_deps.map(&:to_formula)
|
|
|
|
|
2017-02-21 21:29:32 +00:00
|
|
|
recursive_dependencies = []
|
|
|
|
recursive_formulae.each do |dep|
|
|
|
|
dep_recursive_dependencies = dep.recursive_dependencies.map(&:to_s)
|
|
|
|
if dep_recursive_dependencies.include?(formula.name)
|
|
|
|
recursive_dependencies << "#{formula.full_name} depends on #{dep.full_name}"
|
|
|
|
recursive_dependencies << "#{dep.full_name} depends on #{formula.full_name}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
unless recursive_dependencies.empty?
|
2017-10-15 02:28:32 +02:00
|
|
|
raise CannotInstallFormulaError, <<~EOS
|
2017-02-21 21:29:32 +00:00
|
|
|
#{formula.full_name} contains a recursive dependency on itself:
|
|
|
|
#{recursive_dependencies.join("\n ")}
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
|
2018-07-16 16:46:39 +01:00
|
|
|
if recursive_formulae.flat_map(&:recursive_dependencies)
|
|
|
|
.map(&:to_s)
|
|
|
|
.include?(formula.name)
|
2017-10-15 02:28:32 +02:00
|
|
|
raise CannotInstallFormulaError, <<~EOS
|
2017-02-21 21:29:32 +00:00
|
|
|
#{formula.full_name} contains a recursive dependency on itself!
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
|
2016-09-23 22:02:23 +02:00
|
|
|
pinned_unsatisfied_deps = recursive_deps.select do |dep|
|
|
|
|
dep.to_formula.pinned? && !dep.satisfied?(inherited_options_for(dep))
|
2012-08-19 17:36:10 -04:00
|
|
|
end
|
2016-09-23 22:02:23 +02:00
|
|
|
|
|
|
|
return if pinned_unsatisfied_deps.empty?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-09-23 22:02:23 +02:00
|
|
|
raise CannotInstallFormulaError,
|
2019-04-30 08:44:35 +01:00
|
|
|
"You must `brew unpin #{pinned_unsatisfied_deps * " "}` as installing " \
|
|
|
|
"#{formula.full_name} requires the latest version of pinned dependencies"
|
2009-10-26 18:13:38 +00:00
|
|
|
end
|
|
|
|
|
2013-10-05 20:32:05 +01:00
|
|
|
def build_bottle_preinstall
|
2019-11-06 17:24:56 +00:00
|
|
|
@etc_var_dirs ||= [HOMEBREW_PREFIX/"etc", HOMEBREW_PREFIX/"var"]
|
|
|
|
@etc_var_preinstall = Find.find(*@etc_var_dirs.select(&:directory?)).to_a
|
2013-10-05 20:32:05 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def build_bottle_postinstall
|
2019-11-06 17:24:56 +00:00
|
|
|
@etc_var_postinstall = Find.find(*@etc_var_dirs.select(&:directory?)).to_a
|
2013-10-05 20:32:05 +01:00
|
|
|
(@etc_var_postinstall - @etc_var_preinstall).each do |file|
|
2014-10-29 22:38:49 -05:00
|
|
|
Pathname.new(file).cp_path_sub(HOMEBREW_PREFIX, formula.bottle_prefix)
|
2013-10-05 20:32:05 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-08-23 23:30:52 +01:00
|
|
|
def install
|
2018-06-20 00:54:14 -04:00
|
|
|
start_time = Time.now
|
2018-06-11 10:38:32 -04:00
|
|
|
if !formula.bottle_unneeded? && !pour_bottle? && DevelopmentTools.installed?
|
2019-01-21 19:23:31 +00:00
|
|
|
Homebrew::Install.perform_build_from_source_checks
|
2018-06-11 00:45:25 -04:00
|
|
|
end
|
|
|
|
|
2012-03-07 11:16:27 +00:00
|
|
|
# not in initialize so upgrade can unlink the active keg before calling this
|
|
|
|
# function but after instantiating this class so that it can avoid having to
|
|
|
|
# relink the active keg if possible (because it is slow).
|
2014-10-29 22:38:49 -05:00
|
|
|
if formula.linked_keg.directory?
|
2017-10-15 02:28:32 +02:00
|
|
|
message = <<~EOS
|
2017-05-27 10:15:37 +01:00
|
|
|
#{formula.name} #{formula.linked_version} is already installed
|
2012-03-07 11:16:27 +00:00
|
|
|
EOS
|
2018-03-13 09:43:29 +00:00
|
|
|
if formula.outdated? && !formula.head?
|
|
|
|
message += <<~EOS
|
2019-04-08 12:47:15 -04:00
|
|
|
To upgrade to #{formula.pkg_version}, run `brew upgrade #{formula.name}`.
|
2017-04-25 12:45:37 +01:00
|
|
|
EOS
|
2018-03-13 09:43:29 +00:00
|
|
|
elsif only_deps?
|
|
|
|
message = nil
|
2017-04-25 12:45:37 +01:00
|
|
|
else
|
|
|
|
# some other version is already installed *and* linked
|
2018-03-13 09:43:29 +00:00
|
|
|
message += <<~EOS
|
2019-04-08 12:47:15 -04:00
|
|
|
To install #{formula.pkg_version}, first run `brew unlink #{formula.name}`.
|
2017-04-25 12:45:37 +01:00
|
|
|
EOS
|
|
|
|
end
|
2018-03-13 09:43:29 +00:00
|
|
|
raise CannotInstallFormulaError, message if message
|
2012-03-07 11:16:27 +00:00
|
|
|
end
|
2011-03-09 21:01:23 -08:00
|
|
|
|
2017-09-28 11:36:56 -07:00
|
|
|
# Warn if a more recent version of this formula is available in the tap.
|
|
|
|
begin
|
|
|
|
if formula.pkg_version < (v = Formulary.factory(formula.full_name).pkg_version)
|
|
|
|
opoo "#{formula.full_name} #{v} is available and more recent than version #{formula.pkg_version}."
|
|
|
|
end
|
|
|
|
rescue FormulaUnavailableError
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
2013-06-09 13:44:59 -05:00
|
|
|
check_conflicts
|
|
|
|
|
2019-02-19 13:11:32 +00:00
|
|
|
raise BuildToolsError, [formula] if !pour_bottle? && !formula.bottle_unneeded? && !DevelopmentTools.installed?
|
2015-06-29 14:09:57 -04:00
|
|
|
|
2016-12-10 19:21:17 +00:00
|
|
|
unless ignore_deps?
|
2015-06-23 19:21:55 -04:00
|
|
|
deps = compute_dependencies
|
2016-07-06 11:07:24 +01:00
|
|
|
check_dependencies_bottled(deps) if pour_bottle? && !DevelopmentTools.installed?
|
2015-06-23 19:21:55 -04:00
|
|
|
install_dependencies(deps)
|
|
|
|
end
|
2010-01-13 09:00:24 +00:00
|
|
|
|
2014-03-13 10:11:00 -05:00
|
|
|
return if only_deps?
|
2013-12-16 16:37:59 -08:00
|
|
|
|
2014-03-13 10:11:00 -05:00
|
|
|
if build_bottle? && (arch = ARGV.bottle_arch) && !Hardware::CPU.optimization_flags.include?(arch)
|
2013-08-25 14:57:26 -07:00
|
|
|
raise "Unrecognized architecture for --bottle-arch: #{arch}"
|
|
|
|
end
|
|
|
|
|
2014-12-27 14:26:56 -05:00
|
|
|
formula.deprecated_flags.each do |deprecated_option|
|
2014-10-16 13:02:04 +01:00
|
|
|
old_flag = deprecated_option.old_flag
|
|
|
|
new_flag = deprecated_option.current_flag
|
2015-05-27 21:51:48 +08:00
|
|
|
opoo "#{formula.full_name}: #{old_flag} was deprecated; using #{new_flag} instead!"
|
2014-10-16 13:02:04 +01:00
|
|
|
end
|
|
|
|
|
2017-06-09 14:53:01 +03:00
|
|
|
options = display_options(formula)
|
2019-02-19 13:11:32 +00:00
|
|
|
oh1 "Installing #{Formatter.identifier(formula.full_name)} #{options}".strip if show_header?
|
2011-08-23 23:30:52 +01:00
|
|
|
|
2017-09-24 20:12:58 +01:00
|
|
|
unless formula.tap&.private?
|
2017-06-09 14:53:01 +03:00
|
|
|
action = "#{formula.full_name} #{options}".strip
|
2017-06-07 16:34:54 +01:00
|
|
|
Utils::Analytics.report_event("install", action)
|
2017-01-09 21:07:55 +00:00
|
|
|
|
2019-02-19 13:11:32 +00:00
|
|
|
Utils::Analytics.report_event("install_on_request", action) if installed_on_request
|
2016-04-12 11:02:22 +01:00
|
|
|
end
|
2016-03-28 09:21:02 +01:00
|
|
|
|
2017-10-07 00:31:28 +02:00
|
|
|
self.class.attempted << formula
|
2013-01-13 15:39:50 -06:00
|
|
|
|
2016-12-10 17:58:41 +00:00
|
|
|
if pour_bottle?(warn: true)
|
2014-10-17 22:41:26 -05:00
|
|
|
begin
|
2013-02-18 07:28:06 +00:00
|
|
|
pour
|
2017-10-07 00:31:28 +02:00
|
|
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
2015-09-25 21:16:17 +08:00
|
|
|
# any exceptions must leave us with nothing installed
|
|
|
|
ignore_interrupts do
|
2019-05-24 16:46:54 +01:00
|
|
|
begin
|
|
|
|
formula.prefix.rmtree if formula.prefix.directory?
|
|
|
|
rescue Errno::EACCES, Errno::ENOTEMPTY
|
|
|
|
odie <<~EOS
|
|
|
|
Could not remove #{formula.prefix.basename} keg! Do so manually:
|
|
|
|
sudo rm -rf #{formula.prefix}
|
|
|
|
EOS
|
|
|
|
end
|
2015-09-25 21:16:17 +08:00
|
|
|
formula.rack.rmdir_if_possible
|
|
|
|
end
|
2019-01-12 12:08:18 +00:00
|
|
|
raise if ARGV.homebrew_developer? ||
|
|
|
|
e.is_a?(Interrupt) ||
|
|
|
|
ENV["HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK"]
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2014-10-17 22:41:26 -05:00
|
|
|
@pour_failed = true
|
|
|
|
onoe e.message
|
|
|
|
opoo "Bottle installation failed: building from source."
|
2016-09-17 15:17:27 +01:00
|
|
|
raise BuildToolsError, [formula] unless DevelopmentTools.installed?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-12-10 19:21:17 +00:00
|
|
|
compute_and_install_dependencies unless ignore_deps?
|
2014-10-17 22:41:26 -05:00
|
|
|
else
|
2013-03-11 18:56:26 +00:00
|
|
|
@poured_bottle = true
|
2013-02-18 07:28:06 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-12-10 17:58:41 +00:00
|
|
|
puts_requirement_messages
|
|
|
|
|
2014-03-13 10:11:00 -05:00
|
|
|
build_bottle_preinstall if build_bottle?
|
2013-10-05 20:32:05 +01:00
|
|
|
|
2013-03-11 18:56:26 +00:00
|
|
|
unless @poured_bottle
|
2011-08-23 23:30:52 +01:00
|
|
|
build
|
|
|
|
clean
|
2016-09-20 14:42:29 -07:00
|
|
|
|
|
|
|
# Store the formula used to build the keg in the keg.
|
2017-09-25 22:46:51 -07:00
|
|
|
formula_contents = if formula.local_bottle_path
|
|
|
|
Utils::Bottles.formula_contents formula.local_bottle_path, name: formula.name
|
|
|
|
else
|
|
|
|
formula.path.read
|
|
|
|
end
|
|
|
|
s = formula_contents.gsub(/ bottle do.+?end\n\n?/m, "")
|
2016-09-20 14:42:29 -07:00
|
|
|
brew_prefix = formula.prefix/".brew"
|
|
|
|
brew_prefix.mkdir
|
|
|
|
Pathname(brew_prefix/"#{formula.name}.rb").atomic_write(s)
|
2017-01-09 21:07:55 +00:00
|
|
|
|
|
|
|
keg = Keg.new(formula.prefix)
|
|
|
|
tab = Tab.for_keg(keg)
|
|
|
|
tab.installed_as_dependency = installed_as_dependency
|
|
|
|
tab.installed_on_request = installed_on_request
|
|
|
|
tab.write
|
2010-02-09 11:30:16 -08:00
|
|
|
end
|
2011-08-23 23:30:52 +01:00
|
|
|
|
2014-03-13 10:11:00 -05:00
|
|
|
build_bottle_postinstall if build_bottle?
|
2013-10-05 20:32:05 +01:00
|
|
|
|
2019-12-03 11:42:09 +00:00
|
|
|
opoo "Nothing was installed to #{formula.prefix}" unless formula.latest_version_installed?
|
2018-06-20 00:54:14 -04:00
|
|
|
end_time = Time.now
|
|
|
|
Homebrew.messages.formula_installed(formula, end_time - start_time)
|
2010-02-09 11:30:16 -08:00
|
|
|
end
|
|
|
|
|
2013-06-09 13:44:59 -05:00
|
|
|
def check_conflicts
|
2020-01-15 20:26:58 +05:30
|
|
|
return if Homebrew.args.force?
|
2013-06-09 13:44:59 -05:00
|
|
|
|
2014-11-13 22:56:31 +09:00
|
|
|
conflicts = formula.conflicts.select do |c|
|
2019-10-13 10:03:26 +01:00
|
|
|
f = Formulary.factory(c.name)
|
|
|
|
rescue TapFormulaUnavailableError
|
|
|
|
# If the formula name is a fully-qualified name let's silently
|
|
|
|
# ignore it as we don't care about things used in taps that aren't
|
|
|
|
# currently tapped.
|
|
|
|
false
|
|
|
|
rescue FormulaUnavailableError => e
|
|
|
|
# If the formula name doesn't exist any more then complain but don't
|
|
|
|
# stop installation from continuing.
|
|
|
|
opoo <<~EOS
|
2019-10-13 10:11:35 +01:00
|
|
|
#{formula}: #{e.message}
|
|
|
|
'conflicts_with \"#{c.name}\"' should be removed from #{formula.path.basename}.
|
2019-10-13 10:12:01 +01:00
|
|
|
EOS
|
2016-09-23 22:02:23 +02:00
|
|
|
|
2019-10-13 10:03:26 +01:00
|
|
|
raise if ARGV.homebrew_developer?
|
2016-09-23 22:02:23 +02:00
|
|
|
|
2020-03-11 10:57:36 +00:00
|
|
|
$stderr.puts "Please report this issue to the #{formula.tap} tap (not Homebrew/brew or Homebrew/core)!"
|
2019-10-13 10:03:26 +01:00
|
|
|
false
|
2019-10-16 19:10:52 +02:00
|
|
|
else # rubocop:disable Layout/ElseAlignment
|
2019-10-14 09:03:02 +01:00
|
|
|
f.linked_keg.exist? && f.opt_prefix.exist?
|
2013-06-09 13:44:59 -05:00
|
|
|
end
|
|
|
|
|
2014-10-29 22:38:49 -05:00
|
|
|
raise FormulaConflictError.new(formula, conflicts) unless conflicts.empty?
|
2013-06-09 13:44:59 -05:00
|
|
|
end
|
|
|
|
|
2015-08-12 14:57:54 -04:00
|
|
|
# Compute and collect the dependencies needed by the formula currently
|
|
|
|
# being installed.
|
2015-06-23 19:21:55 -04:00
|
|
|
def compute_dependencies
|
2013-12-09 14:36:10 -06:00
|
|
|
req_map, req_deps = expand_requirements
|
|
|
|
check_requirements(req_map)
|
2014-10-29 22:38:49 -05:00
|
|
|
deps = expand_dependencies(req_deps + formula.deps)
|
2013-12-09 14:36:10 -06:00
|
|
|
|
2015-06-23 19:21:55 -04:00
|
|
|
deps
|
|
|
|
end
|
|
|
|
|
2015-08-12 14:57:54 -04:00
|
|
|
# Check that each dependency in deps has a bottle available, terminating
|
|
|
|
# abnormally with a BuildToolsError if one or more don't.
|
|
|
|
# Only invoked when the user has no developer tools.
|
2015-06-23 19:21:55 -04:00
|
|
|
def check_dependencies_bottled(deps)
|
2015-10-19 18:11:25 +08:00
|
|
|
unbottled = deps.reject do |dep, _|
|
|
|
|
dep_f = dep.to_formula
|
|
|
|
dep_f.pour_bottle? || dep_f.bottle_unneeded?
|
|
|
|
end
|
2015-06-23 19:21:55 -04:00
|
|
|
|
2016-09-17 15:17:27 +01:00
|
|
|
raise BuildToolsError, unbottled unless unbottled.empty?
|
2015-06-23 19:21:55 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def compute_and_install_dependencies
|
|
|
|
deps = compute_dependencies
|
|
|
|
install_dependencies(deps)
|
2013-12-02 12:44:28 -06:00
|
|
|
end
|
|
|
|
|
2013-12-09 14:36:10 -06:00
|
|
|
def check_requirements(req_map)
|
2016-11-19 02:03:30 +09:00
|
|
|
@requirement_messages = []
|
2013-12-09 14:36:10 -06:00
|
|
|
fatals = []
|
|
|
|
|
|
|
|
req_map.each_pair do |dependent, reqs|
|
|
|
|
reqs.each do |req|
|
2017-12-09 14:23:34 +00:00
|
|
|
next if dependent.installed? && req.name == "maximummacos"
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-11-19 02:03:30 +09:00
|
|
|
@requirement_messages << "#{dependent}: #{req.message}"
|
2013-12-09 14:36:10 -06:00
|
|
|
fatals << req if req.fatal?
|
2013-01-27 23:57:34 -06:00
|
|
|
end
|
2013-01-23 00:26:24 -06:00
|
|
|
end
|
|
|
|
|
2016-11-19 02:03:30 +09:00
|
|
|
return if fatals.empty?
|
|
|
|
|
2016-11-20 19:45:33 +09:00
|
|
|
puts_requirement_messages
|
2016-11-19 02:03:30 +09:00
|
|
|
raise UnsatisfiedRequirements, fatals
|
2013-01-23 00:26:24 -06:00
|
|
|
end
|
|
|
|
|
2017-06-23 00:45:08 -07:00
|
|
|
def runtime_requirements(formula)
|
2018-07-16 16:46:39 +01:00
|
|
|
runtime_deps = formula.runtime_formula_dependencies(undeclared: false)
|
2017-06-23 00:45:08 -07:00
|
|
|
recursive_requirements = formula.recursive_requirements do |dependent, _|
|
|
|
|
Requirement.prune unless runtime_deps.include?(dependent)
|
|
|
|
end
|
|
|
|
(recursive_requirements.to_a + formula.requirements.to_a).reject(&:build?).uniq
|
|
|
|
end
|
|
|
|
|
2013-12-09 14:36:10 -06:00
|
|
|
def expand_requirements
|
|
|
|
unsatisfied_reqs = Hash.new { |h, k| h[k] = [] }
|
2018-07-05 20:51:44 +01:00
|
|
|
req_deps = []
|
2014-10-29 22:38:49 -05:00
|
|
|
formulae = [formula]
|
2018-07-05 20:51:44 +01:00
|
|
|
formula_deps_map = Dependency.expand(formula)
|
|
|
|
.each_with_object({}) do |dep, hash|
|
|
|
|
hash[dep.name] = dep
|
|
|
|
end
|
2013-12-09 14:36:10 -06:00
|
|
|
|
|
|
|
while f = formulae.pop
|
2017-06-23 00:45:08 -07:00
|
|
|
runtime_requirements = runtime_requirements(f)
|
2014-06-19 21:35:47 -05:00
|
|
|
f.recursive_requirements do |dependent, req|
|
|
|
|
build = effective_build_options_for(dependent)
|
2017-07-30 16:56:24 +01:00
|
|
|
install_bottle_for_dependent = install_bottle_for?(dependent, build)
|
2014-06-19 21:35:47 -05:00
|
|
|
|
2018-03-24 16:55:16 +00:00
|
|
|
if req.prune_from_option?(build)
|
2014-06-19 21:35:47 -05:00
|
|
|
Requirement.prune
|
2014-08-10 16:41:30 +01:00
|
|
|
elsif req.satisfied?
|
2014-07-06 17:22:56 +01:00
|
|
|
Requirement.prune
|
2018-03-15 13:37:34 +00:00
|
|
|
elsif include_test? && req.test?
|
|
|
|
next
|
2017-07-30 16:56:24 +01:00
|
|
|
elsif !runtime_requirements.include?(req) && install_bottle_for_dependent
|
2017-06-23 00:45:08 -07:00
|
|
|
Requirement.prune
|
2018-07-05 20:51:44 +01:00
|
|
|
elsif (dep = formula_deps_map[dependent.name]) && dep.build?
|
|
|
|
Requirement.prune
|
2014-06-19 21:35:47 -05:00
|
|
|
else
|
|
|
|
unsatisfied_reqs[dependent] << req
|
2013-12-09 14:36:10 -06:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-10-28 20:34:59 +08:00
|
|
|
# Merge the repeated dependencies, which may have different tags.
|
2018-07-05 20:51:44 +01:00
|
|
|
req_deps = Dependency.merge_repeats(req_deps)
|
2015-10-28 20:34:59 +08:00
|
|
|
|
2018-07-05 20:51:44 +01:00
|
|
|
[unsatisfied_reqs, req_deps]
|
2013-12-09 14:36:10 -06:00
|
|
|
end
|
|
|
|
|
2013-12-09 14:36:10 -06:00
|
|
|
def expand_dependencies(deps)
|
2016-06-02 02:09:35 -07:00
|
|
|
inherited_options = Hash.new { |hash, key| hash[key] = Options.new }
|
2018-06-22 16:56:37 -07:00
|
|
|
pour_bottle = pour_bottle?
|
2014-02-27 14:22:43 -06:00
|
|
|
|
2014-10-29 22:38:49 -05:00
|
|
|
expanded_deps = Dependency.expand(formula, deps) do |dependent, dep|
|
2016-06-02 02:09:35 -07:00
|
|
|
inherited_options[dep.name] |= inherited_options_for(dep)
|
2014-06-19 21:35:47 -05:00
|
|
|
build = effective_build_options_for(
|
|
|
|
dependent,
|
2017-02-12 15:06:54 +00:00
|
|
|
inherited_options.fetch(dependent.name, []),
|
2014-06-19 21:35:47 -05:00
|
|
|
)
|
|
|
|
|
2018-03-24 16:55:16 +00:00
|
|
|
if dep.prune_from_option?(build)
|
2014-06-19 21:35:47 -05:00
|
|
|
Dependency.prune
|
2019-09-20 08:17:50 +01:00
|
|
|
elsif include_test? && dep.test? && !dep.installed?
|
|
|
|
Dependency.keep_but_prune_recursive_deps
|
2014-10-29 00:28:29 -05:00
|
|
|
elsif dep.build? && install_bottle_for?(dependent, build)
|
2014-06-19 21:35:47 -05:00
|
|
|
Dependency.prune
|
2018-03-24 16:55:16 +00:00
|
|
|
elsif dep.prune_if_build_and_not_dependent?(dependent)
|
2017-12-07 14:56:12 +00:00
|
|
|
Dependency.prune
|
2016-06-02 02:09:35 -07:00
|
|
|
elsif dep.satisfied?(inherited_options[dep.name])
|
2014-06-19 21:35:47 -05:00
|
|
|
Dependency.skip
|
2019-09-29 23:29:49 -07:00
|
|
|
else
|
|
|
|
pour_bottle ||= install_bottle_for?(dep.to_formula, build)
|
2013-06-03 22:50:11 -05:00
|
|
|
end
|
2013-01-23 00:26:25 -06:00
|
|
|
end
|
2014-02-27 14:22:43 -06:00
|
|
|
|
2018-10-01 16:36:03 -07:00
|
|
|
if pour_bottle && !Keg.bottle_dependencies.empty?
|
|
|
|
bottle_deps = if !Keg.bottle_dependencies.include?(formula.name)
|
|
|
|
Keg.bottle_dependencies
|
|
|
|
elsif !Keg.relocation_formulae.include?(formula.name)
|
|
|
|
Keg.relocation_formulae
|
|
|
|
else
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
bottle_deps = bottle_deps.map { |formula| Dependency.new(formula) }
|
|
|
|
.reject do |dep|
|
2018-06-22 16:56:37 -07:00
|
|
|
inherited_options[dep.name] |= inherited_options_for(dep)
|
|
|
|
dep.satisfied? inherited_options[dep.name]
|
|
|
|
end
|
2018-10-01 16:36:03 -07:00
|
|
|
expanded_deps = Dependency.merge_repeats(bottle_deps + expanded_deps)
|
2018-06-22 16:56:37 -07:00
|
|
|
end
|
|
|
|
|
2014-08-24 16:14:16 -05:00
|
|
|
expanded_deps.map { |dep| [dep, inherited_options[dep.name]] }
|
2014-02-27 14:22:43 -06:00
|
|
|
end
|
|
|
|
|
2015-08-03 13:09:07 +01:00
|
|
|
def effective_build_options_for(dependent, inherited_options = [])
|
2014-08-11 17:48:30 -05:00
|
|
|
args = dependent.build.used_options
|
2017-05-29 18:24:52 +01:00
|
|
|
args |= (dependent == formula) ? options : inherited_options
|
2014-08-24 14:46:34 -05:00
|
|
|
args |= Tab.for_formula(dependent).used_options
|
2016-01-09 12:00:35 +00:00
|
|
|
args &= dependent.options
|
2014-08-11 17:48:30 -05:00
|
|
|
BuildOptions.new(args, dependent.options)
|
2014-03-02 14:02:18 -06:00
|
|
|
end
|
|
|
|
|
2017-06-09 14:53:01 +03:00
|
|
|
def display_options(formula)
|
|
|
|
options = []
|
|
|
|
if formula.head?
|
|
|
|
options << "--HEAD"
|
|
|
|
elsif formula.devel?
|
|
|
|
options << "--devel"
|
|
|
|
end
|
|
|
|
options += effective_build_options_for(formula).used_options.to_a
|
|
|
|
return if options.empty?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2017-06-09 14:53:01 +03:00
|
|
|
options.join(" ")
|
|
|
|
end
|
|
|
|
|
2014-03-02 14:02:17 -06:00
|
|
|
def inherited_options_for(dep)
|
2014-04-04 10:12:09 -05:00
|
|
|
inherited_options = Options.new
|
2014-07-31 19:37:39 -05:00
|
|
|
u = Option.new("universal")
|
2014-10-29 22:38:49 -05:00
|
|
|
if (options.include?(u) || formula.require_universal_deps?) && !dep.build? && dep.to_formula.option_defined?(u)
|
2014-07-31 19:37:39 -05:00
|
|
|
inherited_options << u
|
2014-03-01 18:54:00 -06:00
|
|
|
end
|
2014-04-04 10:12:09 -05:00
|
|
|
inherited_options
|
2013-01-23 00:26:25 -06:00
|
|
|
end
|
|
|
|
|
2013-12-09 14:36:10 -06:00
|
|
|
def install_dependencies(deps)
|
2015-06-23 19:21:55 -04:00
|
|
|
if deps.empty? && only_deps?
|
|
|
|
puts "All dependencies for #{formula.full_name} are satisfied."
|
2016-08-10 09:29:20 -04:00
|
|
|
elsif !deps.empty?
|
2018-09-02 16:15:09 +01:00
|
|
|
oh1 "Installing dependencies for #{formula.full_name}: " \
|
2018-09-17 20:11:11 +02:00
|
|
|
"#{deps.map(&:first).map(&Formatter.method(:identifier)).to_sentence}",
|
2018-09-02 16:15:09 +01:00
|
|
|
truncate: false
|
2015-06-23 19:21:55 -04:00
|
|
|
deps.each { |dep, options| install_dependency(dep, options) }
|
2013-10-16 15:34:43 -05:00
|
|
|
end
|
|
|
|
|
2013-12-09 14:36:10 -06:00
|
|
|
@show_header = true unless deps.empty?
|
2013-01-23 00:26:25 -06:00
|
|
|
end
|
|
|
|
|
2014-02-27 14:22:43 -06:00
|
|
|
def install_dependency(dep, inherited_options)
|
2014-02-27 14:22:42 -06:00
|
|
|
df = dep.to_formula
|
2014-04-05 10:48:54 -05:00
|
|
|
tab = Tab.for_formula(df)
|
2013-01-23 00:26:27 -06:00
|
|
|
|
2014-04-05 10:48:54 -05:00
|
|
|
if df.linked_keg.directory?
|
2014-04-05 12:17:19 -05:00
|
|
|
linked_keg = Keg.new(df.linked_keg.resolved_path)
|
2017-07-30 21:44:43 +01:00
|
|
|
keg_had_linked_keg = true
|
2017-07-30 20:04:41 +01:00
|
|
|
keg_was_linked = linked_keg.linked?
|
2014-04-05 10:48:54 -05:00
|
|
|
linked_keg.unlink
|
|
|
|
end
|
|
|
|
|
|
|
|
if df.installed?
|
|
|
|
installed_keg = Keg.new(df.prefix)
|
|
|
|
tmp_keg = Pathname.new("#{installed_keg}.tmp")
|
|
|
|
installed_keg.rename(tmp_keg)
|
|
|
|
end
|
2012-03-07 13:48:04 +00:00
|
|
|
|
2018-11-10 12:04:26 +00:00
|
|
|
tab_tap = tab.source["tap"]
|
2019-09-25 10:46:06 +01:00
|
|
|
if tab_tap.present? && df.tap.present? && df.tap.to_s != tab_tap.to_s
|
2018-11-10 12:04:26 +00:00
|
|
|
odie <<~EOS
|
|
|
|
#{df} is already installed from #{tab_tap}!
|
|
|
|
Please `brew uninstall #{df}` first."
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
|
2016-12-10 19:21:17 +00:00
|
|
|
fi = FormulaInstaller.new(df)
|
2018-01-09 16:37:59 +00:00
|
|
|
fi.options |= tab.used_options
|
|
|
|
fi.options |= Tab.remap_deprecated_options(df.deprecated_options, dep.options)
|
|
|
|
fi.options |= inherited_options
|
|
|
|
fi.options &= df.options
|
|
|
|
fi.build_from_source = ARGV.build_formula_from_source?(df)
|
|
|
|
fi.force_bottle = false
|
|
|
|
fi.verbose = verbose?
|
2020-02-05 19:43:59 +00:00
|
|
|
fi.quiet = quiet?
|
2018-01-09 16:37:59 +00:00
|
|
|
fi.debug = debug?
|
2018-01-10 16:43:21 +00:00
|
|
|
fi.link_keg ||= keg_was_linked if keg_had_linked_keg
|
2017-01-09 21:07:55 +00:00
|
|
|
fi.installed_as_dependency = true
|
2018-01-09 16:37:59 +00:00
|
|
|
fi.installed_on_request = df.any_version_installed? && tab.installed_on_request
|
2014-03-04 14:06:25 -06:00
|
|
|
fi.prelude
|
2016-08-30 21:38:13 +02:00
|
|
|
oh1 "Installing #{formula.full_name} dependency: #{Formatter.identifier(dep.name)}"
|
2011-11-26 21:03:46 -08:00
|
|
|
fi.install
|
|
|
|
fi.finish
|
2019-12-04 09:08:22 +00:00
|
|
|
rescue FormulaInstallationAlreadyAttemptedError
|
|
|
|
# We already attempted to install f as part of the dependency tree of
|
|
|
|
# another formula. In that case, don't generate an error, just move on.
|
|
|
|
nil
|
2017-10-07 00:31:28 +02:00
|
|
|
rescue Exception # rubocop:disable Lint/RescueException
|
2014-04-05 10:48:54 -05:00
|
|
|
ignore_interrupts do
|
|
|
|
tmp_keg.rename(installed_keg) if tmp_keg && !installed_keg.directory?
|
2017-07-28 17:47:10 +01:00
|
|
|
linked_keg.link if keg_was_linked
|
2014-04-05 10:48:54 -05:00
|
|
|
end
|
2014-04-05 10:48:54 -05:00
|
|
|
raise
|
|
|
|
else
|
2017-09-24 19:24:46 +01:00
|
|
|
ignore_interrupts { tmp_keg.rmtree if tmp_keg&.directory? }
|
2011-11-26 21:03:46 -08:00
|
|
|
end
|
|
|
|
|
2011-08-23 23:30:52 +01:00
|
|
|
def caveats
|
2014-03-13 10:11:00 -05:00
|
|
|
return if only_deps?
|
2013-12-16 16:37:59 -08:00
|
|
|
|
2018-02-14 03:38:38 -08:00
|
|
|
audit_installed if ARGV.homebrew_developer?
|
2012-07-18 03:22:00 -05:00
|
|
|
|
2017-06-26 07:30:28 +02:00
|
|
|
caveats = Caveats.new(formula)
|
2013-01-12 13:08:29 -06:00
|
|
|
|
2017-06-26 07:30:28 +02:00
|
|
|
return if caveats.empty?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-09-23 22:02:23 +02:00
|
|
|
@show_summary_heading = true
|
2017-06-26 07:30:28 +02:00
|
|
|
ohai "Caveats", caveats.to_s
|
2018-06-20 02:10:54 -04:00
|
|
|
Homebrew.messages.record_caveats(formula, caveats)
|
2011-08-23 23:30:52 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def finish
|
2014-03-13 10:11:00 -05:00
|
|
|
return if only_deps?
|
2013-12-16 16:37:59 -08:00
|
|
|
|
2015-08-03 13:09:07 +01:00
|
|
|
ohai "Finishing up" if verbose?
|
2011-08-23 23:30:52 +01:00
|
|
|
|
2013-06-30 11:16:53 -07:00
|
|
|
install_plist
|
|
|
|
|
2014-10-29 22:38:49 -05:00
|
|
|
keg = Keg.new(formula.prefix)
|
2014-07-24 19:39:09 -05:00
|
|
|
link(keg)
|
2015-06-05 22:42:56 -04:00
|
|
|
|
2019-02-19 13:11:32 +00:00
|
|
|
fix_dynamic_linkage(keg) unless @poured_bottle && formula.bottle_specification.skip_relocation?
|
2011-08-23 23:30:52 +01:00
|
|
|
|
2017-05-03 09:00:17 +01:00
|
|
|
if build_bottle?
|
|
|
|
ohai "Not running post_install as we're building a bottle"
|
|
|
|
puts "You can run it manually using `brew postinstall #{formula.full_name}`"
|
|
|
|
else
|
|
|
|
post_install
|
2014-11-23 13:43:35 +00:00
|
|
|
end
|
2013-12-05 10:09:14 -06:00
|
|
|
|
2018-05-15 12:49:48 -04:00
|
|
|
# Updates the cache for a particular formula after doing an install
|
2018-05-22 14:46:14 +01:00
|
|
|
CacheStoreDatabase.use(:linkage) do |db|
|
|
|
|
break unless db.created?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2018-06-06 13:27:59 +01:00
|
|
|
LinkageChecker.new(keg, formula, cache_db: db, rebuild_cache: true)
|
2018-05-15 12:49:48 -04:00
|
|
|
end
|
|
|
|
|
2018-06-01 13:29:46 +01:00
|
|
|
# Update tab with actual runtime dependencies
|
|
|
|
tab = Tab.for_keg(keg)
|
|
|
|
Tab.clear_cache
|
2018-06-01 20:39:39 +01:00
|
|
|
f_runtime_deps = formula.runtime_dependencies(read_from_tab: false)
|
|
|
|
tab.runtime_dependencies = Tab.runtime_deps_hash(f_runtime_deps)
|
2018-06-01 13:29:46 +01:00
|
|
|
tab.write
|
|
|
|
|
2015-09-08 16:24:09 +08:00
|
|
|
# let's reset Utils.git_available? if we just installed git
|
|
|
|
Utils.clear_git_available_cache if formula.name == "git"
|
2017-09-16 12:41:08 +01:00
|
|
|
|
|
|
|
# use installed curl when it's needed and available
|
|
|
|
if formula.name == "curl" &&
|
|
|
|
!DevelopmentTools.curl_handles_most_https_certificates?
|
|
|
|
ENV["HOMEBREW_CURL"] = formula.opt_bin/"curl"
|
|
|
|
end
|
2018-06-01 13:29:46 +01:00
|
|
|
|
|
|
|
caveats
|
|
|
|
|
|
|
|
ohai "Summary" if verbose? || show_summary_heading?
|
|
|
|
puts summary
|
2013-06-11 15:35:30 -05:00
|
|
|
ensure
|
2015-07-17 16:08:49 +08:00
|
|
|
unlock
|
2009-10-26 18:13:38 +00:00
|
|
|
end
|
2010-07-20 21:03:25 -07:00
|
|
|
|
2013-12-12 15:42:31 -06:00
|
|
|
def summary
|
2019-04-20 14:07:29 +09:00
|
|
|
s = +""
|
2016-07-09 13:51:43 +01:00
|
|
|
s << "#{Emoji.install_badge} " if Emoji.enabled?
|
2016-12-31 16:38:05 +00:00
|
|
|
s << "#{formula.prefix.resolved_path}: #{formula.prefix.abv}"
|
2013-12-12 15:42:31 -06:00
|
|
|
s << ", built in #{pretty_duration build_time}" if build_time
|
2019-04-18 17:33:02 +09:00
|
|
|
s.freeze
|
2013-12-12 15:42:31 -06:00
|
|
|
end
|
|
|
|
|
2011-08-23 23:30:52 +01:00
|
|
|
def build_time
|
2014-03-13 14:16:15 -05:00
|
|
|
@build_time ||= Time.now - @start_time if @start_time && !interactive?
|
2011-08-23 23:30:52 +01:00
|
|
|
end
|
2009-10-26 18:13:38 +00:00
|
|
|
|
2016-09-21 09:07:04 +02:00
|
|
|
def sanitized_argv_options
|
2014-03-13 10:10:59 -05:00
|
|
|
args = []
|
2014-03-13 19:10:41 -05:00
|
|
|
args << "--ignore-dependencies" if ignore_deps?
|
2014-03-13 10:10:59 -05:00
|
|
|
|
2014-03-13 10:11:00 -05:00
|
|
|
if build_bottle?
|
2014-03-13 10:10:59 -05:00
|
|
|
args << "--build-bottle"
|
|
|
|
args << "--bottle-arch=#{ARGV.bottle_arch}" if ARGV.bottle_arch
|
|
|
|
end
|
|
|
|
|
2014-11-03 21:34:41 -06:00
|
|
|
args << "--git" if git?
|
|
|
|
args << "--interactive" if interactive?
|
2014-03-13 10:11:00 -05:00
|
|
|
args << "--verbose" if verbose?
|
2014-03-13 10:11:00 -05:00
|
|
|
args << "--debug" if debug?
|
2014-03-13 10:10:59 -05:00
|
|
|
args << "--cc=#{ARGV.cc}" if ARGV.cc
|
2016-01-10 02:41:00 +01:00
|
|
|
args << "--default-fortran-flags" if ARGV.include? "--default-fortran-flags"
|
2016-04-10 22:53:56 -04:00
|
|
|
args << "--keep-tmp" if ARGV.keep_tmp?
|
2015-04-16 20:33:32 -04:00
|
|
|
|
|
|
|
if ARGV.env
|
|
|
|
args << "--env=#{ARGV.env}"
|
2016-09-13 12:36:56 -04:00
|
|
|
elsif formula.env.std? || formula.deps.select(&:build?).any? { |d| d.name == "scons" }
|
2015-04-16 20:33:32 -04:00
|
|
|
args << "--env=std"
|
|
|
|
end
|
2014-06-19 21:35:47 -05:00
|
|
|
|
2014-10-29 23:32:38 -05:00
|
|
|
if formula.head?
|
|
|
|
args << "--HEAD"
|
|
|
|
elsif formula.devel?
|
|
|
|
args << "--devel"
|
2014-06-19 21:35:47 -05:00
|
|
|
end
|
2014-04-26 19:09:49 -05:00
|
|
|
|
2014-10-29 22:38:49 -05:00
|
|
|
formula.options.each do |opt|
|
2016-07-21 14:08:06 +08:00
|
|
|
name = opt.name[/^([^=]+)=$/, 1]
|
2016-05-11 06:04:35 +02:00
|
|
|
value = ARGV.value(name) if name
|
|
|
|
args << "--#{name}=#{value}" if value
|
2014-04-26 19:09:49 -05:00
|
|
|
end
|
|
|
|
|
2014-03-08 16:54:19 -06:00
|
|
|
args
|
|
|
|
end
|
|
|
|
|
2013-01-23 00:26:28 -06:00
|
|
|
def build_argv
|
2016-09-21 09:07:04 +02:00
|
|
|
sanitized_argv_options + options.as_flags
|
2013-01-23 00:26:28 -06:00
|
|
|
end
|
|
|
|
|
2011-08-23 23:30:52 +01:00
|
|
|
def build
|
2015-04-25 22:07:06 -04:00
|
|
|
FileUtils.rm_rf(formula.logs)
|
2012-09-11 20:59:59 -04:00
|
|
|
|
2011-08-23 23:30:52 +01:00
|
|
|
@start_time = Time.now
|
2009-10-26 18:13:38 +00:00
|
|
|
|
|
|
|
# 1. formulae can modify ENV, so we must ensure that each
|
2010-11-09 12:57:41 +00:00
|
|
|
# installation has a pristine ENV when it starts, forking now is
|
2009-10-26 18:13:38 +00:00
|
|
|
# the easiest way to do this
|
2013-04-05 17:42:53 -05:00
|
|
|
args = %W[
|
|
|
|
nice #{RUBY_PATH}
|
|
|
|
-W0
|
2018-07-17 14:23:33 +02:00
|
|
|
-I #{$LOAD_PATH.join(File::PATH_SEPARATOR)}
|
2013-04-05 17:42:53 -05:00
|
|
|
--
|
2014-08-26 22:06:43 -05:00
|
|
|
#{HOMEBREW_LIBRARY_PATH}/build.rb
|
2016-09-05 22:13:55 +01:00
|
|
|
#{formula.specified_path}
|
2013-04-05 17:42:53 -05:00
|
|
|
].concat(build_argv)
|
|
|
|
|
2015-04-13 18:02:46 +08:00
|
|
|
Utils.safe_fork do
|
2016-08-14 17:35:06 +01:00
|
|
|
if Sandbox.formula?(formula)
|
2015-04-13 18:05:15 +08:00
|
|
|
sandbox = Sandbox.new
|
2015-04-25 22:07:06 -04:00
|
|
|
formula.logs.mkpath
|
2016-05-27 01:53:08 -04:00
|
|
|
sandbox.record_log(formula.logs/"build.sandbox.log")
|
2017-05-09 20:00:11 +01:00
|
|
|
sandbox.allow_write_path(ENV["HOME"]) if ARGV.interactive?
|
2015-04-13 18:05:15 +08:00
|
|
|
sandbox.allow_write_temp_and_cache
|
|
|
|
sandbox.allow_write_log(formula)
|
2018-07-01 23:35:29 +02:00
|
|
|
sandbox.allow_cvs
|
|
|
|
sandbox.allow_fossil
|
2015-08-25 17:34:52 +01:00
|
|
|
sandbox.allow_write_xcode
|
2015-04-13 18:05:15 +08:00
|
|
|
sandbox.allow_write_cellar(formula)
|
2015-04-13 18:02:46 +08:00
|
|
|
sandbox.exec(*args)
|
2015-04-08 14:15:38 +08:00
|
|
|
else
|
2015-04-13 18:02:46 +08:00
|
|
|
exec(*args)
|
2015-04-08 14:15:38 +08:00
|
|
|
end
|
2012-08-10 16:04:56 -04:00
|
|
|
end
|
|
|
|
|
2016-07-13 10:11:59 +03:00
|
|
|
formula.update_head_version
|
|
|
|
|
2019-02-19 13:11:32 +00:00
|
|
|
raise "Empty installation" if !formula.prefix.directory? || Keg.new(formula.prefix).empty_installation?
|
2017-10-07 00:31:28 +02:00
|
|
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
2018-08-17 22:42:37 -04:00
|
|
|
if e.is_a? BuildError
|
|
|
|
e.formula = formula
|
|
|
|
e.options = options
|
|
|
|
end
|
|
|
|
|
2012-08-10 16:04:56 -04:00
|
|
|
ignore_interrupts do
|
|
|
|
# any exceptions must leave us with nothing installed
|
2016-07-13 10:11:59 +03:00
|
|
|
formula.update_head_version
|
2014-10-29 22:38:49 -05:00
|
|
|
formula.prefix.rmtree if formula.prefix.directory?
|
|
|
|
formula.rack.rmdir_if_possible
|
2010-11-09 12:57:41 +00:00
|
|
|
end
|
2018-08-17 22:42:37 -04:00
|
|
|
raise e
|
2009-10-26 18:13:38 +00:00
|
|
|
end
|
2011-08-23 23:30:52 +01:00
|
|
|
|
2014-07-24 19:39:09 -05:00
|
|
|
def link(keg)
|
2017-07-30 21:44:43 +01:00
|
|
|
unless link_keg
|
2014-07-24 19:39:09 -05:00
|
|
|
begin
|
|
|
|
keg.optlink
|
2019-11-05 20:34:06 +00:00
|
|
|
Formula.clear_cache
|
2014-07-24 19:39:09 -05:00
|
|
|
rescue Keg::LinkError => e
|
2014-10-29 22:38:49 -05:00
|
|
|
onoe "Failed to create #{formula.opt_prefix}"
|
2015-05-27 21:51:48 +08:00
|
|
|
puts "Things that depend on #{formula.full_name} will probably not build."
|
2014-07-24 19:39:09 -05:00
|
|
|
puts e
|
2014-10-27 13:16:18 +00:00
|
|
|
Homebrew.failed = true
|
2014-07-24 19:39:09 -05:00
|
|
|
end
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2019-01-25 20:10:02 +00:00
|
|
|
cask_installed_with_formula_name = begin
|
|
|
|
Cask::CaskLoader.load(formula.name).installed?
|
2019-02-11 15:11:19 -08:00
|
|
|
rescue Cask::CaskUnavailableError, Cask::CaskInvalidError
|
2019-01-25 20:10:02 +00:00
|
|
|
false
|
|
|
|
end
|
|
|
|
|
|
|
|
if cask_installed_with_formula_name
|
|
|
|
ohai "#{formula.name} cask is installed, skipping link."
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2014-06-27 16:20:17 -05:00
|
|
|
if keg.linked?
|
2012-02-21 11:40:06 +00:00
|
|
|
opoo "This keg was marked linked already, continuing anyway"
|
2014-06-27 16:20:17 -05:00
|
|
|
keg.remove_linked_keg_record
|
2012-02-21 11:40:06 +00:00
|
|
|
end
|
|
|
|
|
2015-09-05 14:36:50 +08:00
|
|
|
link_overwrite_backup = {} # Hash: conflict file -> backup file
|
2015-08-23 16:35:51 +08:00
|
|
|
backup_dir = HOMEBREW_CACHE/"Backup"
|
|
|
|
|
2012-08-22 15:50:27 -04:00
|
|
|
begin
|
|
|
|
keg.link
|
2014-06-27 16:10:42 -05:00
|
|
|
rescue Keg::ConflictError => e
|
2015-08-23 16:35:51 +08:00
|
|
|
conflict_file = e.dst
|
|
|
|
if formula.link_overwrite?(conflict_file) && !link_overwrite_backup.key?(conflict_file)
|
|
|
|
backup_file = backup_dir/conflict_file.relative_path_from(HOMEBREW_PREFIX).to_s
|
|
|
|
backup_file.parent.mkpath
|
|
|
|
conflict_file.rename backup_file
|
|
|
|
link_overwrite_backup[conflict_file] = backup_file
|
|
|
|
retry
|
|
|
|
end
|
2012-08-22 15:50:27 -04:00
|
|
|
onoe "The `brew link` step did not complete successfully"
|
|
|
|
puts "The formula built, but is not symlinked into #{HOMEBREW_PREFIX}"
|
2014-06-27 16:10:42 -05:00
|
|
|
puts e
|
2013-06-23 16:32:31 -07:00
|
|
|
puts
|
|
|
|
puts "Possible conflicting files are:"
|
2016-09-17 15:32:44 +01:00
|
|
|
mode = OpenStruct.new(dry_run: true, overwrite: true)
|
2013-06-23 16:32:31 -07:00
|
|
|
keg.link(mode)
|
2012-08-22 15:50:27 -04:00
|
|
|
@show_summary_heading = true
|
2014-10-27 13:16:18 +00:00
|
|
|
Homebrew.failed = true
|
2014-06-27 16:10:42 -05:00
|
|
|
rescue Keg::LinkError => e
|
|
|
|
onoe "The `brew link` step did not complete successfully"
|
|
|
|
puts "The formula built, but is not symlinked into #{HOMEBREW_PREFIX}"
|
|
|
|
puts e
|
|
|
|
puts
|
|
|
|
puts "You can try again using:"
|
2014-10-29 22:38:49 -05:00
|
|
|
puts " brew link #{formula.name}"
|
2014-06-27 16:10:42 -05:00
|
|
|
@show_summary_heading = true
|
2014-10-27 13:16:18 +00:00
|
|
|
Homebrew.failed = true
|
2017-10-07 00:31:28 +02:00
|
|
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
2014-04-21 09:40:24 -05:00
|
|
|
onoe "An unexpected error occurred during the `brew link` step"
|
|
|
|
puts "The formula built, but is not symlinked into #{HOMEBREW_PREFIX}"
|
|
|
|
puts e
|
|
|
|
puts e.backtrace if debug?
|
|
|
|
@show_summary_heading = true
|
2015-08-23 16:35:51 +08:00
|
|
|
ignore_interrupts do
|
|
|
|
keg.unlink
|
2015-09-05 14:36:50 +08:00
|
|
|
link_overwrite_backup.each do |origin, backup|
|
|
|
|
origin.parent.mkpath
|
|
|
|
backup.rename origin
|
2015-08-23 16:35:51 +08:00
|
|
|
end
|
|
|
|
end
|
2014-10-27 13:16:18 +00:00
|
|
|
Homebrew.failed = true
|
2014-04-21 09:40:24 -05:00
|
|
|
raise
|
2012-08-22 15:50:27 -04:00
|
|
|
end
|
2015-08-23 16:35:51 +08:00
|
|
|
|
2016-09-23 22:02:23 +02:00
|
|
|
return if link_overwrite_backup.empty?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-09-23 22:02:23 +02:00
|
|
|
opoo "These files were overwritten during `brew link` step:"
|
|
|
|
puts link_overwrite_backup.keys
|
|
|
|
puts
|
|
|
|
puts "They have been backed up in #{backup_dir}"
|
|
|
|
@show_summary_heading = true
|
2011-08-23 23:30:52 +01:00
|
|
|
end
|
|
|
|
|
2012-09-11 20:57:41 -04:00
|
|
|
def install_plist
|
2014-10-29 22:38:49 -05:00
|
|
|
return unless formula.plist
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2014-10-29 22:38:49 -05:00
|
|
|
formula.plist_path.atomic_write(formula.plist)
|
|
|
|
formula.plist_path.chmod 0644
|
2015-03-23 01:14:21 +08:00
|
|
|
log = formula.var/"log"
|
|
|
|
log.mkpath if formula.plist.include? log.to_s
|
2017-10-07 00:31:28 +02:00
|
|
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
2014-03-25 23:45:49 -05:00
|
|
|
onoe "Failed to install plist file"
|
|
|
|
ohai e, e.backtrace if debug?
|
2014-10-27 13:16:18 +00:00
|
|
|
Homebrew.failed = true
|
2012-09-11 20:57:41 -04:00
|
|
|
end
|
|
|
|
|
2016-07-09 13:52:05 +01:00
|
|
|
def fix_dynamic_linkage(keg)
|
|
|
|
keg.fix_dynamic_linkage
|
2017-10-07 00:31:28 +02:00
|
|
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
2016-07-09 13:52:05 +01:00
|
|
|
onoe "Failed to fix install linkage"
|
2011-08-23 23:30:52 +01:00
|
|
|
puts "The formula built, but you may encounter issues using it or linking other"
|
2019-04-08 12:47:15 -04:00
|
|
|
puts "formulae against it."
|
2014-03-13 10:11:00 -05:00
|
|
|
ohai e, e.backtrace if debug?
|
2014-10-27 13:16:18 +00:00
|
|
|
Homebrew.failed = true
|
2011-08-23 23:30:52 +01:00
|
|
|
@show_summary_heading = true
|
|
|
|
end
|
|
|
|
|
|
|
|
def clean
|
2014-03-13 10:11:00 -05:00
|
|
|
ohai "Cleaning" if verbose?
|
2014-10-29 22:38:49 -05:00
|
|
|
Cleaner.new(formula).clean
|
2017-10-07 00:31:28 +02:00
|
|
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
2011-08-23 23:30:52 +01:00
|
|
|
opoo "The cleaning step did not complete successfully"
|
|
|
|
puts "Still, the installation was successful, so we will link it into your prefix"
|
2014-03-13 10:11:00 -05:00
|
|
|
ohai e, e.backtrace if debug?
|
2014-10-27 13:16:18 +00:00
|
|
|
Homebrew.failed = true
|
2011-08-23 23:30:52 +01:00
|
|
|
@show_summary_heading = true
|
|
|
|
end
|
|
|
|
|
2013-12-05 10:09:14 -06:00
|
|
|
def post_install
|
2018-05-12 13:52:40 +02:00
|
|
|
args = %W[
|
|
|
|
nice #{RUBY_PATH}
|
|
|
|
-W0
|
2018-07-17 14:23:33 +02:00
|
|
|
-I #{$LOAD_PATH.join(File::PATH_SEPARATOR)}
|
2018-05-12 13:52:40 +02:00
|
|
|
--
|
|
|
|
#{HOMEBREW_LIBRARY_PATH}/postinstall.rb
|
|
|
|
#{formula.path}
|
2019-12-28 14:48:34 +05:30
|
|
|
]
|
2018-05-12 13:52:40 +02:00
|
|
|
|
|
|
|
Utils.safe_fork do
|
|
|
|
if Sandbox.formula?(formula)
|
|
|
|
sandbox = Sandbox.new
|
|
|
|
formula.logs.mkpath
|
|
|
|
sandbox.record_log(formula.logs/"postinstall.sandbox.log")
|
|
|
|
sandbox.allow_write_temp_and_cache
|
|
|
|
sandbox.allow_write_log(formula)
|
|
|
|
sandbox.allow_write_xcode
|
|
|
|
sandbox.deny_write_homebrew_repository
|
|
|
|
sandbox.allow_write_cellar(formula)
|
2018-09-06 18:38:43 +01:00
|
|
|
Keg::KEG_LINK_DIRECTORIES.each do |dir|
|
2018-05-12 13:52:40 +02:00
|
|
|
sandbox.allow_write_path "#{HOMEBREW_PREFIX}/#{dir}"
|
|
|
|
end
|
|
|
|
sandbox.exec(*args)
|
|
|
|
else
|
|
|
|
exec(*args)
|
|
|
|
end
|
|
|
|
end
|
2017-10-07 00:31:28 +02:00
|
|
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
2013-12-05 10:09:14 -06:00
|
|
|
opoo "The post-install step did not complete successfully"
|
2015-05-27 21:51:48 +08:00
|
|
|
puts "You can try again using `brew postinstall #{formula.full_name}`"
|
2018-11-11 10:01:16 +00:00
|
|
|
ohai e, e.backtrace if debug? || ARGV.homebrew_developer?
|
2014-10-27 13:16:18 +00:00
|
|
|
Homebrew.failed = true
|
2013-12-05 10:09:14 -06:00
|
|
|
@show_summary_heading = true
|
|
|
|
end
|
|
|
|
|
2011-08-24 01:13:15 +01:00
|
|
|
def pour
|
2015-06-15 21:32:15 -04:00
|
|
|
if (bottle_path = formula.local_bottle_path)
|
|
|
|
downloader = LocalBottleDownloadStrategy.new(bottle_path)
|
2013-06-08 16:41:23 +01:00
|
|
|
else
|
2014-10-29 22:38:49 -05:00
|
|
|
downloader = formula.bottle
|
2019-06-15 17:22:45 +01:00
|
|
|
downloader.fetch
|
2013-06-08 16:41:23 +01:00
|
|
|
end
|
2019-06-15 17:22:45 +01:00
|
|
|
|
2011-08-24 01:13:15 +01:00
|
|
|
HOMEBREW_CELLAR.cd do
|
|
|
|
downloader.stage
|
|
|
|
end
|
2013-10-05 20:32:05 +01:00
|
|
|
|
2015-07-30 19:58:25 +08:00
|
|
|
keg = Keg.new(formula.prefix)
|
2016-10-25 03:41:35 -04:00
|
|
|
tab = Tab.for_keg(keg)
|
|
|
|
Tab.clear_cache
|
2016-10-09 19:43:55 -04:00
|
|
|
|
2016-10-25 03:41:35 -04:00
|
|
|
skip_linkage = formula.bottle_specification.skip_relocation?
|
|
|
|
keg.replace_placeholders_with_locations tab.changed_files, skip_linkage: skip_linkage
|
2015-07-30 19:58:25 +08:00
|
|
|
|
2016-10-10 12:02:12 -04:00
|
|
|
tab = Tab.for_keg(keg)
|
2015-06-27 20:04:45 -04:00
|
|
|
|
2014-10-17 22:40:03 -05:00
|
|
|
CxxStdlib.check_compatibility(
|
2014-10-29 22:38:49 -05:00
|
|
|
formula, formula.recursive_dependencies,
|
2015-06-27 20:04:45 -04:00
|
|
|
Keg.new(formula.prefix), tab.compiler
|
2014-10-17 22:40:03 -05:00
|
|
|
)
|
|
|
|
|
2015-05-26 14:15:14 +01:00
|
|
|
tab.tap = formula.tap
|
2014-10-17 22:40:03 -05:00
|
|
|
tab.poured_from_bottle = true
|
2015-12-15 14:21:27 +00:00
|
|
|
tab.time = Time.now.to_i
|
2016-07-02 09:44:48 +02:00
|
|
|
tab.head = HOMEBREW_REPOSITORY.git_head
|
2017-01-15 14:26:07 +00:00
|
|
|
tab.source["path"] = formula.specified_path.to_s
|
2017-01-09 21:07:55 +00:00
|
|
|
tab.installed_as_dependency = installed_as_dependency
|
|
|
|
tab.installed_on_request = installed_on_request
|
2017-07-21 17:20:54 +01:00
|
|
|
tab.aliases = formula.aliases
|
2014-10-17 22:40:03 -05:00
|
|
|
tab.write
|
2011-08-24 01:13:15 +01:00
|
|
|
end
|
|
|
|
|
2017-04-18 08:17:24 +01:00
|
|
|
def problem_if_output(output)
|
2016-09-23 22:02:23 +02:00
|
|
|
return unless output
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-09-23 22:02:23 +02:00
|
|
|
opoo output
|
|
|
|
@show_summary_heading = true
|
2012-02-26 16:33:44 -08:00
|
|
|
end
|
|
|
|
|
2014-10-13 23:13:01 -05:00
|
|
|
def audit_installed
|
2018-02-14 03:38:38 -08:00
|
|
|
unless formula.keg_only?
|
|
|
|
problem_if_output(check_env_path(formula.bin))
|
|
|
|
problem_if_output(check_env_path(formula.sbin))
|
|
|
|
end
|
2014-10-13 23:13:01 -05:00
|
|
|
super
|
2014-10-01 23:32:53 -05:00
|
|
|
end
|
|
|
|
|
2017-10-07 00:31:28 +02:00
|
|
|
def self.locked
|
|
|
|
@locked ||= []
|
|
|
|
end
|
|
|
|
|
2013-01-23 00:26:25 -06:00
|
|
|
private
|
|
|
|
|
2017-06-26 07:30:28 +02:00
|
|
|
attr_predicate :hold_locks?
|
2013-01-23 00:26:25 -06:00
|
|
|
|
|
|
|
def lock
|
2017-10-07 00:31:28 +02:00
|
|
|
return unless self.class.locked.empty?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2016-11-13 23:37:40 +01:00
|
|
|
unless ignore_deps?
|
|
|
|
formula.recursive_dependencies.each do |dep|
|
2017-10-07 00:31:28 +02:00
|
|
|
self.class.locked << dep.to_formula
|
2016-11-13 23:37:40 +01:00
|
|
|
end
|
|
|
|
end
|
2017-10-07 00:31:28 +02:00
|
|
|
self.class.locked.unshift(formula)
|
|
|
|
self.class.locked.uniq!
|
|
|
|
self.class.locked.each(&:lock)
|
2016-09-23 22:02:23 +02:00
|
|
|
@hold_locks = true
|
2013-01-23 00:26:25 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
def unlock
|
2016-09-23 22:02:23 +02:00
|
|
|
return unless hold_locks?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2017-10-07 00:31:28 +02:00
|
|
|
self.class.locked.each(&:unlock)
|
|
|
|
self.class.locked.clear
|
2016-09-23 22:02:23 +02:00
|
|
|
@hold_locks = false
|
2013-01-23 00:26:25 -06:00
|
|
|
end
|
2016-11-20 19:45:33 +09:00
|
|
|
|
|
|
|
def puts_requirement_messages
|
|
|
|
return unless @requirement_messages
|
|
|
|
return if @requirement_messages.empty?
|
2018-09-17 02:45:00 +02:00
|
|
|
|
2017-04-23 15:10:18 +01:00
|
|
|
$stderr.puts @requirement_messages
|
2016-11-20 19:45:33 +09:00
|
|
|
end
|
2011-08-23 23:30:52 +01:00
|
|
|
end
|