2009-10-15 09:07:12 +01:00
|
|
|
require 'download_strategy'
|
2012-02-28 19:56:35 -08:00
|
|
|
require 'dependencies'
|
2012-02-04 18:45:08 -08:00
|
|
|
require 'formula_support'
|
2012-02-25 15:22:32 -08:00
|
|
|
require 'hardware'
|
2012-03-07 21:30:03 -05:00
|
|
|
require 'bottles'
|
2012-03-09 10:56:45 -08:00
|
|
|
require 'patches'
|
2012-03-18 13:58:13 -05:00
|
|
|
require 'compilers'
|
2012-09-14 07:54:14 -07:00
|
|
|
require 'build_environment'
|
2012-10-02 13:21:00 -05:00
|
|
|
require 'extend/set'
|
2011-03-21 14:23:28 -07:00
|
|
|
|
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-01-19 20:45:57 -06:00
|
|
|
extend BuildEnvironmentDSL
|
2010-07-04 14:17:03 -07:00
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
attr_reader :name, :path, :homepage, :downloader
|
|
|
|
attr_reader :stable, :bottle, :devel, :head, :active_spec
|
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
|
|
|
|
2009-08-21 20:20:44 +01:00
|
|
|
# Homebrew determines the name
|
2010-09-22 07:54:53 -07:00
|
|
|
def initialize name='__UNKNOWN__', path=nil
|
2012-04-05 21:09:24 -05:00
|
|
|
set_instance_variable :homepage
|
|
|
|
set_instance_variable :stable
|
|
|
|
set_instance_variable :bottle
|
|
|
|
set_instance_variable :devel
|
|
|
|
set_instance_variable :head
|
2009-08-23 17:57:45 +01:00
|
|
|
|
2012-03-09 10:18:12 -08:00
|
|
|
@name = name
|
2009-08-22 17:26:15 +01:00
|
|
|
validate_variable :name
|
2009-09-22 13:03:46 -04:00
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
# If a checksum or version was set in the DSL, but no stable URL
|
|
|
|
# was defined, make @stable nil and save callers some trouble
|
|
|
|
@stable = nil if @stable and @stable.url.nil?
|
2010-09-22 07:54:53 -07:00
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
# Ensure the bottle URL is set. If it does not have a checksum,
|
|
|
|
# then a bottle is not available for the current platform.
|
2012-06-18 19:58:35 -05:00
|
|
|
if @bottle and not (@bottle.checksum.nil? or @bottle.checksum.empty?)
|
2012-04-05 21:09:24 -05:00
|
|
|
@bottle.url ||= bottle_base_url + bottle_filename(self)
|
|
|
|
else
|
|
|
|
@bottle = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
@active_spec = if @head and ARGV.build_head? then @head # --HEAD
|
|
|
|
elsif @devel and ARGV.build_devel? then @devel # --devel
|
|
|
|
elsif @bottle and install_bottle?(self) then @bottle # bottle available
|
|
|
|
elsif @stable.nil? and @head then @head # head-only
|
|
|
|
else @stable # default
|
|
|
|
end
|
|
|
|
|
|
|
|
@version = @active_spec.version
|
2012-03-10 10:02:05 -08:00
|
|
|
validate_variable :version if @version
|
2009-09-22 13:03:46 -04:00
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
raise "No url provided for formula #{name}" if @active_spec.url.nil?
|
2010-01-16 17:54:14 -08:00
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
# If we got an explicit path, use that, else determine from the name
|
|
|
|
@path = path.nil? ? self.class.path(name) : Pathname.new(path)
|
2012-06-26 01:35:37 -05:00
|
|
|
@downloader = download_strategy.new(name, @active_spec)
|
2012-07-30 11:32:56 -07:00
|
|
|
|
|
|
|
# Combine DSL `option` and `def options`
|
2012-08-11 16:51:05 -05:00
|
|
|
options.each do |opt, desc|
|
|
|
|
# make sure to strip "--" from the start of options
|
|
|
|
self.class.build.add opt[/--(.+)$/, 1], desc
|
|
|
|
end
|
2012-04-05 21:09:24 -05:00
|
|
|
end
|
|
|
|
|
2012-07-17 03:22:57 -05:00
|
|
|
def url; @active_spec.url; end
|
|
|
|
def version; @active_spec.version; end
|
|
|
|
def specs; @active_spec.specs; end
|
|
|
|
def mirrors; @active_spec.mirrors; end
|
2012-04-05 21:09:24 -05:00
|
|
|
|
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-01-14 22:32:39 -06:00
|
|
|
installed_prefix.children.length > 0 rescue false
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
|
|
|
|
2011-11-26 21:03:46 -08:00
|
|
|
def explicitly_requested?
|
2012-11-24 17:42:34 -06:00
|
|
|
ARGV.formulae.include?(self) rescue false
|
2011-11-26 21:03:46 -08:00
|
|
|
end
|
|
|
|
|
2012-01-14 20:03:30 -06:00
|
|
|
def linked_keg
|
2012-02-10 17:21:48 -06:00
|
|
|
HOMEBREW_REPOSITORY/'Library/LinkedKegs'/@name
|
2012-01-14 20:03:30 -06:00
|
|
|
end
|
|
|
|
|
2010-09-24 11:55:21 -05:00
|
|
|
def installed_prefix
|
2012-04-05 21:09:24 -05:00
|
|
|
devel_prefix = unless @devel.nil?
|
|
|
|
HOMEBREW_CELLAR/@name/@devel.version
|
|
|
|
end
|
|
|
|
|
|
|
|
head_prefix = unless @head.nil?
|
|
|
|
HOMEBREW_CELLAR/@name/@head.version
|
|
|
|
end
|
|
|
|
|
|
|
|
if @active_spec == @head || @head and head_prefix.directory?
|
2010-09-24 11:55:21 -05:00
|
|
|
head_prefix
|
2012-04-05 21:09:24 -05:00
|
|
|
elsif @active_spec == @devel || @devel and devel_prefix.directory?
|
|
|
|
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
|
|
|
|
|
2010-07-04 14:17:03 -07:00
|
|
|
def prefix
|
|
|
|
validate_variable :name
|
|
|
|
validate_variable :version
|
2012-07-10 16:01:02 -05:00
|
|
|
HOMEBREW_CELLAR/@name/@version
|
2010-02-19 21:55:17 -08:00
|
|
|
end
|
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
|
|
|
|
2009-10-03 15:23:28 +01:00
|
|
|
# configuration needs to be preserved past upgrades
|
2009-10-02 15:55:34 +01:00
|
|
|
def etc; HOMEBREW_PREFIX+'etc' end
|
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
|
|
|
|
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
|
|
|
|
2012-07-30 11:32:56 -07:00
|
|
|
def build
|
|
|
|
self.class.build
|
|
|
|
end
|
|
|
|
|
2012-08-10 16:33:22 -04:00
|
|
|
def opt_prefix; HOMEBREW_PREFIX/:opt/name end
|
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
# Use the @active_spec to detect the download strategy.
|
2010-07-04 14:17:03 -07:00
|
|
|
# Can be overriden to force a custom download strategy
|
|
|
|
def download_strategy
|
2012-04-05 21:09:24 -05:00
|
|
|
@active_spec.download_strategy
|
2010-07-04 14:17:03 -07:00
|
|
|
end
|
2010-03-17 16:56:06 -07:00
|
|
|
|
2010-07-04 14:17:03 -07:00
|
|
|
def cached_download
|
|
|
|
@downloader.cached_location
|
2009-08-11 12:20:55 -07:00
|
|
|
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
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
# patches are automatically applied after extracting the tarball
|
2009-11-13 14:27:21 -05:00
|
|
|
# return an array of strings, or if you need a patch level other than -p1
|
2009-08-11 18:16:12 +01:00
|
|
|
# return a Hash eg.
|
|
|
|
# {
|
|
|
|
# :p0 => ['http://foo.com/patch1', 'http://foo.com/patch2'],
|
|
|
|
# :p1 => 'http://bar.com/patch2',
|
|
|
|
# :p2 => ['http://moo.com/patch5', 'http://moo.com/patch6']
|
|
|
|
# }
|
2009-09-17 21:10:39 +01:00
|
|
|
# The final option is to return DATA, then put a diff after __END__. You
|
2009-09-04 15:28:18 +01:00
|
|
|
# can still return a Hash with DATA as the value for a patch level key.
|
2009-09-21 23:51:31 +01: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
|
|
|
|
return false if self.class.cc_failures.nil?
|
|
|
|
cc = Compiler.new(cc) unless cc.is_a? Compiler
|
|
|
|
return self.class.cc_failures.find do |failure|
|
|
|
|
next unless failure.compiler == cc.name
|
|
|
|
failure.build.zero? or failure.build >= cc.build
|
2011-08-26 17:08:42 +01:00
|
|
|
end
|
2011-03-21 14:23:28 -07:00
|
|
|
end
|
|
|
|
|
2009-09-28 14:06:53 -07:00
|
|
|
# sometimes the clean process breaks things
|
|
|
|
# skip cleaning paths in a formula with a class method like this:
|
|
|
|
# skip_clean [bin+"foo", lib+"bar"]
|
2011-12-17 17:12:19 -08:00
|
|
|
# redefining skip_clean? now deprecated
|
2009-09-28 14:06:53 -07:00
|
|
|
def skip_clean? path
|
2010-08-09 00:30:51 -05:00
|
|
|
return true if self.class.skip_clean_all?
|
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
|
2009-08-22 17:26:15 +01:00
|
|
|
validate_variable :name
|
|
|
|
validate_variable :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
|
2012-09-11 20:59:59 -04:00
|
|
|
rescue RuntimeError, SystemCallError => e
|
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
|
|
|
|
2010-09-11 20:22:54 +01:00
|
|
|
def == b
|
|
|
|
name == b.name
|
|
|
|
end
|
|
|
|
def eql? b
|
|
|
|
self == b and self.class.equal? b.class
|
|
|
|
end
|
|
|
|
def hash
|
|
|
|
name.hash
|
|
|
|
end
|
|
|
|
def <=> b
|
|
|
|
name <=> b.name
|
|
|
|
end
|
|
|
|
def to_s
|
|
|
|
name
|
|
|
|
end
|
|
|
|
|
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
|
|
|
|
-Wno-dev
|
|
|
|
]
|
2009-08-21 20:20:44 +01:00
|
|
|
end
|
|
|
|
|
2009-09-11 14:22:46 +01:00
|
|
|
def self.class_s name
|
2010-01-13 11:07:42 +00:00
|
|
|
#remove invalid characters and then camelcase it
|
2009-10-19 13:05:47 +01:00
|
|
|
name.capitalize.gsub(/[-_.\s]([a-zA-Z0-9])/) { $1.upcase } \
|
|
|
|
.gsub('+', 'x')
|
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
|
|
|
|
Dir["#{HOMEBREW_REPOSITORY}/Library/Formula/*.rb"].map{ |f| File.basename f, '.rb' }.sort
|
|
|
|
end
|
|
|
|
|
2010-09-11 20:22:54 +01:00
|
|
|
def self.each
|
2012-08-21 11:39:45 -04:00
|
|
|
names.each do |name|
|
|
|
|
yield begin
|
|
|
|
Formula.factory(name)
|
|
|
|
rescue => 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}"
|
|
|
|
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
|
|
|
|
def self.all
|
|
|
|
opoo "Formula.all is deprecated, simply use Formula.map"
|
|
|
|
map
|
2012-08-10 16:05:30 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.installed
|
|
|
|
HOMEBREW_CELLAR.children.map{ |rack| factory(rack.basename) rescue nil }.compact
|
|
|
|
end
|
|
|
|
|
2010-09-11 20:22:54 +01:00
|
|
|
def inspect
|
|
|
|
name
|
2010-03-09 02:18:08 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.aliases
|
|
|
|
Dir["#{HOMEBREW_REPOSITORY}/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
|
2011-12-26 11:52:33 -08:00
|
|
|
name = name.to_s if name.kind_of? Pathname
|
|
|
|
|
2010-12-31 11:00:15 -08:00
|
|
|
formula_with_that_name = HOMEBREW_REPOSITORY+"Library/Formula/#{name}.rb"
|
2011-06-08 11:13:50 -07:00
|
|
|
possible_alias = HOMEBREW_REPOSITORY+"Library/Aliases/#{name}"
|
|
|
|
possible_cached_formula = HOMEBREW_CACHE_FORMULA+"#{name}.rb"
|
|
|
|
|
2010-11-05 13:44:24 +00:00
|
|
|
if name.include? "/"
|
2012-03-04 14:17:54 +00:00
|
|
|
if name =~ %r{(.+)/(.+)/(.+)}
|
2012-03-18 01:51:10 +00:00
|
|
|
tapd = HOMEBREW_REPOSITORY/"Library/Taps"/"#$1-#$2".downcase
|
2012-03-04 14:17:54 +00:00
|
|
|
tapd.find_formula do |relative_pathname|
|
|
|
|
return "#{tapd}/#{relative_pathname}" if relative_pathname.stem.to_s == $3
|
|
|
|
end if tapd.directory?
|
|
|
|
end
|
|
|
|
# Otherwise don't resolve paths or URLs
|
2010-11-05 13:44:24 +00:00
|
|
|
name
|
|
|
|
elsif formula_with_that_name.file? and formula_with_that_name.readable?
|
|
|
|
name
|
|
|
|
elsif possible_alias.file?
|
|
|
|
possible_alias.realpath.basename('.rb').to_s
|
2011-06-08 11:13:50 -07:00
|
|
|
elsif possible_cached_formula.file?
|
|
|
|
possible_cached_formula.to_s
|
2010-09-22 12:32:16 -07:00
|
|
|
else
|
|
|
|
name
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-08-21 20:20:44 +01:00
|
|
|
def self.factory name
|
2010-09-22 07:54:53 -07:00
|
|
|
# If an instance of Formula is passed, just return it
|
2009-09-18 19:16:39 +01:00
|
|
|
return name if name.kind_of? Formula
|
2010-09-22 07:54:53 -07:00
|
|
|
|
2012-02-17 21:18:37 +01:00
|
|
|
# Otherwise, convert to String in case a Pathname comes in
|
|
|
|
name = name.to_s
|
|
|
|
|
2010-09-22 07:54:53 -07:00
|
|
|
# If a URL is passed, download to the cache and install
|
|
|
|
if name =~ %r[(https?|ftp)://]
|
|
|
|
url = name
|
|
|
|
name = Pathname.new(name).basename
|
2012-08-23 14:33:33 -05:00
|
|
|
path = HOMEBREW_CACHE_FORMULA+name
|
2010-09-22 07:54:53 -07:00
|
|
|
name = name.basename(".rb").to_s
|
|
|
|
|
2012-08-23 14:33:33 -05:00
|
|
|
unless Object.const_defined? self.class_s(name)
|
|
|
|
HOMEBREW_CACHE_FORMULA.mkpath
|
|
|
|
FileUtils.rm path, :force => true
|
|
|
|
curl url, '-o', path
|
|
|
|
end
|
2010-09-22 07:54:53 -07:00
|
|
|
|
|
|
|
install_type = :from_url
|
2012-11-25 14:33:52 +00:00
|
|
|
elsif name.match bottle_regex
|
|
|
|
bottle_filename = Pathname(name).realpath
|
2013-01-07 20:26:56 +00:00
|
|
|
name = bottle_filename.basename.to_s.rpartition('-').first
|
2012-11-25 14:33:52 +00:00
|
|
|
path = Formula.path(name)
|
|
|
|
install_type = :from_local_bottle
|
2009-09-04 15:28:18 +01:00
|
|
|
else
|
2011-06-08 11:13:50 -07:00
|
|
|
name = Formula.canonical_name(name)
|
2012-05-15 02:27:11 -04:00
|
|
|
|
2012-10-09 14:45:53 -05:00
|
|
|
if name =~ %r{^(\w+)/(\w+)/([^/])+$}
|
|
|
|
# name appears to be a tapped formula, so we don't munge it
|
|
|
|
# in order to provide a useful error message when require fails.
|
|
|
|
path = Pathname.new(name)
|
|
|
|
elsif name.include? "/"
|
|
|
|
# If name was a path or mapped to a cached formula
|
|
|
|
|
2012-05-15 02:27:11 -04:00
|
|
|
# require allows filenames to drop the .rb extension, but everything else
|
|
|
|
# in our codebase will require an exact and fullpath.
|
|
|
|
name = "#{name}.rb" unless name =~ /\.rb$/
|
|
|
|
|
2011-03-12 16:37:56 -08:00
|
|
|
path = Pathname.new(name)
|
2010-09-22 07:54:53 -07:00
|
|
|
name = path.stem
|
|
|
|
install_type = :from_path
|
|
|
|
else
|
|
|
|
# For names, map to the path and then require
|
2012-08-23 14:33:33 -05:00
|
|
|
path = Formula.path(name)
|
2010-09-22 07:54:53 -07:00
|
|
|
install_type = :from_name
|
|
|
|
end
|
2009-09-04 15:28:18 +01:00
|
|
|
end
|
2010-09-22 07:54:53 -07:00
|
|
|
|
2012-08-23 14:33:33 -05:00
|
|
|
klass_name = self.class_s(name)
|
|
|
|
unless Object.const_defined? klass_name
|
|
|
|
puts "#{$0}: loading #{path}" if ARGV.debug?
|
|
|
|
require path
|
|
|
|
end
|
|
|
|
|
2009-09-23 10:06:19 -07:00
|
|
|
begin
|
2011-03-20 22:37:25 +01:00
|
|
|
klass = Object.const_get klass_name
|
2011-06-08 11:34:01 -07:00
|
|
|
rescue NameError
|
2009-09-23 10:06:19 -07:00
|
|
|
# TODO really this text should be encoded into the exception
|
|
|
|
# and only shown if the UI deems it correct to show it
|
|
|
|
onoe "class \"#{klass_name}\" expected but not found in #{name}.rb"
|
|
|
|
puts "Double-check the name of the class in that formula."
|
|
|
|
raise LoadError
|
|
|
|
end
|
2010-09-22 07:54:53 -07:00
|
|
|
|
2012-11-25 14:33:52 +00:00
|
|
|
if install_type == :from_local_bottle
|
|
|
|
formula = klass.new(name)
|
|
|
|
formula.downloader.local_bottle_path = bottle_filename
|
|
|
|
return formula
|
|
|
|
end
|
|
|
|
|
2012-11-28 10:58:29 -06:00
|
|
|
raise NameError if !klass.ancestors.include? Formula
|
2012-11-28 10:00:40 -06:00
|
|
|
|
2010-09-22 07:54:53 -07:00
|
|
|
return klass.new(name) if install_type == :from_name
|
2012-08-23 14:33:33 -05:00
|
|
|
return klass.new(name, path.to_s)
|
2012-08-26 17:06:38 -07:00
|
|
|
rescue NoMethodError
|
|
|
|
# This is a programming error in an existing formula, and should not
|
|
|
|
# have a "no such formula" message.
|
|
|
|
raise
|
2012-08-21 15:51:59 -05:00
|
|
|
rescue LoadError, NameError
|
2012-08-26 17:08:09 -07:00
|
|
|
# Catch NameError so that things that are invalid symbols still get
|
|
|
|
# a useful error message.
|
2009-08-21 20:20:44 +01:00
|
|
|
raise FormulaUnavailableError.new(name)
|
|
|
|
end
|
|
|
|
|
2012-03-16 12:29:47 +00:00
|
|
|
def tap
|
|
|
|
if path.realpath.to_s =~ %r{#{HOMEBREW_REPOSITORY}/Library/Taps/(\w+)-(\w+)}
|
|
|
|
"#$1/#$2"
|
|
|
|
else
|
|
|
|
# remotely installed formula are not mxcl/master but this will do for now
|
|
|
|
"mxcl/master"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-08-21 20:20:44 +01:00
|
|
|
def self.path name
|
2010-12-31 11:00:15 -08:00
|
|
|
HOMEBREW_REPOSITORY+"Library/Formula/#{name.downcase}.rb"
|
2009-08-21 20:20:44 +01:00
|
|
|
end
|
|
|
|
|
2012-07-23 17:06:38 -07:00
|
|
|
def deps; self.class.dependencies.deps; end
|
|
|
|
def requirements; self.class.dependencies.requirements; end
|
2010-09-11 20:22:54 +01:00
|
|
|
|
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
|
|
|
|
requirements.select { |r| r.is_a? ConflictRequirement }
|
|
|
|
end
|
|
|
|
|
2010-09-11 20:22:54 +01:00
|
|
|
# deps are in an installable order
|
|
|
|
# which means if a depends on b then b will be ordered before a in this list
|
|
|
|
def recursive_deps
|
|
|
|
Formula.expand_deps(self).flatten.uniq
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.expand_deps f
|
|
|
|
f.deps.map do |dep|
|
2012-02-28 19:56:35 -08:00
|
|
|
f_dep = Formula.factory dep.to_s
|
|
|
|
expand_deps(f_dep) << f_dep
|
2010-09-11 20:22:54 +01:00
|
|
|
end
|
2010-01-13 09:00:24 +00:00
|
|
|
end
|
|
|
|
|
2012-08-14 21:45:08 -05:00
|
|
|
def recursive_requirements
|
2012-10-02 13:21:00 -05:00
|
|
|
reqs = ComparableSet.new
|
|
|
|
recursive_deps.each { |dep| reqs.merge dep.requirements }
|
|
|
|
reqs.merge requirements
|
2012-08-14 21:45:08 -05:00
|
|
|
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),
|
|
|
|
"bottle" => bottle && MacOS.bottles_supported? || false,
|
|
|
|
"devel" => (devel.version.to_s if devel),
|
|
|
|
"head" => (head.version.to_s if head)
|
|
|
|
},
|
|
|
|
"installed" => [],
|
|
|
|
"linked_keg" => (linked_keg.realpath.basename.to_s if linked_keg.exist?),
|
|
|
|
"keg_only" => keg_only?,
|
|
|
|
"dependencies" => deps.map {|dep| dep.to_s},
|
|
|
|
"conflicts_with" => conflicts.map {|c| c.formula},
|
|
|
|
"options" => [],
|
|
|
|
"caveats" => caveats
|
|
|
|
}
|
|
|
|
|
|
|
|
build.each do |opt|
|
|
|
|
hsh["options"] << {
|
|
|
|
"option" => "--"+opt.name,
|
|
|
|
"description" => opt.description
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
if rack.directory?
|
|
|
|
rack.children.each do |keg|
|
|
|
|
next if keg.basename.to_s == '.DS_Store'
|
|
|
|
tab = Tab.for_keg keg
|
|
|
|
|
|
|
|
hsh["installed"] << {
|
|
|
|
"version" => keg.basename.to_s,
|
|
|
|
"used_options" => tab.used_options,
|
|
|
|
"built_as_bottle" => tab.built_bottle
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
hsh
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2009-08-10 16:48:30 +01: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
|
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
|
|
|
|
2011-09-10 11:24:29 +01:00
|
|
|
removed_ENV_variables = case if args.empty? then cmd.split(' ').first else cmd end
|
|
|
|
when "xcodebuild"
|
|
|
|
ENV.remove_cc_etc
|
|
|
|
end
|
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
if ARGV.verbose?
|
|
|
|
safe_system cmd, *args
|
2009-07-24 15:10:01 +01:00
|
|
|
else
|
2012-09-11 20:59:59 -04:00
|
|
|
@exec_count ||= 0
|
|
|
|
@exec_count += 1
|
|
|
|
logd = HOMEBREW_LOGS/name
|
|
|
|
logfn = "#{logd}/%02d.%s" % [@exec_count, File.basename(cmd).split(' ').first]
|
|
|
|
mkdir_p(logd)
|
|
|
|
|
2009-11-06 17:09:14 +00:00
|
|
|
rd, wr = IO.pipe
|
2009-11-09 17:45:22 +00:00
|
|
|
pid = fork do
|
2009-11-06 17:09:14 +00:00
|
|
|
rd.close
|
|
|
|
$stdout.reopen wr
|
|
|
|
$stderr.reopen wr
|
2012-02-24 17:23:20 -06:00
|
|
|
args.collect!{|arg| arg.to_s}
|
2009-11-11 19:42:35 +00:00
|
|
|
exec(cmd, *args) rescue nil
|
2012-09-11 20:59:59 -04:00
|
|
|
puts "Failed to execute: #{cmd}"
|
2009-11-11 19:42:35 +00:00
|
|
|
exit! 1 # never gets here unless exec threw or failed
|
2009-11-06 17:09:14 +00:00
|
|
|
end
|
2009-11-09 17:45:22 +00:00
|
|
|
wr.close
|
2012-09-11 20:59:59 -04:00
|
|
|
|
|
|
|
f = File.open(logfn, 'w')
|
|
|
|
f.write(rd.read) until rd.eof?
|
|
|
|
|
2009-11-07 18:23:21 +00:00
|
|
|
Process.wait
|
2011-09-10 11:24:29 +01:00
|
|
|
|
2012-09-28 09:12:15 -04:00
|
|
|
unless $?.success?
|
|
|
|
unless ARGV.verbose?
|
|
|
|
f.flush
|
2012-12-11 13:58:43 -06:00
|
|
|
Kernel.system "/usr/bin/tail", "-n", "5", logfn
|
2012-09-28 09:12:15 -04:00
|
|
|
end
|
|
|
|
f.puts
|
|
|
|
require 'cmd/--config'
|
|
|
|
Homebrew.write_build_config(f)
|
2012-10-31 11:27:30 -04:00
|
|
|
raise ErrorDuringExecution
|
2012-09-28 09:12:15 -04:00
|
|
|
end
|
2012-09-11 20:59:59 -04:00
|
|
|
end
|
2012-10-31 11:27:30 -04:00
|
|
|
rescue ErrorDuringExecution => e
|
|
|
|
raise BuildError.new(self, cmd, args, $?)
|
2012-09-11 20:59:59 -04:00
|
|
|
ensure
|
2012-11-09 14:04:05 -06:00
|
|
|
f.close if f and not f.closed?
|
2012-09-28 09:12:15 -04:00
|
|
|
removed_ENV_variables.each do |key, value|
|
|
|
|
ENV[key] = value
|
|
|
|
end if removed_ENV_variables
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
2009-07-24 15:10:01 +01:00
|
|
|
|
2012-03-04 16:48:00 -08:00
|
|
|
public
|
2009-09-07 16:10:50 +02:00
|
|
|
|
2011-09-11 15:23:41 -07:00
|
|
|
# For brew-fetch and others.
|
|
|
|
def fetch
|
2011-09-19 19:05:44 -07:00
|
|
|
# Ensure the cache exists
|
|
|
|
HOMEBREW_CACHE.mkpath
|
|
|
|
|
2012-06-26 01:35:37 -05:00
|
|
|
return @downloader.fetch, @downloader
|
2011-09-11 15:23:41 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
# For FormulaInstaller.
|
2012-04-05 21:09:24 -05:00
|
|
|
def verify_download_integrity fn
|
2012-06-18 19:58:35 -05:00
|
|
|
@active_spec.verify_download_integrity(fn)
|
2009-08-11 12:20:55 -07:00
|
|
|
end
|
|
|
|
|
2012-11-01 14:40:59 -05:00
|
|
|
def test
|
|
|
|
ret = nil
|
|
|
|
mktemp do
|
|
|
|
@testpath = Pathname.pwd
|
2013-01-09 19:25:02 -06:00
|
|
|
ret = instance_eval(&self.class.test)
|
2012-11-01 14:40:59 -05:00
|
|
|
@testpath = nil
|
|
|
|
end
|
|
|
|
ret
|
|
|
|
end
|
|
|
|
|
2013-01-07 17:34:56 -06:00
|
|
|
def test_defined?
|
2013-01-09 19:25:02 -06:00
|
|
|
not self.class.instance_variable_get(:@test_defined).nil?
|
2013-01-07 17:34:56 -06:00
|
|
|
end
|
|
|
|
|
2012-03-04 16:48:00 -08:00
|
|
|
private
|
|
|
|
|
2009-08-11 12:20:55 -07:00
|
|
|
def stage
|
2011-09-11 15:23:41 -07:00
|
|
|
fetched, downloader = fetch
|
2010-07-04 14:17:03 -07:00
|
|
|
verify_download_integrity fetched if fetched.kind_of? Pathname
|
2011-08-24 01:13:15 +01:00
|
|
|
mktemp do
|
2011-09-11 15:23:41 -07:00
|
|
|
downloader.stage
|
2012-02-24 12:50:21 -08:00
|
|
|
# Set path after the downloader changes the working folder.
|
|
|
|
@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
|
2012-03-09 10:56:45 -08:00
|
|
|
patch_list = Patches.new(patches)
|
2009-09-04 15:28:18 +01:00
|
|
|
return if patch_list.empty?
|
2009-09-15 20:07:40 +01:00
|
|
|
|
2012-04-29 11:51:04 -07:00
|
|
|
if patch_list.external_patches?
|
2011-08-29 14:55:28 -07:00
|
|
|
ohai "Downloading patches"
|
2012-04-29 11:51:04 -07:00
|
|
|
patch_list.download!
|
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"
|
2009-09-09 11:59:46 -04:00
|
|
|
patch_list.each do |p|
|
2012-03-09 10:56:45 -08:00
|
|
|
case p.compression
|
2012-04-29 11:51:04 -07:00
|
|
|
when :gzip then safe_system "/usr/bin/gunzip", p.compressed_filename
|
|
|
|
when :bzip2 then safe_system "/usr/bin/bunzip2", p.compressed_filename
|
2009-08-11 18:16:12 +01:00
|
|
|
end
|
2012-03-09 10:56:45 -08:00
|
|
|
# -f means don't prompt the user if there are errors; just exit with non-zero status
|
|
|
|
safe_system '/usr/bin/patch', '-f', *(p.patch_args)
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
|
|
|
end
|
2009-08-11 18:16:12 +01:00
|
|
|
|
2009-08-22 17:26:15 +01:00
|
|
|
def validate_variable name
|
2009-09-28 14:10:20 -07:00
|
|
|
v = instance_variable_get("@#{name}")
|
2012-07-10 16:01:02 -05:00
|
|
|
raise "Invalid @#{name}" if v.to_s.empty? or v.to_s =~ /\s/
|
2009-08-22 17:26:15 +01:00
|
|
|
end
|
2009-09-28 14:10:20 -07:00
|
|
|
|
2009-09-22 13:03:46 -04:00
|
|
|
def set_instance_variable(type)
|
2012-03-04 17:34:29 -08:00
|
|
|
return if instance_variable_defined? "@#{type}"
|
|
|
|
class_value = self.class.send(type)
|
|
|
|
instance_variable_set("@#{type}", class_value) if class_value
|
2009-09-22 13:03:46 -04:00
|
|
|
end
|
2009-08-22 17:26:15 +01:00
|
|
|
|
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
|
|
|
|
raise "You cannot override Formula#brew"
|
|
|
|
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
|
|
|
|
2009-09-28 14:06:53 -07:00
|
|
|
class << self
|
2010-07-04 14:17:03 -07:00
|
|
|
# The methods below define the formula DSL.
|
2009-09-28 14:06:53 -07:00
|
|
|
|
2009-09-22 12:31:53 -04:00
|
|
|
def self.attr_rw(*attrs)
|
|
|
|
attrs.each do |attr|
|
|
|
|
class_eval %Q{
|
|
|
|
def #{attr}(val=nil)
|
|
|
|
val.nil? ? @#{attr} : @#{attr} = val
|
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
2009-09-28 14:06:53 -07:00
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
attr_rw :homepage, :keg_only_reason, :skip_clean_all, :cc_failures
|
2012-11-25 15:06:41 +00:00
|
|
|
attr_rw :plist_startup, :plist_manual
|
2009-10-17 14:35:24 +02:00
|
|
|
|
2012-06-18 19:58:35 -05:00
|
|
|
Checksum::TYPES.each do |cksum|
|
2012-04-05 21:09:24 -05:00
|
|
|
class_eval %Q{
|
|
|
|
def #{cksum}(val=nil)
|
|
|
|
unless val.nil?
|
|
|
|
@stable ||= SoftwareSpec.new
|
|
|
|
@stable.#{cksum}(val)
|
|
|
|
end
|
|
|
|
return @stable ? @stable.#{cksum} : @#{cksum}
|
|
|
|
end
|
|
|
|
}
|
2010-07-04 14:17:03 -07:00
|
|
|
end
|
|
|
|
|
2012-07-30 11:32:56 -07:00
|
|
|
def build
|
|
|
|
@build ||= BuildOptions.new(ARGV)
|
|
|
|
end
|
|
|
|
|
2010-07-04 14:17:03 -07:00
|
|
|
def url val=nil, specs=nil
|
2012-04-05 21:09:24 -05:00
|
|
|
if val.nil?
|
|
|
|
return @stable.url if @stable
|
|
|
|
return @url if @url
|
|
|
|
end
|
|
|
|
@stable ||= SoftwareSpec.new
|
|
|
|
@stable.url(val, specs)
|
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
|
2012-04-05 21:09:24 -05:00
|
|
|
return @stable unless block_given?
|
|
|
|
instance_eval(&block)
|
2012-01-22 22:32:15 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
def bottle url=nil, &block
|
2012-04-05 21:09:24 -05:00
|
|
|
return @bottle unless block_given?
|
|
|
|
@bottle ||= Bottle.new
|
|
|
|
@bottle.instance_eval(&block)
|
|
|
|
end
|
2012-03-18 20:37:10 +13:00
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
def devel &block
|
|
|
|
return @devel unless block_given?
|
|
|
|
@devel ||= SoftwareSpec.new
|
|
|
|
@devel.instance_eval(&block)
|
|
|
|
end
|
2012-03-18 20:37:10 +13:00
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
def head val=nil, specs=nil
|
|
|
|
return @head if val.nil?
|
|
|
|
@head ||= HeadSoftwareSpec.new
|
|
|
|
@head.url(val, specs)
|
|
|
|
end
|
2012-03-18 20:37:10 +13:00
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
def version val=nil
|
|
|
|
return @version if val.nil?
|
|
|
|
@stable ||= SoftwareSpec.new
|
|
|
|
@stable.version(val)
|
2012-01-22 22:32:15 -06:00
|
|
|
end
|
|
|
|
|
2012-06-26 01:35:37 -05:00
|
|
|
def mirror val
|
2012-04-05 21:09:24 -05:00
|
|
|
@stable ||= SoftwareSpec.new
|
2012-06-26 01:35:37 -05:00
|
|
|
@stable.mirror(val)
|
2011-09-11 15:23:41 -07:00
|
|
|
end
|
|
|
|
|
2012-02-28 19:56:35 -08:00
|
|
|
def dependencies
|
|
|
|
@dependencies ||= DependencyCollector.new
|
|
|
|
end
|
|
|
|
|
|
|
|
def depends_on dep
|
|
|
|
dependencies.add(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
|
|
|
|
# Support symbols
|
|
|
|
name = name.to_s
|
|
|
|
raise "Option name is required." if name.empty?
|
|
|
|
raise "Options should not start with dashes." if name[0, 1] == "-"
|
|
|
|
build.add name, description
|
|
|
|
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
|
|
|
|
2012-07-28 13:02:46 -03:00
|
|
|
def conflicts_with formula, opts={}
|
2012-11-06 17:32:23 -06:00
|
|
|
dependencies.add ConflictRequirement.new(formula, name, opts)
|
2012-07-28 13:02:46 -03:00
|
|
|
end
|
|
|
|
|
2012-10-21 13:03:35 -07:00
|
|
|
def skip_clean *paths
|
|
|
|
paths = [paths].flatten
|
|
|
|
|
|
|
|
# :all is deprecated though
|
|
|
|
if paths.include? :all
|
2012-08-29 15:43:28 -04:00
|
|
|
@skip_clean_all = true
|
2010-07-25 15:53:39 -07:00
|
|
|
return
|
|
|
|
end
|
2012-10-21 13:03:35 -07:00
|
|
|
|
2009-09-28 14:06:53 -07:00
|
|
|
@skip_clean_paths ||= []
|
2012-10-21 13:03:35 -07:00
|
|
|
paths.each do |p|
|
|
|
|
p = p.to_s unless p == :la # Keep :la in paths as a symbol
|
2012-09-09 10:01:59 -07:00
|
|
|
@skip_clean_paths << p unless @skip_clean_paths.include? p
|
2009-09-28 14:06:53 -07:00
|
|
|
end
|
|
|
|
end
|
2010-07-04 14:17:03 -07:00
|
|
|
|
2010-08-09 00:30:51 -05:00
|
|
|
def skip_clean_all?
|
|
|
|
@skip_clean_all
|
|
|
|
end
|
|
|
|
|
2009-09-29 23:51:37 +01:00
|
|
|
def skip_clean_paths
|
|
|
|
@skip_clean_paths or []
|
|
|
|
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
|
|
|
|
2012-03-18 13:58:13 -05:00
|
|
|
def fails_with compiler, &block
|
|
|
|
@cc_failures ||= CompilerFailures.new
|
|
|
|
@cc_failures << if block_given?
|
|
|
|
CompilerFailure.new(compiler, &block)
|
|
|
|
else
|
|
|
|
CompilerFailure.new(compiler)
|
|
|
|
end
|
2011-03-21 14:23:28 -07:00
|
|
|
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'
|