2015-08-03 13:09:07 +01:00
require " cxxstdlib "
require " exceptions "
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 " cmd/postinstall "
require " hooks/bottles "
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 "
2009-10-26 18:13:38 +00:00
class FormulaInstaller
2013-07-15 19:28:10 -07:00
include FormulaCellarChecks
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
2016-11-12 12:03:04 +00:00
attr_accessor :options , :build_bottle , :invalid_option_names
2014-03-13 10:11:00 -05:00
mode_attr_accessor :show_summary_heading , :show_header
2015-09-14 19:59:00 +08:00
mode_attr_accessor :build_from_source , :force_bottle
2014-11-03 21:34:41 -06:00
mode_attr_accessor :ignore_deps , :only_deps , :interactive , :git
2014-11-03 21:36:01 -06:00
mode_attr_accessor :verbose , :debug , :quieter
2009-10-26 18:13:38 +00:00
2014-10-29 22:38:49 -05:00
def initialize ( formula )
@formula = formula
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
2014-03-08 22:28:50 -06:00
@build_from_source = false
@build_bottle = false
2014-03-10 14:56:02 -05:00
@force_bottle = false
2014-03-13 10:11:00 -05:00
@interactive = false
2014-11-03 21:34:41 -06:00
@git = false
2014-03-13 10:11:00 -05:00
@verbose = false
2014-11-03 21:36:01 -06:00
@quieter = false
2014-03-13 10:11:00 -05:00
@debug = false
2013-01-23 00:26:28 -06:00
@options = Options . new
2016-11-12 12:03:04 +00:00
@invalid_option_names = [ ]
2016-11-20 19:45:33 +09:00
@requirement_messages = [ ]
2012-03-07 11:16:27 +00:00
2013-01-13 15:39:50 -06:00
@@attempted || = Set . new
2013-12-12 15:42:31 -06:00
@poured_bottle = false
@pour_failed = false
2012-03-07 11:16:27 +00:00
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
2016-09-17 15:17:27 +01:00
raise BuildFlagsError , build_flags unless build_flags . empty?
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
! 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 } )
2014-10-29 22:38:49 -05:00
return true if Homebrew :: Hooks :: Bottles . formula_has_bottle? ( formula )
2014-03-31 13:15:07 -05:00
2013-11-14 15:25:56 -05:00
return false if @pour_failed
2014-10-29 22:38:49 -05:00
bottle = formula . bottle
2016-01-09 11:07:07 +00:00
return false unless bottle
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?
2015-07-24 16:06:26 +08:00
return true if formula . local_bottle_path
2016-01-09 11:07:40 +00:00
unless formula . pour_bottle?
if install_bottle_options [ :warn ] && formula . pour_bottle_check_unsatisfied_reason
opoo <<-EOS.undent
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
2014-10-29 22:38:49 -05:00
unless bottle . compatible_cellar?
2014-03-10 14:56:02 -05:00
if install_bottle_options [ :warn ]
2016-01-09 11:07:28 +00:00
opoo <<-EOS.undent
Building #{formula.full_name} from source:
The bottle needs a #{bottle.cellar} Cellar (yours is #{HOMEBREW_CELLAR}).
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?
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
2014-10-29 22:38:49 -05:00
raise FormulaInstallationAlreadyAttemptedError , formula if @@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 )
version_hash = { }
version_conflicts = Set . new
recursive_formulae . each do | f |
name = f . name
unversioned_name , = name . split ( " @ " )
version_hash [ unversioned_name ] || = Set . new
version_hash [ unversioned_name ] << name
next if version_hash [ unversioned_name ] . length < 2
version_conflicts += version_hash [ unversioned_name ]
end
unless version_conflicts . empty?
raise CannotInstallFormulaError , " #{ formula . full_name } contains conflicting version dependencies ( #{ version_conflicts . to_a . join " " } ) so cannot be installed "
end
unlinked_deps = recursive_formulae . select do | dep |
2016-09-23 22:02:23 +02:00
dep . installed? && ! dep . keg_only? && ! dep . linked_keg . directory?
end
2016-09-04 00:01:01 +03:00
2016-09-23 22:02:23 +02:00
unless unlinked_deps . empty?
raise CannotInstallFormulaError , " You must `brew link #{ unlinked_deps * " " } ` before #{ formula . full_name } can be installed "
end
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?
raise CannotInstallFormulaError ,
" 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
@etc_var_glob || = " #{ HOMEBREW_PREFIX } /{etc,var}/**/* "
@etc_var_preinstall = Dir [ @etc_var_glob ]
end
def build_bottle_postinstall
@etc_var_postinstall = Dir [ @etc_var_glob ]
( @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
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?
2012-03-07 11:16:27 +00:00
# some other version is already installed *and* linked
raise CannotInstallFormulaError , <<-EOS.undent
2014-10-29 22:38:49 -05:00
#{formula.name}-#{formula.linked_keg.resolved_path.basename} already installed
2015-11-19 12:42:26 -08:00
To install this version , first ` brew unlink #{ formula . name } `
2012-03-07 11:16:27 +00:00
EOS
end
2011-03-09 21:01:23 -08:00
2013-06-09 13:44:59 -05:00
check_conflicts
2016-07-06 11:07:24 +01:00
if ! pour_bottle? && ! formula . bottle_unneeded? && ! DevelopmentTools . installed?
2016-09-17 15:17:27 +01:00
raise BuildToolsError , [ formula ]
2015-06-29 14:09:57 -04:00
end
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
2016-11-12 12:03:04 +00:00
invalid_option_names . each do | option |
opoo " #{ formula . full_name } : this formula has no #{ option } option so it will be ignored! "
2016-10-03 09:42:53 +01:00
end
2016-12-10 13:07:03 +00:00
options = [ ]
if formula . head?
options << " --HEAD "
elsif formula . devel?
options << " --devel "
end
options += effective_build_options_for ( formula ) . used_options . to_a
oh1 " Installing #{ Formatter . identifier ( formula . full_name ) } #{ options . join " " } " if show_header?
2011-08-23 23:30:52 +01:00
2016-04-12 11:02:22 +01:00
if formula . tap && ! formula . tap . private?
2016-08-08 09:56:12 +01:00
category = " install "
action = ( [ formula . full_name ] + options ) . join ( " " )
Utils :: Analytics . report_event ( category , action )
2016-04-12 11:02:22 +01:00
end
2016-03-28 09:21:02 +01:00
2014-10-29 22:38:49 -05:00
@@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
2015-09-25 21:16:17 +08:00
rescue Exception = > e
# any exceptions must leave us with nothing installed
ignore_interrupts do
formula . prefix . rmtree if formula . prefix . directory?
formula . rack . rmdir_if_possible
end
2015-11-17 23:41:03 +08:00
raise if ARGV . homebrew_developer? || e . is_a? ( Interrupt )
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?
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.
s = formula . path . read . gsub ( / bottle do.+?end \ n \ n? /m , " " )
brew_prefix = formula . prefix / " .brew "
brew_prefix . mkdir
Pathname ( brew_prefix / " #{ formula . name } .rb " ) . atomic_write ( s )
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
2014-10-29 22:38:49 -05:00
opoo " Nothing was installed to #{ formula . prefix } " unless formula . installed?
2010-02-09 11:30:16 -08:00
end
2013-06-09 13:44:59 -05:00
def check_conflicts
return if ARGV . force?
2014-11-13 22:56:31 +09:00
conflicts = formula . conflicts . select do | c |
2015-03-27 23:51:52 +08:00
begin
f = Formulary . factory ( c . name )
2015-05-03 13:15:40 +08:00
rescue TapFormulaUnavailableError
2016-08-08 09:31:49 +01:00
# If the formula name is a fully-qualified name let's silently
2015-03-27 23:51:52 +08:00
# ignore it as we don't care about things used in taps that aren't
# currently tapped.
2015-05-12 20:33:34 -04:00
false
2016-08-08 09:31:49 +01:00
rescue FormulaUnavailableError = > e
# If the formula name doesn't exist any more then complain but don't
# stop installation from continuing.
opoo <<-EOS.undent
#{formula}: #{e.message}
'conflicts_with \"#{c.name}\"' should be removed from #{formula.path.basename}.
EOS
2016-09-23 22:02:23 +02:00
raise if ARGV . homebrew_developer?
$stderr . puts " Please report this to the #{ formula . tap } tap! "
2016-08-08 09:31:49 +01:00
false
2015-05-12 20:33:34 -04:00
else
f . linked_keg . exist? && f . opt_prefix . exist?
2015-03-27 23:51:52 +08:00
end
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 |
2016-08-09 09:59:05 +01:00
next if dependent . installed?
2013-12-09 14:36:10 -06:00
reqs . each do | req |
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
2014-10-29 00:36:13 -05:00
def install_requirement_default_formula? ( req , dependent , build )
2014-07-06 17:22:56 +01:00
return false unless req . default_formula?
return true unless req . satisfied?
2015-12-15 05:36:05 +01:00
return false if req . run?
2014-10-29 00:36:13 -05:00
install_bottle_for? ( dependent , build ) || build_bottle?
2014-07-06 17:22:56 +01:00
end
2013-12-09 14:36:10 -06:00
def expand_requirements
unsatisfied_reqs = Hash . new { | h , k | h [ k ] = [ ] }
deps = [ ]
2014-10-29 22:38:49 -05:00
formulae = [ formula ]
2013-12-09 14:36:10 -06:00
while f = formulae . pop
2014-06-19 21:35:47 -05:00
f . recursive_requirements do | dependent , req |
build = effective_build_options_for ( dependent )
if ( req . optional? || req . recommended? ) && build . without? ( req )
Requirement . prune
2014-10-29 00:28:29 -05:00
elsif req . build? && install_bottle_for? ( dependent , build )
2014-06-19 21:35:47 -05:00
Requirement . prune
2014-10-29 00:36:13 -05:00
elsif install_requirement_default_formula? ( req , dependent , build )
2014-06-19 21:35:47 -05:00
dep = req . to_dependency
deps . unshift ( dep )
formulae . unshift ( dep . to_formula )
Requirement . prune
2014-08-10 16:41:30 +01:00
elsif req . satisfied?
2014-07-06 17:22:56 +01:00
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.
deps = Dependency . merge_repeats ( deps )
2015-08-03 13:09:07 +01:00
[ unsatisfied_reqs , 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 }
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 ,
inherited_options . fetch ( dependent . name , [ ] )
)
if ( dep . optional? || dep . recommended? ) && build . without? ( dep )
Dependency . prune
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
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
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
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
2014-10-29 22:38:49 -05: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
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?
2016-08-30 21:38:13 +02:00
oh1 " Installing dependencies for #{ formula . full_name } : #{ deps . map ( & :first ) . map ( & Formatter . method ( :identifier ) ) . join ( " , " ) } " ,
2016-09-17 15:32:44 +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 )
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
2016-12-10 19:21:17 +00:00
fi = FormulaInstaller . new ( df )
2014-04-05 10:48:54 -05:00
fi . options |= tab . used_options
2016-12-10 17:58:41 +00:00
fi . options |= Tab . remap_deprecated_options ( df . deprecated_options , dep . options )
2014-03-13 10:11:00 -05:00
fi . options |= inherited_options
2016-11-12 12:11:55 +00:00
fi . options & = df . options
2016-05-06 12:02:13 -07:00
fi . build_from_source = ARGV . build_formula_from_source? ( df )
2014-11-03 21:36:01 -06:00
fi . verbose = verbose? && ! quieter?
2014-03-13 10:11:00 -05:00
fi . debug = debug?
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
2014-04-05 10:48:54 -05:00
rescue Exception
2014-04-05 10:48:54 -05:00
ignore_interrupts do
tmp_keg . rename ( installed_keg ) if tmp_keg && ! installed_keg . directory?
linked_keg . link if linked_keg
end
2014-04-05 10:48:54 -05:00
raise
else
2014-04-05 10:48:54 -05:00
ignore_interrupts { tmp_keg . rmtree if tmp_keg && 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
2015-08-03 13:09:07 +01:00
audit_installed if ARGV . homebrew_developer? && ! formula . keg_only?
2012-07-18 03:22:00 -05:00
2014-10-29 22:38:49 -05:00
c = Caveats . new ( formula )
2013-01-12 13:08:29 -06:00
2016-09-23 22:02:23 +02:00
return if c . empty?
@show_summary_heading = true
ohai " Caveats " , c . 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
2015-08-22 14:19:16 +08:00
unless @poured_bottle && formula . bottle_specification . skip_relocation?
2016-07-09 13:52:05 +01:00
fix_dynamic_linkage ( keg )
2015-08-22 14:19:16 +08:00
end
2011-08-23 23:30:52 +01:00
2015-08-07 13:56:12 +08:00
if formula . post_install_defined?
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
end
2014-11-23 13:43:35 +00:00
end
2013-12-05 10:09:14 -06:00
2015-08-09 07:45:07 -04:00
caveats
2015-08-03 13:09:07 +01:00
ohai " Summary " if verbose? || show_summary_heading?
2013-12-12 15:42:31 -06:00
puts summary
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 "
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
s = " "
2016-07-09 13:51:43 +01:00
s << " #{ Emoji . install_badge } " if Emoji . enabled?
2014-10-29 22:38:49 -05:00
s << " #{ formula . prefix } : #{ formula . prefix . abv } "
2013-12-12 15:42:31 -06:00
s << " , built in #{ pretty_duration build_time } " if build_time
s
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
2015-04-28 22:37:27 -04:00
- I #{HOMEBREW_LOAD_PATH}
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 )
2016-08-14 17:35:06 +01:00
Sandbox . print_sandbox_message if Sandbox . formula? ( formula )
2015-07-21 14:47:37 +08:00
2015-04-13 18:02:46 +08:00
Utils . safe_fork do
2015-08-28 13:08:17 +08:00
# Invalidate the current sudo timestamp in case a build script calls sudo
system " /usr/bin/sudo " , " -k "
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 " )
2015-04-13 18:05:15 +08:00
sandbox . allow_write_temp_and_cache
sandbox . allow_write_log ( formula )
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
2016-01-09 18:59:34 +08:00
if ! formula . prefix . directory? || Keg . new ( formula . prefix ) . empty_installation?
2016-01-04 08:47:32 -08:00
raise " Empty installation "
end
2012-09-11 20:59:59 -04:00
2013-02-17 22:54:27 -06:00
rescue Exception
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
2012-08-10 16:04:56 -04:00
raise
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 )
2014-10-29 22:38:49 -05:00
if formula . keg_only?
2014-07-24 19:39:09 -05:00
begin
keg . optlink
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
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
2014-04-21 09:40:24 -05:00
rescue Exception = > e
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?
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
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
2014-03-25 23:45:49 -05:00
rescue Exception = > e
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
2011-08-23 23:30:52 +01:00
rescue Exception = > e
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 "
puts " formula 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
2011-08-23 23:30:52 +01:00
rescue Exception = > e
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
2015-04-13 18:16:27 +08:00
Homebrew . run_post_install ( formula )
2013-12-05 10:09:14 -06:00
rescue Exception = > e
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 } ` "
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
2013-12-05 10:09:14 -06:00
@show_summary_heading = true
end
2011-08-24 01:13:15 +01:00
def pour
2014-10-29 22:38:49 -05:00
if Homebrew :: Hooks :: Bottles . formula_has_bottle? ( formula )
return if Homebrew :: Hooks :: Bottles . pour_formula_bottle ( formula )
2014-03-31 13:15:07 -05:00
end
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
2014-07-22 19:11:09 -05:00
downloader . verify_download_integrity ( downloader . fetch )
2013-06-08 16:41:23 +01:00
end
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
2014-10-29 22:38:49 -05:00
Pathname . glob ( " #{ formula . bottle_prefix } /{etc,var}/**/* " ) do | path |
2013-10-05 20:32:05 +01:00
path . extend ( InstallRenamed )
2014-10-29 22:38:49 -05:00
path . cp_path_sub ( formula . bottle_prefix , HOMEBREW_PREFIX )
2013-10-05 20:32:05 +01:00
end
2014-10-29 22:38:49 -05:00
FileUtils . rm_rf formula . bottle_prefix
2014-10-17 22:40:03 -05: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
2014-10-17 22:40:03 -05:00
tab . write
2011-08-24 01:13:15 +01:00
end
2014-10-13 23:13:01 -05:00
def audit_check_output ( output )
2016-09-23 22:02:23 +02:00
return unless output
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
2016-09-21 09:07:04 +02:00
audit_check_output ( check_env_path ( formula . bin ) )
audit_check_output ( check_env_path ( formula . sbin ) )
2014-10-13 23:13:01 -05:00
super
2014-10-01 23:32:53 -05:00
end
2013-01-23 00:26:25 -06:00
private
def hold_locks?
@hold_locks || false
end
def lock
2016-09-23 22:02:23 +02:00
return unless ( @@locked || = [ ] ) . empty?
2016-11-13 23:37:40 +01:00
unless ignore_deps?
formula . recursive_dependencies . each do | dep |
@@locked << dep . to_formula
end
end
2016-09-23 22:02:23 +02:00
@@locked . unshift ( formula )
@@locked . uniq!
@@locked . each ( & :lock )
@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?
@@locked . each ( & :unlock )
@@locked . clear
@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?
puts @requirement_messages
end
2011-08-23 23:30:52 +01:00
end