2012-02-04 18:45:08 -08:00
|
|
|
require 'formula_support'
|
2013-02-09 18:19:50 -06:00
|
|
|
require 'formula_lock'
|
2013-03-11 16:41:08 +01:00
|
|
|
require 'formula_pin'
|
2012-02-25 15:22:32 -08:00
|
|
|
require 'hardware'
|
2012-03-07 21:30:03 -05:00
|
|
|
require 'bottles'
|
2012-03-18 13:58:13 -05:00
|
|
|
require 'compilers'
|
2012-09-14 07:54:14 -07:00
|
|
|
require 'build_environment'
|
2013-01-23 00:26:23 -06:00
|
|
|
require 'build_options'
|
2013-06-08 20:58:43 -07:00
|
|
|
require 'formulary'
|
2013-09-14 10:16:52 -05:00
|
|
|
require 'software_spec'
|
2013-10-06 22:04:46 +01:00
|
|
|
require 'install_renamed'
|
2014-03-05 20:12:51 -06:00
|
|
|
require 'pkg_version'
|
2012-04-05 21:09:24 -05:00
|
|
|
|
2009-08-21 20:20:44 +01:00
|
|
|
class Formula
|
2012-03-06 19:23:51 -06:00
|
|
|
include FileUtils
|
2013-07-11 21:55:02 -05:00
|
|
|
include Utils::Inreplace
|
2013-01-19 20:45:57 -06:00
|
|
|
extend BuildEnvironmentDSL
|
2010-07-04 14:17:03 -07:00
|
|
|
|
2014-02-20 13:45:13 -05:00
|
|
|
attr_reader :name, :path, :homepage, :build
|
2014-03-10 14:56:02 -05:00
|
|
|
attr_reader :stable, :devel, :head, :active_spec
|
2014-03-05 20:12:51 -06:00
|
|
|
attr_reader :pkg_version, :revision
|
2010-06-15 12:35:55 -07:00
|
|
|
|
2012-11-01 14:40:59 -05:00
|
|
|
# The current working directory during builds and tests.
|
|
|
|
# Will only be non-nil inside #stage and #test.
|
|
|
|
attr_reader :buildpath, :testpath
|
2012-02-24 12:50:21 -08:00
|
|
|
|
2013-09-25 18:51:30 -05:00
|
|
|
attr_accessor :local_bottle_path
|
|
|
|
|
2009-08-21 20:20:44 +01:00
|
|
|
# Homebrew determines the name
|
2014-02-21 20:07:41 -05:00
|
|
|
def initialize name='__UNKNOWN__', path=self.class.path(name)
|
2012-03-09 10:18:12 -08:00
|
|
|
@name = name
|
2014-02-21 20:07:41 -05:00
|
|
|
@path = path
|
2013-04-13 17:40:12 -05:00
|
|
|
@homepage = self.class.homepage
|
2014-03-05 20:12:51 -06:00
|
|
|
@revision = self.class.revision || 0
|
2013-04-13 17:40:12 -05:00
|
|
|
|
|
|
|
set_spec :stable
|
|
|
|
set_spec :devel
|
|
|
|
set_spec :head
|
2012-04-05 21:09:24 -05:00
|
|
|
|
2013-04-13 17:40:12 -05:00
|
|
|
@active_spec = determine_active_spec
|
|
|
|
validate_attributes :url, :name, :version
|
2013-09-21 19:27:24 -05:00
|
|
|
@build = determine_build_options
|
2014-03-10 14:56:02 -05:00
|
|
|
@pkg_version = PkgVersion.new(version, revision)
|
2013-03-11 16:41:08 +01:00
|
|
|
|
|
|
|
@pin = FormulaPin.new(self)
|
2012-04-05 21:09:24 -05:00
|
|
|
end
|
|
|
|
|
2013-04-13 17:40:12 -05:00
|
|
|
def set_spec(name)
|
|
|
|
spec = self.class.send(name)
|
2014-03-10 14:56:02 -05:00
|
|
|
if spec.url
|
2013-09-17 21:25:38 -05:00
|
|
|
spec.owner = self
|
2013-04-13 17:40:12 -05:00
|
|
|
instance_variable_set("@#{name}", spec)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def determine_active_spec
|
|
|
|
case
|
2014-04-06 15:56:00 -05:00
|
|
|
when head && ARGV.build_head? then head # --HEAD
|
|
|
|
when devel && ARGV.build_devel? then devel # --devel
|
|
|
|
when stable then stable
|
|
|
|
when devel then devel
|
|
|
|
when head then head # head-only
|
2013-04-13 17:40:14 -05:00
|
|
|
else
|
2013-04-27 14:44:48 -05:00
|
|
|
raise FormulaSpecificationError, "formulae require at least a URL"
|
2013-04-13 17:40:12 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def validate_attributes(*attrs)
|
|
|
|
attrs.each do |attr|
|
|
|
|
if (value = send(attr).to_s).empty? || value =~ /\s/
|
|
|
|
raise FormulaValidationError.new(attr, value)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-09-21 19:27:24 -05:00
|
|
|
def determine_build_options
|
|
|
|
build = active_spec.build
|
|
|
|
options.each { |opt, desc| build.add(opt, desc) }
|
|
|
|
build
|
2013-09-21 19:27:24 -05:00
|
|
|
end
|
|
|
|
|
2014-03-10 14:56:02 -05:00
|
|
|
def bottle
|
|
|
|
Bottle.new(self, active_spec.bottle_specification) if active_spec.bottled?
|
|
|
|
end
|
|
|
|
|
2013-04-13 17:40:12 -05:00
|
|
|
def url; active_spec.url; end
|
|
|
|
def version; active_spec.version; end
|
|
|
|
def mirrors; active_spec.mirrors; end
|
2012-04-05 21:09:24 -05:00
|
|
|
|
2013-08-06 19:52:58 -07:00
|
|
|
def resource(name)
|
2013-09-17 21:25:39 -05:00
|
|
|
active_spec.resource(name)
|
2013-08-06 19:52:58 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def resources
|
2013-09-17 21:25:39 -05:00
|
|
|
active_spec.resources.values
|
2013-08-06 19:52:58 -07:00
|
|
|
end
|
|
|
|
|
2013-09-21 19:27:24 -05:00
|
|
|
def deps
|
|
|
|
active_spec.deps
|
|
|
|
end
|
|
|
|
|
|
|
|
def requirements
|
|
|
|
active_spec.requirements
|
|
|
|
end
|
|
|
|
|
2014-02-21 00:41:07 -05:00
|
|
|
def cached_download
|
2014-02-21 00:41:07 -05:00
|
|
|
active_spec.cached_download
|
2014-02-21 00:41:07 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def clear_cache
|
2014-02-21 00:41:07 -05:00
|
|
|
active_spec.clear_cache
|
2014-02-21 00:41:07 -05:00
|
|
|
end
|
|
|
|
|
2014-03-13 19:51:23 -05:00
|
|
|
def patchlist
|
|
|
|
active_spec.patches
|
|
|
|
end
|
|
|
|
|
2009-07-24 15:10:01 +01:00
|
|
|
# if the dir is there, but it's empty we consider it not installed
|
|
|
|
def installed?
|
2013-04-09 19:40:08 -05:00
|
|
|
(dir = installed_prefix).directory? && dir.children.length > 0
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
|
|
|
|
2012-01-14 20:03:30 -06:00
|
|
|
def linked_keg
|
2013-04-15 15:00:57 -05:00
|
|
|
Pathname.new("#{HOMEBREW_LIBRARY}/LinkedKegs/#{name}")
|
2012-01-14 20:03:30 -06:00
|
|
|
end
|
|
|
|
|
2010-09-24 11:55:21 -05:00
|
|
|
def installed_prefix
|
2013-05-25 18:31:49 -05:00
|
|
|
if head && (head_prefix = prefix(head.version)).directory?
|
2010-09-24 11:55:21 -05:00
|
|
|
head_prefix
|
2013-05-25 18:31:49 -05:00
|
|
|
elsif devel && (devel_prefix = prefix(devel.version)).directory?
|
2012-04-05 21:09:24 -05:00
|
|
|
devel_prefix
|
2010-09-24 11:55:21 -05:00
|
|
|
else
|
|
|
|
prefix
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-08-18 18:37:32 -05:00
|
|
|
def installed_version
|
|
|
|
require 'keg'
|
|
|
|
Keg.new(installed_prefix).version
|
|
|
|
end
|
|
|
|
|
2014-03-05 20:51:37 -08:00
|
|
|
# The directory in the cellar that the formula is installed to.
|
|
|
|
# This directory contains the formula's name and version.
|
2014-03-05 20:12:51 -06:00
|
|
|
def prefix(v=pkg_version)
|
2013-05-25 18:31:49 -05:00
|
|
|
Pathname.new("#{HOMEBREW_CELLAR}/#{name}/#{v}")
|
2010-02-19 21:55:17 -08:00
|
|
|
end
|
2014-03-05 20:51:37 -08:00
|
|
|
# The parent of the prefix; the named directory in the cellar containing all
|
|
|
|
# installed versions of this software
|
2011-09-11 12:57:53 -07:00
|
|
|
def rack; prefix.parent end
|
2010-02-19 21:55:17 -08:00
|
|
|
|
2012-10-28 08:54:54 -07:00
|
|
|
def bin; prefix+'bin' end
|
|
|
|
def doc; share+'doc'+name end
|
|
|
|
def include; prefix+'include' end
|
|
|
|
def info; share+'info' end
|
|
|
|
def lib; prefix+'lib' end
|
|
|
|
def libexec; prefix+'libexec' end
|
|
|
|
def man; share+'man' end
|
|
|
|
def man1; man+'man1' end
|
|
|
|
def man2; man+'man2' end
|
|
|
|
def man3; man+'man3' end
|
|
|
|
def man4; man+'man4' end
|
|
|
|
def man5; man+'man5' end
|
|
|
|
def man6; man+'man6' end
|
|
|
|
def man7; man+'man7' end
|
|
|
|
def man8; man+'man8' end
|
|
|
|
def sbin; prefix+'sbin' end
|
|
|
|
def share; prefix+'share' end
|
2009-10-02 15:55:34 +01:00
|
|
|
|
2013-05-03 09:28:45 -07:00
|
|
|
def frameworks; prefix+'Frameworks' end
|
2013-04-21 10:44:24 +02:00
|
|
|
def kext_prefix; prefix+'Library/Extensions' end
|
|
|
|
|
2009-10-03 15:23:28 +01:00
|
|
|
# configuration needs to be preserved past upgrades
|
2013-10-05 20:39:51 +01:00
|
|
|
def etc; (HOMEBREW_PREFIX+'etc').extend(InstallRenamed) end
|
2013-10-06 22:04:46 +01:00
|
|
|
|
2010-07-04 14:17:03 -07:00
|
|
|
# generally we don't want var stuff inside the keg
|
|
|
|
def var; HOMEBREW_PREFIX+'var' end
|
2010-04-06 13:13:50 -07:00
|
|
|
|
2013-10-30 16:15:31 -07:00
|
|
|
def bash_completion; prefix+'etc/bash_completion.d' end
|
2013-01-27 22:34:26 +00:00
|
|
|
def zsh_completion; share+'zsh/site-functions' end
|
|
|
|
|
2013-10-05 20:29:19 +01:00
|
|
|
# for storing etc, var files for later copying from bottles
|
|
|
|
def bottle_prefix; prefix+'.bottle' end
|
|
|
|
|
2012-09-08 12:18:52 -07:00
|
|
|
# override this to provide a plist
|
2012-11-25 15:06:41 +00:00
|
|
|
def plist; nil; end
|
|
|
|
alias :startup_plist :plist
|
2011-12-30 23:56:52 -06:00
|
|
|
# plist name, i.e. the name of the launchd service
|
|
|
|
def plist_name; 'homebrew.mxcl.'+name end
|
|
|
|
def plist_path; prefix+(plist_name+'.plist') end
|
2012-11-25 15:06:41 +00:00
|
|
|
def plist_manual; self.class.plist_manual end
|
|
|
|
def plist_startup; self.class.plist_startup end
|
2011-12-30 23:56:52 -06:00
|
|
|
|
2014-03-05 20:51:37 -08:00
|
|
|
# A stable path for this formula, when installed. Contains the formula name
|
|
|
|
# but no version number. Only the active version will be linked here if
|
|
|
|
# multiple versions are installed.
|
|
|
|
#
|
|
|
|
# This is the prefered way to refer a formula in plists or from another
|
|
|
|
# formula, as the path is stable even when the software is updated.
|
2013-04-15 15:00:57 -05:00
|
|
|
def opt_prefix
|
|
|
|
Pathname.new("#{HOMEBREW_PREFIX}/opt/#{name}")
|
|
|
|
end
|
2012-08-10 16:33:22 -04:00
|
|
|
|
2014-03-05 21:01:24 -08:00
|
|
|
def opt_bin; opt_prefix+'bin' end
|
|
|
|
def opt_include; opt_prefix+'include' end
|
|
|
|
def opt_lib; opt_prefix+'lib' end
|
|
|
|
def opt_libexec; opt_prefix+'libexec' end
|
|
|
|
def opt_sbin; opt_prefix+'sbin' end
|
|
|
|
def opt_share; opt_prefix+'share' end
|
|
|
|
|
2013-01-27 19:22:56 +00:00
|
|
|
# Can be overridden to selectively disable bottles from formulae.
|
|
|
|
# Defaults to true so overridden version does not have to check if bottles
|
|
|
|
# are supported.
|
2013-02-11 20:24:06 -08:00
|
|
|
def pour_bottle?; true end
|
2013-01-27 19:22:56 +00:00
|
|
|
|
2013-04-01 20:33:12 +01:00
|
|
|
# Can be overridden to run commands on both source and bottle installation.
|
|
|
|
def post_install; end
|
|
|
|
|
2009-09-28 14:06:53 -07:00
|
|
|
# tell the user about any caveats regarding this package, return a string
|
2009-08-10 16:48:30 +01:00
|
|
|
def caveats; nil end
|
2009-09-28 14:06:53 -07:00
|
|
|
|
2011-06-21 22:28:29 +01:00
|
|
|
# any e.g. configure options for this package
|
2011-06-22 17:47:30 +01:00
|
|
|
def options; [] end
|
2011-06-21 22:28:29 +01:00
|
|
|
|
2014-03-13 19:51:23 -05:00
|
|
|
def patches; {} end
|
2009-09-28 14:06:53 -07:00
|
|
|
|
2009-09-17 21:10:39 +01:00
|
|
|
# rarely, you don't want your library symlinked into the main prefix
|
|
|
|
# see gettext.rb for an example
|
2010-07-18 10:38:45 -07:00
|
|
|
def keg_only?
|
2012-08-09 02:00:58 -05:00
|
|
|
kor = self.class.keg_only_reason
|
|
|
|
not kor.nil? and kor.valid?
|
|
|
|
end
|
|
|
|
|
|
|
|
def keg_only_reason
|
|
|
|
self.class.keg_only_reason
|
2010-07-18 10:38:45 -07:00
|
|
|
end
|
2009-08-10 16:48:30 +01:00
|
|
|
|
2012-03-18 13:58:13 -05:00
|
|
|
def fails_with? cc
|
|
|
|
cc = Compiler.new(cc) unless cc.is_a? Compiler
|
2013-03-13 02:07:01 -05:00
|
|
|
(self.class.cc_failures || []).any? do |failure|
|
2013-09-28 12:21:16 -07:00
|
|
|
# Major version check distinguishes between, e.g.,
|
|
|
|
# GCC 4.7.1 and GCC 4.8.2, where a comparison is meaningless
|
2014-02-24 23:26:11 -05:00
|
|
|
failure.compiler == cc.name && failure.major_version == cc.major_version &&
|
|
|
|
failure.version >= (cc.version || 0)
|
2011-08-26 17:08:42 +01:00
|
|
|
end
|
2011-03-21 14:23:28 -07:00
|
|
|
end
|
|
|
|
|
2014-02-23 12:21:43 -08:00
|
|
|
# sometimes the formula cleaner breaks things
|
2009-09-28 14:06:53 -07:00
|
|
|
# skip cleaning paths in a formula with a class method like this:
|
2014-02-23 12:21:43 -08:00
|
|
|
# skip_clean "bin/foo", "lib"bar"
|
|
|
|
# keep .la files with:
|
2014-02-23 12:09:28 -08:00
|
|
|
# skip_clean :la
|
2009-09-28 14:06:53 -07:00
|
|
|
def skip_clean? path
|
2012-09-09 10:01:59 -07:00
|
|
|
return true if path.extname == '.la' and self.class.skip_clean_paths.include? :la
|
2009-09-28 14:06:53 -07:00
|
|
|
to_check = path.relative_path_from(prefix).to_s
|
2009-11-23 10:07:23 -08:00
|
|
|
self.class.skip_clean_paths.include? to_check
|
2009-09-28 14:06:53 -07:00
|
|
|
end
|
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
# yields self with current working directory set to the uncompressed tarball
|
|
|
|
def brew
|
2013-04-13 17:40:12 -05:00
|
|
|
validate_attributes :name, :version
|
Dependency resolution
Specify dependencies in your formula's deps function. You can return an Array,
String or Hash, eg:
def deps
{ :optional => 'libogg', :required => %w[flac sdl], :recommended => 'cmake' }
end
Note currently the Hash is flattened and qualifications are ignored. If you
only return an Array or String, the qualification is assumed to be :required.
Other packaging systems have problems when it comes to packages requiring a
specific version of a package, or some patches that may not work well with
other software. With Homebrew we have some options:
1. If the formula is vanilla but an older version we can cherry-pick the old
version and install it in the Cellar in parallel, but just not symlink it
into /usr/local while forcing the formula that depends on it to link to
that one and not any other versions of it.
2. If the dependency requires patches then we shouldn't install this for use
by any other tools, (I guess this needs to be decided on a per-situation
basis). It can be installed into the parent formula's prefix, and not
symlinked into /usr/local. In this case the dependency's Formula
derivation should be saved in the parent formula's file (check git or
flac for an example of this).
Both the above can be done currently with hacks, so I'll flesh out a proper
way sometime this week.
2009-09-07 01:06:08 +01:00
|
|
|
|
2009-08-11 12:20:55 -07:00
|
|
|
stage do
|
2009-08-10 16:48:30 +01:00
|
|
|
begin
|
|
|
|
patch
|
2013-01-26 13:16:55 +00:00
|
|
|
# we allow formulae to do anything they want to the Ruby process
|
2009-09-04 15:28:18 +01:00
|
|
|
# so load any deps before this point! And exit asap afterwards
|
2009-08-10 16:48:30 +01:00
|
|
|
yield self
|
2013-02-17 22:54:27 -06:00
|
|
|
rescue RuntimeError, SystemCallError
|
2012-02-21 01:14:02 -06:00
|
|
|
%w(config.log CMakeCache.txt).each do |fn|
|
|
|
|
(HOMEBREW_LOGS/name).install(fn) if File.file?(fn)
|
2011-08-31 11:07:27 +01:00
|
|
|
end
|
2012-02-21 01:14:02 -06:00
|
|
|
raise
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
|
|
|
end
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
2009-08-10 16:48:30 +01:00
|
|
|
|
2013-01-23 00:26:25 -06:00
|
|
|
def lock
|
2013-02-09 18:19:50 -06:00
|
|
|
@lock = FormulaLock.new(name)
|
|
|
|
@lock.lock
|
2013-01-23 00:26:25 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
def unlock
|
2013-02-09 18:19:50 -06:00
|
|
|
@lock.unlock unless @lock.nil?
|
2013-01-23 00:26:25 -06:00
|
|
|
end
|
|
|
|
|
2013-05-21 22:41:21 -05:00
|
|
|
def pinnable?
|
|
|
|
@pin.pinnable?
|
|
|
|
end
|
|
|
|
|
|
|
|
def pinned?
|
|
|
|
@pin.pinned?
|
|
|
|
end
|
|
|
|
|
|
|
|
def pin
|
|
|
|
@pin.pin
|
|
|
|
end
|
|
|
|
|
|
|
|
def unpin
|
|
|
|
@pin.unpin
|
|
|
|
end
|
|
|
|
|
2013-10-04 21:19:15 -05:00
|
|
|
def == other
|
|
|
|
instance_of?(other.class) && name == other.name
|
2010-09-11 20:22:54 +01:00
|
|
|
end
|
2013-10-04 21:19:15 -05:00
|
|
|
alias_method :eql?, :==
|
|
|
|
|
2010-09-11 20:22:54 +01:00
|
|
|
def hash
|
|
|
|
name.hash
|
|
|
|
end
|
|
|
|
def <=> b
|
|
|
|
name <=> b.name
|
|
|
|
end
|
|
|
|
def to_s
|
|
|
|
name
|
|
|
|
end
|
2013-03-20 22:23:36 -05:00
|
|
|
def inspect
|
|
|
|
name
|
|
|
|
end
|
2010-09-11 20:22:54 +01:00
|
|
|
|
2010-09-22 08:05:58 -07:00
|
|
|
# Standard parameters for CMake builds.
|
|
|
|
# Using Build Type "None" tells cmake to use our CFLAGS,etc. settings.
|
|
|
|
# Setting it to Release would ignore our flags.
|
2012-05-29 16:58:32 -07:00
|
|
|
# Setting CMAKE_FIND_FRAMEWORK to "LAST" tells CMake to search for our
|
|
|
|
# libraries before trying to utilize Frameworks, many of which will be from
|
|
|
|
# 3rd party installs.
|
2010-09-22 08:05:58 -07:00
|
|
|
# Note: there isn't a std_autotools variant because autotools is a lot
|
|
|
|
# less consistent and the standard parameters are more memorable.
|
2012-05-22 16:32:12 -05:00
|
|
|
def std_cmake_args
|
2012-05-29 16:58:32 -07:00
|
|
|
%W[
|
|
|
|
-DCMAKE_INSTALL_PREFIX=#{prefix}
|
|
|
|
-DCMAKE_BUILD_TYPE=None
|
|
|
|
-DCMAKE_FIND_FRAMEWORK=LAST
|
2013-09-05 22:54:32 -07:00
|
|
|
-DCMAKE_VERBOSE_MAKEFILE=ON
|
2012-05-29 16:58:32 -07:00
|
|
|
-Wno-dev
|
|
|
|
]
|
2009-08-21 20:20:44 +01:00
|
|
|
end
|
|
|
|
|
2014-01-04 13:18:42 +00:00
|
|
|
# Deprecated
|
|
|
|
def python(options={}, &block)
|
|
|
|
opoo 'Formula#python is deprecated and will go away shortly.'
|
|
|
|
block.call if block_given?
|
|
|
|
PythonDependency.new
|
|
|
|
end
|
|
|
|
alias_method :python2, :python
|
|
|
|
alias_method :python3, :python
|
2013-01-21 10:33:56 +01:00
|
|
|
|
2009-09-11 14:22:46 +01:00
|
|
|
def self.class_s name
|
2014-02-21 00:43:58 -05:00
|
|
|
Formulary.class_s(name)
|
2009-08-21 20:20:44 +01:00
|
|
|
end
|
2010-03-09 02:18:08 +00:00
|
|
|
|
|
|
|
# an array of all Formula names
|
|
|
|
def self.names
|
2013-10-30 13:20:48 -07:00
|
|
|
Dir["#{HOMEBREW_LIBRARY}/Formula/*.rb"].map{ |f| File.basename f, '.rb' }.sort
|
2010-03-09 02:18:08 +00:00
|
|
|
end
|
|
|
|
|
2010-09-11 20:22:54 +01:00
|
|
|
def self.each
|
2012-08-21 11:39:45 -04:00
|
|
|
names.each do |name|
|
2013-04-14 23:29:15 -05:00
|
|
|
begin
|
2014-02-24 20:25:16 -08:00
|
|
|
yield Formulary.factory(name)
|
2013-06-26 13:02:44 -05:00
|
|
|
rescue StandardError => e
|
2011-03-11 14:54:26 -08:00
|
|
|
# Don't let one broken formula break commands. But do complain.
|
2012-08-21 11:39:45 -04:00
|
|
|
onoe "Failed to import: #{name}"
|
2013-06-26 13:02:44 -05:00
|
|
|
puts e
|
2012-08-21 11:39:45 -04:00
|
|
|
next
|
2010-07-18 14:07:40 -07:00
|
|
|
end
|
|
|
|
end
|
2010-09-11 20:22:54 +01:00
|
|
|
end
|
2012-08-21 11:39:45 -04:00
|
|
|
class << self
|
|
|
|
include Enumerable
|
|
|
|
end
|
2012-08-10 16:05:30 -04:00
|
|
|
|
|
|
|
def self.installed
|
2013-08-10 19:56:28 -05:00
|
|
|
return [] unless HOMEBREW_CELLAR.directory?
|
|
|
|
|
2013-08-27 10:25:23 +02:00
|
|
|
HOMEBREW_CELLAR.subdirs.map do |rack|
|
2013-06-29 21:35:57 -05:00
|
|
|
begin
|
2014-02-24 20:25:16 -08:00
|
|
|
Formulary.factory(rack.basename.to_s)
|
2013-06-29 21:35:57 -05:00
|
|
|
rescue FormulaUnavailableError
|
|
|
|
end
|
|
|
|
end.compact
|
2012-08-10 16:05:30 -04:00
|
|
|
end
|
|
|
|
|
2010-03-09 02:18:08 +00:00
|
|
|
def self.aliases
|
2013-10-30 13:20:48 -07:00
|
|
|
Dir["#{HOMEBREW_LIBRARY}/Aliases/*"].map{ |f| File.basename f }.sort
|
2009-11-16 15:35:58 -08:00
|
|
|
end
|
2009-08-21 20:20:44 +01:00
|
|
|
|
2011-05-07 19:29:54 -05:00
|
|
|
def self.canonical_name name
|
2014-04-05 22:03:34 -05:00
|
|
|
Formulary.canonical_name(name)
|
2010-09-22 12:32:16 -07:00
|
|
|
end
|
|
|
|
|
2014-02-24 20:25:16 -08:00
|
|
|
def self.[](name)
|
|
|
|
Formulary.factory(name)
|
|
|
|
end
|
|
|
|
|
|
|
|
# deprecated
|
2009-08-21 20:20:44 +01:00
|
|
|
def self.factory name
|
2013-06-08 20:58:43 -07:00
|
|
|
Formulary.factory name
|
2009-08-21 20:20:44 +01:00
|
|
|
end
|
|
|
|
|
2013-10-29 15:46:10 -04:00
|
|
|
def tap?
|
2014-04-06 00:31:07 -05:00
|
|
|
HOMEBREW_TAP_DIR_REGEX === path
|
2013-10-29 15:46:10 -04:00
|
|
|
end
|
|
|
|
|
2012-03-16 12:29:47 +00:00
|
|
|
def tap
|
2014-04-06 00:31:07 -05:00
|
|
|
if path.to_s =~ HOMEBREW_TAP_DIR_REGEX
|
2012-03-16 12:29:47 +00:00
|
|
|
"#$1/#$2"
|
2013-06-23 16:21:48 -07:00
|
|
|
elsif core_formula?
|
2013-12-14 18:15:59 +00:00
|
|
|
"Homebrew/homebrew"
|
2013-06-23 16:21:48 -07:00
|
|
|
else
|
|
|
|
"path or URL"
|
2012-03-16 12:29:47 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-06-23 16:15:11 -07:00
|
|
|
# True if this formula is provided by Homebrew itself
|
|
|
|
def core_formula?
|
2014-04-06 00:31:07 -05:00
|
|
|
path == Formula.path(name)
|
2013-06-23 16:15:11 -07:00
|
|
|
end
|
|
|
|
|
2009-08-21 20:20:44 +01:00
|
|
|
def self.path name
|
2013-10-30 13:20:48 -07:00
|
|
|
Pathname.new("#{HOMEBREW_LIBRARY}/Formula/#{name.downcase}.rb")
|
2009-08-21 20:20:44 +01:00
|
|
|
end
|
|
|
|
|
2012-09-14 07:54:14 -07:00
|
|
|
def env
|
2012-12-23 19:43:10 -06:00
|
|
|
@env ||= self.class.env
|
2012-09-14 07:54:14 -07:00
|
|
|
end
|
|
|
|
|
2012-08-07 14:22:20 -05:00
|
|
|
def conflicts
|
2013-06-09 13:44:59 -05:00
|
|
|
self.class.conflicts
|
2012-08-07 14:22:20 -05:00
|
|
|
end
|
|
|
|
|
2013-01-23 00:26:26 -06:00
|
|
|
# Returns a list of Dependency objects in an installable order, which
|
|
|
|
# means if a depends on b then b will be ordered before a in this list
|
|
|
|
def recursive_dependencies(&block)
|
|
|
|
Dependency.expand(self, &block)
|
2010-01-13 09:00:24 +00:00
|
|
|
end
|
|
|
|
|
2013-01-23 00:26:24 -06:00
|
|
|
# The full set of Requirements for this formula's dependency tree.
|
2013-01-30 17:55:04 -06:00
|
|
|
def recursive_requirements(&block)
|
|
|
|
Requirement.expand(self, &block)
|
2012-08-14 21:45:08 -05:00
|
|
|
end
|
|
|
|
|
2014-04-06 18:39:29 -05:00
|
|
|
# Flag for marking whether this formula needs C++ standard library
|
|
|
|
# compatibility check
|
|
|
|
def cxxstdlib
|
|
|
|
@cxxstdlib ||= Set.new
|
|
|
|
end
|
|
|
|
|
2012-08-15 22:08:40 -05:00
|
|
|
def to_hash
|
|
|
|
hsh = {
|
|
|
|
"name" => name,
|
|
|
|
"homepage" => homepage,
|
|
|
|
"versions" => {
|
|
|
|
"stable" => (stable.version.to_s if stable),
|
2013-05-05 10:55:39 -05:00
|
|
|
"bottle" => bottle ? true : false,
|
2012-08-15 22:08:40 -05:00
|
|
|
"devel" => (devel.version.to_s if devel),
|
|
|
|
"head" => (head.version.to_s if head)
|
|
|
|
},
|
2014-03-28 20:41:02 -05:00
|
|
|
"revision" => revision,
|
2012-08-15 22:08:40 -05:00
|
|
|
"installed" => [],
|
2014-04-05 12:17:19 -05:00
|
|
|
"linked_keg" => (linked_keg.resolved_path.basename.to_s if linked_keg.exist?),
|
2012-08-15 22:08:40 -05:00
|
|
|
"keg_only" => keg_only?,
|
2014-03-28 20:42:20 -05:00
|
|
|
"dependencies" => deps.map(&:name),
|
2013-06-09 15:20:09 -05:00
|
|
|
"conflicts_with" => conflicts.map(&:name),
|
2012-08-15 22:08:40 -05:00
|
|
|
"caveats" => caveats
|
|
|
|
}
|
|
|
|
|
2014-03-28 20:42:55 -05:00
|
|
|
hsh["options"] = build.map { |opt|
|
|
|
|
{ "option" => opt.flag, "description" => opt.description }
|
|
|
|
}
|
2012-08-15 22:08:40 -05:00
|
|
|
|
|
|
|
if rack.directory?
|
2014-04-20 00:03:18 -04:00
|
|
|
rack.subdirs.each do |keg_path|
|
|
|
|
keg = Keg.new keg_path
|
|
|
|
tab = Tab.for_keg keg_path
|
2012-08-15 22:08:40 -05:00
|
|
|
|
|
|
|
hsh["installed"] << {
|
2014-03-28 20:41:02 -05:00
|
|
|
"version" => keg.version.to_s,
|
2013-02-16 21:19:35 -06:00
|
|
|
"used_options" => tab.used_options.map(&:flag),
|
2013-03-15 00:28:18 +00:00
|
|
|
"built_as_bottle" => tab.built_bottle,
|
|
|
|
"poured_from_bottle" => tab.poured_from_bottle
|
2012-08-15 22:08:40 -05:00
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
hsh
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2013-06-05 09:47:08 -07:00
|
|
|
# For brew-fetch and others.
|
|
|
|
def fetch
|
2013-09-17 21:25:38 -05:00
|
|
|
active_spec.fetch
|
2013-06-05 09:47:08 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
# For FormulaInstaller.
|
|
|
|
def verify_download_integrity fn
|
|
|
|
active_spec.verify_download_integrity(fn)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test
|
2013-06-08 21:26:16 -05:00
|
|
|
require 'test/unit/assertions'
|
|
|
|
extend(Test::Unit::Assertions)
|
2013-06-13 15:52:23 +02:00
|
|
|
# Adding the used options allows us to use `build.with?` inside of tests
|
|
|
|
tab = Tab.for_name(name)
|
|
|
|
tab.used_options.each { |opt| build.args << opt unless build.has_opposite_of? opt }
|
2013-06-05 09:47:08 -07:00
|
|
|
ret = nil
|
|
|
|
mktemp do
|
|
|
|
@testpath = Pathname.pwd
|
|
|
|
ret = instance_eval(&self.class.test)
|
|
|
|
@testpath = nil
|
|
|
|
end
|
|
|
|
ret
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_defined?
|
|
|
|
not self.class.instance_variable_get(:@test_defined).nil?
|
|
|
|
end
|
|
|
|
|
2013-04-07 00:49:56 -05:00
|
|
|
protected
|
2012-03-04 16:48:00 -08:00
|
|
|
|
2009-07-24 15:10:01 +01:00
|
|
|
# Pretty titles the command and buffers stdout/stderr
|
|
|
|
# Throws if there's an error
|
2009-08-10 16:48:30 +01:00
|
|
|
def system cmd, *args
|
2014-02-22 21:39:38 -05:00
|
|
|
rd, wr = IO.pipe
|
2014-02-15 17:47:24 -05:00
|
|
|
|
2011-07-30 11:03:27 +01:00
|
|
|
# remove "boring" arguments so that the important ones are more likely to
|
|
|
|
# be shown considering that we trim long ohai lines to the terminal width
|
|
|
|
pretty_args = args.dup
|
2012-08-31 08:09:35 -04:00
|
|
|
if cmd == "./configure" and not ARGV.verbose?
|
|
|
|
pretty_args.delete "--disable-dependency-tracking"
|
|
|
|
pretty_args.delete "--disable-debug"
|
|
|
|
end
|
2011-07-07 18:06:21 +01:00
|
|
|
ohai "#{cmd} #{pretty_args*' '}".strip
|
2009-11-06 17:09:14 +00:00
|
|
|
|
2013-10-27 07:05:13 +01:00
|
|
|
@exec_count ||= 0
|
|
|
|
@exec_count += 1
|
|
|
|
logd = HOMEBREW_LOGS/name
|
2014-02-15 17:47:24 -05:00
|
|
|
logfn = "#{logd}/%02d.%s" % [@exec_count, File.basename(cmd).split(' ').first]
|
2013-10-27 07:05:13 +01:00
|
|
|
mkdir_p(logd)
|
|
|
|
|
2014-03-29 17:47:42 -05:00
|
|
|
pid = fork do
|
2013-11-17 11:53:55 -06:00
|
|
|
ENV['HOMEBREW_CC_LOG_PATH'] = logfn
|
2014-03-28 18:50:12 -05:00
|
|
|
|
|
|
|
# TODO system "xcodebuild" is deprecated, this should be removed soon.
|
|
|
|
if cmd.to_s.start_with? "xcodebuild"
|
|
|
|
ENV.remove_cc_etc
|
|
|
|
end
|
|
|
|
|
2014-03-28 18:55:20 -05:00
|
|
|
# Turn on argument filtering in the superenv compiler wrapper.
|
|
|
|
# We should probably have a better mechanism for this than adding
|
|
|
|
# special cases to this method.
|
|
|
|
if cmd == "python" && %w[setup.py build.py].include?(args.first)
|
|
|
|
ENV.refurbish_args
|
|
|
|
end
|
|
|
|
|
2013-10-27 07:05:13 +01:00
|
|
|
rd.close
|
|
|
|
$stdout.reopen wr
|
|
|
|
$stderr.reopen wr
|
|
|
|
args.collect!{|arg| arg.to_s}
|
2014-02-15 17:47:24 -05:00
|
|
|
exec(cmd, *args) rescue nil
|
2013-10-27 07:05:13 +01:00
|
|
|
puts "Failed to execute: #{cmd}"
|
|
|
|
exit! 1 # never gets here unless exec threw or failed
|
|
|
|
end
|
|
|
|
wr.close
|
2012-09-11 20:59:59 -04:00
|
|
|
|
2013-10-27 07:05:13 +01:00
|
|
|
File.open(logfn, 'w') do |f|
|
|
|
|
while buf = rd.gets
|
|
|
|
f.puts buf
|
|
|
|
puts buf if ARGV.verbose?
|
|
|
|
end
|
2013-09-07 10:22:58 -05:00
|
|
|
|
2014-03-29 17:47:42 -05:00
|
|
|
Process.wait(pid)
|
2013-09-07 10:22:58 -05:00
|
|
|
|
2013-11-29 21:05:20 -06:00
|
|
|
$stdout.flush
|
|
|
|
|
2013-10-27 07:05:13 +01:00
|
|
|
unless $?.success?
|
|
|
|
f.flush
|
|
|
|
Kernel.system "/usr/bin/tail", "-n", "5", logfn unless ARGV.verbose?
|
|
|
|
f.puts
|
|
|
|
require 'cmd/--config'
|
|
|
|
Homebrew.write_build_config(f)
|
2013-11-02 22:52:24 -05:00
|
|
|
raise BuildError.new(self, cmd, args, $?)
|
2012-09-28 09:12:15 -04:00
|
|
|
end
|
2012-09-11 20:59:59 -04:00
|
|
|
end
|
|
|
|
ensure
|
2014-02-22 21:39:38 -05:00
|
|
|
rd.close unless rd.closed?
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
2009-07-24 15:10:01 +01:00
|
|
|
|
2013-04-07 00:49:56 -05:00
|
|
|
private
|
2012-03-04 16:48:00 -08:00
|
|
|
|
2009-08-11 12:20:55 -07:00
|
|
|
def stage
|
2013-09-17 21:25:38 -05:00
|
|
|
active_spec.stage do
|
2012-02-24 12:50:21 -08:00
|
|
|
@buildpath = Pathname.pwd
|
2011-08-24 01:13:15 +01:00
|
|
|
yield
|
2012-02-24 12:50:21 -08:00
|
|
|
@buildpath = nil
|
2009-07-31 11:05:23 -07:00
|
|
|
end
|
|
|
|
end
|
2010-07-04 14:17:03 -07:00
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
def patch
|
2014-03-13 19:51:23 -05:00
|
|
|
active_spec.add_legacy_patches(patches)
|
|
|
|
return if patchlist.empty?
|
2009-09-15 20:07:40 +01:00
|
|
|
|
2014-03-13 19:51:23 -05:00
|
|
|
active_spec.patches.select(&:external?).each do |patch|
|
|
|
|
patch.verify_download_integrity(patch.fetch)
|
2011-08-29 14:55:28 -07:00
|
|
|
end
|
2009-09-15 20:07:40 +01:00
|
|
|
|
2010-05-11 08:34:29 -07:00
|
|
|
ohai "Patching"
|
2014-03-13 19:51:23 -05:00
|
|
|
active_spec.patches.each(&:apply)
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
2009-08-11 18:16:12 +01:00
|
|
|
|
2013-10-28 02:16:42 -07:00
|
|
|
# Explicitly request changing C++ standard library compatibility check
|
|
|
|
# settings. Use with caution!
|
|
|
|
def cxxstdlib_check check_type
|
2014-02-22 11:17:50 -05:00
|
|
|
cxxstdlib << check_type
|
2013-10-28 02:16:42 -07:00
|
|
|
end
|
|
|
|
|
2012-04-06 17:28:44 -05:00
|
|
|
def self.method_added method
|
2013-01-07 17:34:56 -06:00
|
|
|
case method
|
|
|
|
when :brew
|
2013-06-06 16:36:12 -07:00
|
|
|
raise "You cannot override Formula#brew in class #{name}"
|
2013-01-07 17:34:56 -06:00
|
|
|
when :test
|
2013-01-09 19:25:02 -06:00
|
|
|
@test_defined = true
|
2013-01-07 17:34:56 -06:00
|
|
|
end
|
2009-07-31 14:17:56 +01:00
|
|
|
end
|
2009-08-21 20:20:44 +01:00
|
|
|
|
2013-06-05 09:47:08 -07:00
|
|
|
# The methods below define the formula DSL.
|
2009-09-28 14:06:53 -07:00
|
|
|
class << self
|
|
|
|
|
2013-12-09 15:15:53 -06:00
|
|
|
attr_reader :keg_only_reason, :cc_failures
|
2014-03-05 20:12:51 -06:00
|
|
|
attr_rw :homepage, :plist_startup, :plist_manual, :revision
|
2009-10-17 14:35:24 +02:00
|
|
|
|
2013-09-17 21:25:39 -05:00
|
|
|
def specs
|
2014-03-10 14:56:02 -05:00
|
|
|
@specs ||= [stable, devel, head].freeze
|
2013-09-17 21:25:39 -05:00
|
|
|
end
|
|
|
|
|
2013-09-22 16:04:25 -05:00
|
|
|
def url val, specs={}
|
Eagerly initialize formula specs
Declarations of dependencies, options, and resources in the DSL only
apply to specs that have already been initialized. For example, given
this snippet:
url ...
sha1 ...
depends_on 'foo'
devel do
url ...
sha1 ...
end
The dependency 'foo' will be recorded for the stable spec, but not the
devel spec, since it was not initialized prior to the call to
depends_on.
While it is considered best practice to declare all specs (stable,
devel, head, and bottle) prior to other declarations, there is nothing
that enforces this ordering, so when it happens it can be confusing and
hard to debug.
To prevent this, we can initialize all specs up front. This comes with
a performance penalty for commands that load all formulae into memory,
but that is probably outweighed by what we gain in correctness.
Fixes Homebrew/homebrew#23425.
2013-10-22 13:07:08 -05:00
|
|
|
stable.url(val, specs)
|
2012-07-30 11:32:56 -07:00
|
|
|
end
|
|
|
|
|
2013-09-22 16:04:25 -05:00
|
|
|
def version val=nil
|
Eagerly initialize formula specs
Declarations of dependencies, options, and resources in the DSL only
apply to specs that have already been initialized. For example, given
this snippet:
url ...
sha1 ...
depends_on 'foo'
devel do
url ...
sha1 ...
end
The dependency 'foo' will be recorded for the stable spec, but not the
devel spec, since it was not initialized prior to the call to
depends_on.
While it is considered best practice to declare all specs (stable,
devel, head, and bottle) prior to other declarations, there is nothing
that enforces this ordering, so when it happens it can be confusing and
hard to debug.
To prevent this, we can initialize all specs up front. This comes with
a performance penalty for commands that load all formulae into memory,
but that is probably outweighed by what we gain in correctness.
Fixes Homebrew/homebrew#23425.
2013-10-22 13:07:08 -05:00
|
|
|
stable.version(val)
|
2013-09-22 16:04:25 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def mirror val
|
Eagerly initialize formula specs
Declarations of dependencies, options, and resources in the DSL only
apply to specs that have already been initialized. For example, given
this snippet:
url ...
sha1 ...
depends_on 'foo'
devel do
url ...
sha1 ...
end
The dependency 'foo' will be recorded for the stable spec, but not the
devel spec, since it was not initialized prior to the call to
depends_on.
While it is considered best practice to declare all specs (stable,
devel, head, and bottle) prior to other declarations, there is nothing
that enforces this ordering, so when it happens it can be confusing and
hard to debug.
To prevent this, we can initialize all specs up front. This comes with
a performance penalty for commands that load all formulae into memory,
but that is probably outweighed by what we gain in correctness.
Fixes Homebrew/homebrew#23425.
2013-10-22 13:07:08 -05:00
|
|
|
stable.mirror(val)
|
2013-09-22 16:04:25 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
Checksum::TYPES.each do |cksum|
|
|
|
|
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
|
|
|
def #{cksum}(val)
|
Eagerly initialize formula specs
Declarations of dependencies, options, and resources in the DSL only
apply to specs that have already been initialized. For example, given
this snippet:
url ...
sha1 ...
depends_on 'foo'
devel do
url ...
sha1 ...
end
The dependency 'foo' will be recorded for the stable spec, but not the
devel spec, since it was not initialized prior to the call to
depends_on.
While it is considered best practice to declare all specs (stable,
devel, head, and bottle) prior to other declarations, there is nothing
that enforces this ordering, so when it happens it can be confusing and
hard to debug.
To prevent this, we can initialize all specs up front. This comes with
a performance penalty for commands that load all formulae into memory,
but that is probably outweighed by what we gain in correctness.
Fixes Homebrew/homebrew#23425.
2013-10-22 13:07:08 -05:00
|
|
|
stable.#{cksum}(val)
|
2013-09-22 16:04:25 -05:00
|
|
|
end
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
|
2014-03-10 14:56:02 -05:00
|
|
|
def bottle *, &block
|
|
|
|
stable.bottle(&block)
|
|
|
|
end
|
|
|
|
|
2013-09-22 16:04:25 -05:00
|
|
|
def build
|
Eagerly initialize formula specs
Declarations of dependencies, options, and resources in the DSL only
apply to specs that have already been initialized. For example, given
this snippet:
url ...
sha1 ...
depends_on 'foo'
devel do
url ...
sha1 ...
end
The dependency 'foo' will be recorded for the stable spec, but not the
devel spec, since it was not initialized prior to the call to
depends_on.
While it is considered best practice to declare all specs (stable,
devel, head, and bottle) prior to other declarations, there is nothing
that enforces this ordering, so when it happens it can be confusing and
hard to debug.
To prevent this, we can initialize all specs up front. This comes with
a performance penalty for commands that load all formulae into memory,
but that is probably outweighed by what we gain in correctness.
Fixes Homebrew/homebrew#23425.
2013-10-22 13:07:08 -05:00
|
|
|
stable.build
|
2009-10-17 14:35:24 +02:00
|
|
|
end
|
2009-09-28 14:06:53 -07:00
|
|
|
|
2012-01-22 22:32:15 -06:00
|
|
|
def stable &block
|
Eagerly initialize formula specs
Declarations of dependencies, options, and resources in the DSL only
apply to specs that have already been initialized. For example, given
this snippet:
url ...
sha1 ...
depends_on 'foo'
devel do
url ...
sha1 ...
end
The dependency 'foo' will be recorded for the stable spec, but not the
devel spec, since it was not initialized prior to the call to
depends_on.
While it is considered best practice to declare all specs (stable,
devel, head, and bottle) prior to other declarations, there is nothing
that enforces this ordering, so when it happens it can be confusing and
hard to debug.
To prevent this, we can initialize all specs up front. This comes with
a performance penalty for commands that load all formulae into memory,
but that is probably outweighed by what we gain in correctness.
Fixes Homebrew/homebrew#23425.
2013-10-22 13:07:08 -05:00
|
|
|
@stable ||= SoftwareSpec.new
|
2012-04-05 21:09:24 -05:00
|
|
|
return @stable unless block_given?
|
2013-09-12 19:43:22 -05:00
|
|
|
@stable.instance_eval(&block)
|
2012-01-22 22:32:15 -06:00
|
|
|
end
|
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
def devel &block
|
Eagerly initialize formula specs
Declarations of dependencies, options, and resources in the DSL only
apply to specs that have already been initialized. For example, given
this snippet:
url ...
sha1 ...
depends_on 'foo'
devel do
url ...
sha1 ...
end
The dependency 'foo' will be recorded for the stable spec, but not the
devel spec, since it was not initialized prior to the call to
depends_on.
While it is considered best practice to declare all specs (stable,
devel, head, and bottle) prior to other declarations, there is nothing
that enforces this ordering, so when it happens it can be confusing and
hard to debug.
To prevent this, we can initialize all specs up front. This comes with
a performance penalty for commands that load all formulae into memory,
but that is probably outweighed by what we gain in correctness.
Fixes Homebrew/homebrew#23425.
2013-10-22 13:07:08 -05:00
|
|
|
@devel ||= SoftwareSpec.new
|
2012-04-05 21:09:24 -05:00
|
|
|
return @devel unless block_given?
|
|
|
|
@devel.instance_eval(&block)
|
|
|
|
end
|
2012-03-18 20:37:10 +13:00
|
|
|
|
2013-09-13 11:13:12 -05:00
|
|
|
def head val=nil, specs={}, &block
|
Eagerly initialize formula specs
Declarations of dependencies, options, and resources in the DSL only
apply to specs that have already been initialized. For example, given
this snippet:
url ...
sha1 ...
depends_on 'foo'
devel do
url ...
sha1 ...
end
The dependency 'foo' will be recorded for the stable spec, but not the
devel spec, since it was not initialized prior to the call to
depends_on.
While it is considered best practice to declare all specs (stable,
devel, head, and bottle) prior to other declarations, there is nothing
that enforces this ordering, so when it happens it can be confusing and
hard to debug.
To prevent this, we can initialize all specs up front. This comes with
a performance penalty for commands that load all formulae into memory,
but that is probably outweighed by what we gain in correctness.
Fixes Homebrew/homebrew#23425.
2013-10-22 13:07:08 -05:00
|
|
|
@head ||= HeadSoftwareSpec.new
|
2013-09-13 11:13:12 -05:00
|
|
|
if block_given?
|
|
|
|
@head.instance_eval(&block)
|
|
|
|
elsif val
|
|
|
|
@head.url(val, specs)
|
|
|
|
else
|
|
|
|
@head
|
|
|
|
end
|
2012-04-05 21:09:24 -05:00
|
|
|
end
|
2012-03-18 20:37:10 +13:00
|
|
|
|
2013-08-06 19:52:58 -07:00
|
|
|
# Define a named resource using a SoftwareSpec style block
|
2013-09-17 21:25:38 -05:00
|
|
|
def resource name, &block
|
2013-09-17 21:25:40 -05:00
|
|
|
specs.each do |spec|
|
|
|
|
spec.resource(name, &block) unless spec.resource?(name)
|
|
|
|
end
|
2013-08-06 19:52:58 -07:00
|
|
|
end
|
|
|
|
|
2012-02-28 19:56:35 -08:00
|
|
|
def depends_on dep
|
2013-09-21 19:27:24 -05:00
|
|
|
specs.each { |spec| spec.depends_on(dep) }
|
2009-09-18 19:16:39 +01:00
|
|
|
end
|
2009-09-28 14:06:53 -07:00
|
|
|
|
2012-07-30 11:32:56 -07:00
|
|
|
def option name, description=nil
|
2013-09-21 19:27:24 -05:00
|
|
|
specs.each { |spec| spec.option(name, description) }
|
2012-07-30 11:32:56 -07:00
|
|
|
end
|
2012-11-25 15:06:41 +00:00
|
|
|
|
2014-03-13 19:51:23 -05:00
|
|
|
def patch strip=:p1, io=nil, &block
|
|
|
|
specs.each { |spec| spec.patch(strip, io, &block) }
|
|
|
|
end
|
|
|
|
|
2012-11-25 15:06:41 +00:00
|
|
|
def plist_options options
|
|
|
|
@plist_startup = options[:startup]
|
|
|
|
@plist_manual = options[:manual]
|
|
|
|
end
|
2012-07-30 11:32:56 -07:00
|
|
|
|
2013-06-09 13:44:59 -05:00
|
|
|
def conflicts
|
|
|
|
@conflicts ||= []
|
|
|
|
end
|
|
|
|
|
2013-08-29 19:03:34 -05:00
|
|
|
def conflicts_with *names
|
|
|
|
opts = Hash === names.last ? names.pop : {}
|
|
|
|
names.each { |name| conflicts << FormulaConflict.new(name, opts[:because]) }
|
2012-07-28 13:02:46 -03:00
|
|
|
end
|
|
|
|
|
2012-10-21 13:03:35 -07:00
|
|
|
def skip_clean *paths
|
2013-06-20 16:18:01 -05:00
|
|
|
paths.flatten!
|
2014-02-23 12:09:28 -08:00
|
|
|
# Specifying :all is deprecated and will become an error
|
2013-12-22 13:43:00 -06:00
|
|
|
skip_clean_paths.merge(paths)
|
2009-09-28 14:06:53 -07:00
|
|
|
end
|
2010-07-04 14:17:03 -07:00
|
|
|
|
2009-09-29 23:51:37 +01:00
|
|
|
def skip_clean_paths
|
2013-06-20 16:25:58 -05:00
|
|
|
@skip_clean_paths ||= Set.new
|
2009-09-29 23:51:37 +01:00
|
|
|
end
|
2010-07-18 15:18:51 -07:00
|
|
|
|
2011-03-15 22:01:27 -07:00
|
|
|
def keg_only reason, explanation=nil
|
2011-03-15 22:46:10 -07:00
|
|
|
@keg_only_reason = KegOnlyReason.new(reason, explanation.to_s.chomp)
|
2010-07-18 10:38:45 -07:00
|
|
|
end
|
2011-03-21 14:23:28 -07:00
|
|
|
|
2013-09-28 12:21:16 -07:00
|
|
|
# For Apple compilers, this should be in the format:
|
|
|
|
# fails_with compiler do
|
|
|
|
# cause "An explanation for why the build doesn't work."
|
|
|
|
# build "The Apple build number for the newest incompatible release."
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# The block may be omitted, and if present the build may be omitted;
|
|
|
|
# if so, then the compiler will be blacklisted for *all* versions.
|
|
|
|
#
|
|
|
|
# For GNU GCC compilers, this should be in the format:
|
|
|
|
# fails_with compiler => major_version do
|
|
|
|
# cause
|
|
|
|
# version "The official release number for the latest incompatible
|
|
|
|
# version, for instance 4.8.1"
|
|
|
|
# end
|
2014-01-04 12:49:48 +00:00
|
|
|
#
|
2013-09-28 12:21:16 -07:00
|
|
|
# `major_version` should be the major release number only, for instance
|
|
|
|
# '4.8' for the GCC 4.8 series (4.8.0, 4.8.1, etc.).
|
|
|
|
# If `version` or the block is omitted, then the compiler will be
|
|
|
|
# blacklisted for all compilers in that series.
|
|
|
|
#
|
|
|
|
# For example, if a bug is only triggered on GCC 4.8.1 but is not
|
|
|
|
# encountered on 4.8.2:
|
2014-01-04 12:49:48 +00:00
|
|
|
#
|
2013-09-28 12:21:16 -07:00
|
|
|
# fails_with :gcc => '4.8' do
|
|
|
|
# version '4.8.1'
|
|
|
|
# end
|
2012-03-18 13:58:13 -05:00
|
|
|
def fails_with compiler, &block
|
2013-03-13 02:07:01 -05:00
|
|
|
@cc_failures ||= Set.new
|
|
|
|
@cc_failures << CompilerFailure.new(compiler, &block)
|
2011-03-21 14:23:28 -07:00
|
|
|
end
|
2012-11-01 14:40:59 -05:00
|
|
|
|
2014-04-04 21:16:09 -07:00
|
|
|
def needs *standards
|
|
|
|
@cc_failures ||= Set.new
|
|
|
|
standards.each do |standard|
|
|
|
|
@cc_failures.merge CompilerFailure.for_standard standard
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-09-21 19:27:24 -05:00
|
|
|
def require_universal_deps
|
|
|
|
specs.each { |spec| spec.build.universal = true }
|
|
|
|
end
|
|
|
|
|
2012-11-01 14:40:59 -05:00
|
|
|
def test &block
|
|
|
|
return @test unless block_given?
|
2013-01-09 19:25:02 -06:00
|
|
|
@test_defined = true
|
|
|
|
@test = block
|
2012-11-01 14:40:59 -05:00
|
|
|
end
|
2009-09-28 14:06:53 -07:00
|
|
|
end
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
2012-03-06 00:26:25 -06:00
|
|
|
|
|
|
|
require 'formula_specialties'
|