2009-10-15 09:07:12 +01:00
|
|
|
require 'download_strategy'
|
2009-12-01 10:54:59 +00:00
|
|
|
require 'fileutils'
|
2012-02-04 18:45:08 -08:00
|
|
|
require 'formula_support'
|
2011-03-21 14:23:28 -07:00
|
|
|
|
|
|
|
|
2009-08-21 20:20:44 +01:00
|
|
|
# Derive and define at least @url, see Library/Formula for examples
|
|
|
|
class Formula
|
2009-12-01 10:54:59 +00:00
|
|
|
include FileUtils
|
2010-07-04 14:17:03 -07:00
|
|
|
|
2011-06-21 16:34:07 -07:00
|
|
|
attr_reader :name, :path, :url, :version, :homepage, :specs, :downloader
|
2012-01-22 22:32:15 -06:00
|
|
|
attr_reader :standard, :unstable
|
|
|
|
attr_reader :bottle_url, :bottle_sha1, :head
|
2010-06-15 12:35:55 -07:00
|
|
|
|
2012-02-24 12:50:21 -08:00
|
|
|
# The build folder, usually in /tmp.
|
|
|
|
# Will only be non-nil during the stage method.
|
|
|
|
attr_reader :buildpath
|
|
|
|
|
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
|
2010-07-04 14:17:03 -07:00
|
|
|
set_instance_variable 'homepage'
|
2009-09-22 13:03:46 -04:00
|
|
|
set_instance_variable 'url'
|
2012-01-22 22:32:15 -06:00
|
|
|
set_instance_variable 'bottle_url'
|
2010-11-24 09:40:37 +00:00
|
|
|
set_instance_variable 'bottle_sha1'
|
2009-09-22 13:03:46 -04:00
|
|
|
set_instance_variable 'head'
|
2009-10-17 14:35:24 +02:00
|
|
|
set_instance_variable 'specs'
|
2009-08-23 17:57:45 +01:00
|
|
|
|
2012-01-22 22:32:15 -06:00
|
|
|
set_instance_variable 'standard'
|
2010-07-04 14:17:03 -07:00
|
|
|
set_instance_variable 'unstable'
|
|
|
|
|
2010-07-18 09:20:47 -07:00
|
|
|
if @head and (not @url or ARGV.build_head?)
|
2010-07-04 14:17:03 -07:00
|
|
|
@url = @head
|
|
|
|
@version = 'HEAD'
|
|
|
|
@spec_to_use = @unstable
|
|
|
|
else
|
2012-01-22 22:32:15 -06:00
|
|
|
if @standard.nil?
|
2010-07-04 14:17:03 -07:00
|
|
|
@spec_to_use = SoftwareSpecification.new(@url, @specs)
|
|
|
|
else
|
2012-01-22 22:32:15 -06:00
|
|
|
@spec_to_use = @standard
|
2010-07-04 14:17:03 -07:00
|
|
|
end
|
2009-08-23 17:57:45 +01:00
|
|
|
end
|
|
|
|
|
2009-12-17 23:00:20 +00:00
|
|
|
raise "No url provided for formula #{name}" if @url.nil?
|
2009-08-21 20:20:44 +01:00
|
|
|
@name=name
|
2009-08-22 17:26:15 +01:00
|
|
|
validate_variable :name
|
2009-09-22 13:03:46 -04:00
|
|
|
|
2011-11-27 16:44:42 -08:00
|
|
|
@path = path.nil? ? nil : Pathname.new(path)
|
2010-09-22 07:54:53 -07:00
|
|
|
|
2009-09-22 13:03:46 -04:00
|
|
|
set_instance_variable 'version'
|
2010-07-04 14:17:03 -07:00
|
|
|
@version ||= @spec_to_use.detect_version
|
2009-08-22 17:26:15 +01:00
|
|
|
validate_variable :version if @version
|
2009-09-22 13:03:46 -04:00
|
|
|
|
2010-07-04 14:17:03 -07:00
|
|
|
CHECKSUM_TYPES.each { |type| set_instance_variable type }
|
2010-01-16 17:54:14 -08:00
|
|
|
|
2010-07-04 14:17:03 -07:00
|
|
|
@downloader=download_strategy.new @spec_to_use.url, name, version, @spec_to_use.specs
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
# if the dir is there, but it's empty we consider it not installed
|
|
|
|
def installed?
|
2010-09-24 11:55:21 -05:00
|
|
|
return installed_prefix.children.length > 0
|
2009-07-24 15:10:01 +01:00
|
|
|
rescue
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2012-02-09 21:05:17 +00:00
|
|
|
def bottle_up_to_date?
|
|
|
|
!bottle_url.nil? && Pathname.new(bottle_url).version == version
|
|
|
|
end
|
|
|
|
|
2011-11-26 21:03:46 -08:00
|
|
|
def explicitly_requested?
|
2011-12-17 17:12:19 -08:00
|
|
|
# `ARGV.formulae` will throw an exception if it comes up with an empty list.
|
2011-11-26 21:03:46 -08:00
|
|
|
# FIXME: `ARGV.formulae` shouldn't be throwing exceptions, see issue #8823
|
|
|
|
return false if ARGV.named.empty?
|
|
|
|
ARGV.formulae.include? self
|
|
|
|
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
|
|
|
|
head_prefix = HOMEBREW_CELLAR+@name+'HEAD'
|
|
|
|
if @version == 'HEAD' || head_prefix.directory?
|
|
|
|
head_prefix
|
|
|
|
else
|
|
|
|
prefix
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
def path
|
2010-09-22 07:54:53 -07:00
|
|
|
if @path.nil?
|
2010-11-03 07:03:50 -07:00
|
|
|
return self.class.path(name)
|
2010-09-22 07:54:53 -07:00
|
|
|
else
|
|
|
|
return @path
|
|
|
|
end
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
|
|
|
|
2010-07-04 14:17:03 -07:00
|
|
|
def prefix
|
|
|
|
validate_variable :name
|
|
|
|
validate_variable :version
|
|
|
|
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
|
|
|
|
2010-07-04 21:07:37 -07:00
|
|
|
def bin; prefix+'bin' end
|
|
|
|
def doc; prefix+'share/doc'+name end
|
|
|
|
def include; prefix+'include' end
|
|
|
|
def info; prefix+'share/info' end
|
|
|
|
def lib; prefix+'lib' end
|
|
|
|
def libexec; prefix+'libexec' end
|
|
|
|
def man; prefix+'share/man' end
|
|
|
|
def man1; man+'man1' end
|
2010-07-21 11:21:09 -07:00
|
|
|
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
|
2010-07-04 21:07:37 -07:00
|
|
|
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
|
|
|
|
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-02-21 20:48:36 -08:00
|
|
|
# A version of mkdir that also changes to that folder in a block
|
|
|
|
def mkdir name, &block
|
|
|
|
FileUtils.mkdir name
|
|
|
|
if block_given?
|
|
|
|
FileUtils.chdir name do
|
|
|
|
yield
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-07-04 14:17:03 -07:00
|
|
|
# Use the @spec_to_use to detect the download strategy.
|
|
|
|
# Can be overriden to force a custom download strategy
|
|
|
|
def download_strategy
|
|
|
|
@spec_to_use.download_strategy
|
|
|
|
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?
|
|
|
|
self.class.keg_only_reason || false
|
|
|
|
end
|
2009-08-10 16:48:30 +01:00
|
|
|
|
2011-03-21 14:23:28 -07:00
|
|
|
def fails_with_llvm?
|
2011-08-26 17:08:42 +01:00
|
|
|
llvm = self.class.fails_with_llvm_reason
|
|
|
|
if llvm
|
2011-09-06 17:51:14 +01:00
|
|
|
if llvm.build and MacOS.llvm_build_version.to_i > llvm.build.to_i
|
2011-09-01 09:39:54 +01:00
|
|
|
false
|
2011-08-26 17:08:42 +01:00
|
|
|
else
|
2011-09-01 09:39:54 +01:00
|
|
|
llvm
|
2011-08-26 17:08:42 +01:00
|
|
|
end
|
|
|
|
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?
|
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
|
|
|
|
2011-03-21 14:23:28 -07:00
|
|
|
handle_llvm_failure(fails_with_llvm?) if fails_with_llvm?
|
|
|
|
|
2009-08-11 12:20:55 -07:00
|
|
|
stage do
|
2009-08-10 16:48:30 +01:00
|
|
|
begin
|
|
|
|
patch
|
2009-09-04 15:28:18 +01:00
|
|
|
# we allow formulas to do anything they want to the Ruby process
|
|
|
|
# so load any deps before this point! And exit asap afterwards
|
2009-08-10 16:48:30 +01:00
|
|
|
yield self
|
|
|
|
rescue Interrupt, RuntimeError, SystemCallError => e
|
2011-08-31 11:07:27 +01:00
|
|
|
unless ARGV.debug?
|
2011-08-31 17:35:33 +01:00
|
|
|
logs = File.expand_path '~/Library/Logs/Homebrew/'
|
2011-08-31 11:07:27 +01:00
|
|
|
if File.exist? 'config.log'
|
|
|
|
mkdir_p logs
|
2011-08-31 17:35:33 +01:00
|
|
|
mv 'config.log', logs
|
2011-08-31 11:07:27 +01:00
|
|
|
end
|
2011-09-01 10:28:11 +01:00
|
|
|
if File.exist? 'CMakeCache.txt'
|
2011-08-31 17:35:33 +01:00
|
|
|
mkdir_p logs
|
2011-09-01 10:28:11 +01:00
|
|
|
mv 'CMakeCache.txt', logs
|
2011-08-31 17:37:38 +01:00
|
|
|
end
|
2011-08-31 11:07:27 +01:00
|
|
|
raise
|
|
|
|
end
|
2009-08-10 16:48:30 +01:00
|
|
|
onoe e.inspect
|
|
|
|
puts e.backtrace
|
2011-08-31 11:07:27 +01:00
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
ohai "Rescuing build..."
|
2010-04-03 08:44:41 -07:00
|
|
|
if (e.was_running_configure? rescue false) and File.exist? 'config.log'
|
|
|
|
puts "It looks like an autotools configure failed."
|
|
|
|
puts "Gist 'config.log' and any error output when reporting an issue."
|
|
|
|
puts
|
|
|
|
end
|
|
|
|
|
2009-08-27 13:46:19 -07:00
|
|
|
puts "When you exit this shell Homebrew will attempt to finalise the installation."
|
|
|
|
puts "If nothing is installed or the shell exits with a non-zero error code,"
|
|
|
|
puts "Homebrew will abort. The installation prefix is:"
|
|
|
|
puts prefix
|
2010-08-20 10:01:49 -07:00
|
|
|
interactive_shell self
|
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.
|
|
|
|
# Note: there isn't a std_autotools variant because autotools is a lot
|
|
|
|
# less consistent and the standard parameters are more memorable.
|
2009-08-21 20:20:44 +01:00
|
|
|
def std_cmake_parameters
|
2009-12-09 04:47:17 +01:00
|
|
|
"-DCMAKE_INSTALL_PREFIX='#{prefix}' -DCMAKE_BUILD_TYPE=None -Wno-dev"
|
2009-08-21 20:20:44 +01:00
|
|
|
end
|
|
|
|
|
2011-03-21 14:23:28 -07:00
|
|
|
def handle_llvm_failure llvm
|
2011-12-24 12:48:10 -08:00
|
|
|
if ENV.compiler == :llvm
|
2012-01-16 19:47:44 +00:00
|
|
|
# version 2336 is the latest version as of Xcode 4.2, so it is the
|
2011-09-01 14:32:38 +01:00
|
|
|
# latest version we have tested against so we will switch to GCC and
|
2012-01-16 19:47:44 +00:00
|
|
|
# bump this integer when Xcode 4.3 is released. TODO do that!
|
|
|
|
if llvm.build.to_i >= 2336
|
2012-01-16 20:05:51 +00:00
|
|
|
if MacOS.xcode_version < "4.2"
|
|
|
|
opoo "Formula will not build with LLVM, using GCC"
|
2012-02-21 00:17:19 -06:00
|
|
|
ENV.gcc
|
2012-01-16 20:05:51 +00:00
|
|
|
else
|
|
|
|
opoo "Formula will not build with LLVM, trying Clang"
|
2012-02-21 00:17:19 -06:00
|
|
|
ENV.clang
|
2012-01-16 20:05:51 +00:00
|
|
|
end
|
2011-09-01 14:32:38 +01:00
|
|
|
return
|
|
|
|
end
|
2011-09-01 09:39:54 +01:00
|
|
|
opoo "Building with LLVM, but this formula is reported to not work with LLVM:"
|
2011-08-26 16:45:06 +01:00
|
|
|
puts
|
2011-08-26 14:21:37 +01:00
|
|
|
puts llvm.reason
|
|
|
|
puts
|
2011-09-01 09:39:54 +01:00
|
|
|
puts <<-EOS.undent
|
|
|
|
We are continuing anyway so if the build succeeds, please open a ticket with
|
|
|
|
the following information: #{MacOS.llvm_build_version}-#{MACOS_VERSION}. So
|
|
|
|
that we can update the formula accordingly. Thanks!
|
|
|
|
EOS
|
|
|
|
puts
|
2011-12-04 10:12:40 -08:00
|
|
|
if MacOS.xcode_version < "4.2"
|
2011-10-25 11:55:09 -07:00
|
|
|
puts "If it doesn't work you can: brew install --use-gcc"
|
|
|
|
else
|
|
|
|
puts "If it doesn't work you can try: brew install --use-clang"
|
|
|
|
end
|
2011-08-26 14:21:37 +01:00
|
|
|
puts
|
2010-09-22 08:12:03 -07:00
|
|
|
end
|
|
|
|
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
|
|
|
|
|
|
|
|
# an array of all Formula, instantiated
|
|
|
|
def self.all
|
2010-09-11 20:22:54 +01:00
|
|
|
map{ |f| f }
|
|
|
|
end
|
|
|
|
def self.map
|
|
|
|
rv = []
|
|
|
|
each{ |f| rv << yield(f) }
|
|
|
|
rv
|
|
|
|
end
|
|
|
|
def self.each
|
2010-07-18 14:07:40 -07:00
|
|
|
names.each do |n|
|
|
|
|
begin
|
2010-09-11 20:22:54 +01:00
|
|
|
yield Formula.factory(n)
|
2010-07-18 14:07:40 -07:00
|
|
|
rescue
|
2011-03-11 14:54:26 -08:00
|
|
|
# Don't let one broken formula break commands. But do complain.
|
|
|
|
onoe "Formula #{n} will not import."
|
2010-07-18 14:07:40 -07:00
|
|
|
end
|
|
|
|
end
|
2010-09-11 20:22:54 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
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
|
|
|
# Cast pathnames to strings.
|
|
|
|
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? "/"
|
|
|
|
# Don't resolve paths or URLs
|
|
|
|
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
|
2011-06-08 11:13:50 -07:00
|
|
|
target_file = HOMEBREW_CACHE_FORMULA+name
|
2010-09-22 07:54:53 -07:00
|
|
|
name = name.basename(".rb").to_s
|
|
|
|
|
2011-06-08 11:13:50 -07:00
|
|
|
HOMEBREW_CACHE_FORMULA.mkpath
|
2010-09-22 07:54:53 -07:00
|
|
|
FileUtils.rm target_file, :force => true
|
|
|
|
curl url, '-o', target_file
|
|
|
|
|
|
|
|
require target_file
|
|
|
|
install_type = :from_url
|
2009-09-04 15:28:18 +01:00
|
|
|
else
|
2011-06-08 11:13:50 -07:00
|
|
|
name = Formula.canonical_name(name)
|
|
|
|
# If name was a path or mapped to a cached formula
|
2011-03-12 16:37:56 -08:00
|
|
|
if name.include? "/"
|
2010-09-22 07:54:53 -07:00
|
|
|
require name
|
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
|
2010-11-04 13:53:03 -07:00
|
|
|
target_file = path.to_s
|
2010-09-22 07:54:53 -07:00
|
|
|
else
|
|
|
|
# For names, map to the path and then require
|
2010-09-11 20:22:54 +01:00
|
|
|
require 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
|
|
|
|
2009-09-23 10:06:19 -07:00
|
|
|
begin
|
2010-07-04 14:17:03 -07:00
|
|
|
klass_name = self.class_s(name)
|
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
|
|
|
|
|
|
|
return klass.new(name) if install_type == :from_name
|
|
|
|
return klass.new(name, target_file)
|
2011-06-08 11:34:01 -07:00
|
|
|
rescue LoadError
|
2009-08-21 20:20:44 +01:00
|
|
|
raise FormulaUnavailableError.new(name)
|
|
|
|
end
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2011-09-11 15:23:41 -07:00
|
|
|
def mirrors
|
|
|
|
self.class.mirrors or []
|
|
|
|
end
|
|
|
|
|
2009-09-18 19:16:39 +01:00
|
|
|
def deps
|
|
|
|
self.class.deps or []
|
|
|
|
end
|
|
|
|
|
2010-01-13 09:00:24 +00:00
|
|
|
def external_deps
|
2010-09-11 20:22:54 +01:00
|
|
|
self.class.external_deps or {}
|
|
|
|
end
|
|
|
|
|
|
|
|
# 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|
|
|
|
|
dep = Formula.factory dep
|
|
|
|
expand_deps(dep) << dep
|
|
|
|
end
|
2010-01-13 09:00:24 +00:00
|
|
|
end
|
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
protected
|
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
|
|
|
|
pretty_args.delete "--disable-dependency-tracking" if cmd == "./configure" and not ARGV.verbose?
|
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
|
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
|
|
|
|
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
|
2009-11-06 17:09:14 +00:00
|
|
|
out = ''
|
2009-11-09 17:45:22 +00:00
|
|
|
out << rd.read until rd.eof?
|
2009-11-07 18:23:21 +00:00
|
|
|
Process.wait
|
2009-11-06 17:09:14 +00:00
|
|
|
unless $?.success?
|
2009-08-10 16:48:30 +01:00
|
|
|
puts out
|
|
|
|
raise
|
|
|
|
end
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
2011-09-10 11:24:29 +01:00
|
|
|
|
|
|
|
removed_ENV_variables.each do |key, value|
|
|
|
|
ENV[key] = value # ENV.kind_of? Hash # => false
|
|
|
|
end if removed_ENV_variables
|
|
|
|
|
2010-07-04 14:17:03 -07:00
|
|
|
rescue
|
2010-09-11 20:22:54 +01:00
|
|
|
raise BuildError.new(self, cmd, args, $?)
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
2009-07-24 15:10:01 +01:00
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
private
|
2010-07-04 14:17:03 -07:00
|
|
|
# Create a temporary directory then yield. When the block returns,
|
|
|
|
# recursively delete the temporary directory.
|
2009-08-10 16:48:30 +01:00
|
|
|
def mktemp
|
2010-07-04 14:17:03 -07:00
|
|
|
# I used /tmp rather than `mktemp -td` because that generates a directory
|
2009-08-23 17:57:45 +01:00
|
|
|
# name with exotic characters like + in it, and these break badly written
|
|
|
|
# scripts that don't escape strings before trying to regexp them :(
|
2010-05-01 14:06:23 -07:00
|
|
|
|
|
|
|
# If the user has FileVault enabled, then we can't mv symlinks from the
|
|
|
|
# /tmp volume to the other volume. So we let the user override the tmp
|
|
|
|
# prefix if they need to.
|
|
|
|
tmp_prefix = ENV['HOMEBREW_TEMP'] || '/tmp'
|
|
|
|
tmp=Pathname.new `/usr/bin/mktemp -d #{tmp_prefix}/homebrew-#{name}-#{version}-XXXX`.strip
|
2009-08-23 17:57:45 +01:00
|
|
|
raise "Couldn't create build sandbox" if not tmp.directory? or $? != 0
|
2009-08-10 16:48:30 +01:00
|
|
|
begin
|
|
|
|
wd=Dir.pwd
|
|
|
|
Dir.chdir tmp
|
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
Dir.chdir wd
|
|
|
|
tmp.rmtree
|
|
|
|
end
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
|
|
|
|
2009-09-07 16:10:50 +02:00
|
|
|
CHECKSUM_TYPES=[:md5, :sha1, :sha256].freeze
|
|
|
|
|
2011-09-11 15:23:41 -07:00
|
|
|
public
|
|
|
|
# For brew-fetch and others.
|
|
|
|
def fetch
|
|
|
|
downloader = @downloader
|
2011-10-04 18:35:14 -07:00
|
|
|
# Don't attempt mirrors if this install is not pointed at a "stable" URL.
|
|
|
|
# This can happen when options like `--HEAD` are invoked.
|
2012-01-22 22:32:15 -06:00
|
|
|
mirror_list = @spec_to_use == @standard ? mirrors : []
|
2011-09-11 15:23:41 -07:00
|
|
|
|
2011-09-19 19:05:44 -07:00
|
|
|
# Ensure the cache exists
|
|
|
|
HOMEBREW_CACHE.mkpath
|
|
|
|
|
2011-09-11 15:23:41 -07:00
|
|
|
begin
|
|
|
|
fetched = downloader.fetch
|
2011-09-19 23:29:07 +01:00
|
|
|
rescue CurlDownloadStrategyError => e
|
2011-09-11 15:23:41 -07:00
|
|
|
raise e if mirror_list.empty?
|
2011-09-19 23:29:07 +01:00
|
|
|
puts "Trying a mirror..."
|
2011-09-11 15:23:41 -07:00
|
|
|
url, specs = mirror_list.shift.values_at :url, :specs
|
|
|
|
downloader = download_strategy.new url, name, version, specs
|
|
|
|
retry
|
|
|
|
end
|
2011-08-24 01:13:15 +01:00
|
|
|
|
2011-09-11 15:23:41 -07:00
|
|
|
return fetched, downloader
|
|
|
|
end
|
|
|
|
|
2011-12-17 17:01:21 -08:00
|
|
|
# Detect which type of checksum is being used, or nil if none
|
|
|
|
def checksum_type
|
|
|
|
CHECKSUM_TYPES.detect { |type| instance_variable_defined?("@#{type}") }
|
|
|
|
end
|
|
|
|
|
2011-09-11 15:23:41 -07:00
|
|
|
# For FormulaInstaller.
|
2011-08-24 01:13:15 +01:00
|
|
|
def verify_download_integrity fn, *args
|
2009-07-31 11:05:23 -07:00
|
|
|
require 'digest'
|
2011-08-24 17:33:28 -07:00
|
|
|
if args.length != 2
|
2011-12-17 17:01:21 -08:00
|
|
|
type = checksum_type || :md5
|
|
|
|
supplied = instance_variable_get("@#{type}")
|
|
|
|
# Convert symbol to readable string
|
|
|
|
type = type.to_s.upcase
|
2010-11-24 09:40:37 +00:00
|
|
|
else
|
2011-08-24 01:13:15 +01:00
|
|
|
supplied, type = args
|
2010-11-24 09:40:37 +00:00
|
|
|
end
|
|
|
|
|
2010-03-23 19:56:20 -05:00
|
|
|
hasher = Digest.const_get(type)
|
2010-03-27 10:41:24 -05:00
|
|
|
hash = fn.incremental_hash(hasher)
|
2009-07-31 11:05:23 -07:00
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
if supplied and not supplied.empty?
|
2010-06-18 13:42:12 -07:00
|
|
|
message = <<-EOF
|
|
|
|
#{type} mismatch
|
|
|
|
Expected: #{supplied}
|
|
|
|
Got: #{hash}
|
|
|
|
Archive: #{fn}
|
|
|
|
(To retry an incomplete download, remove the file above.)
|
|
|
|
EOF
|
|
|
|
raise message unless supplied.upcase == hash.upcase
|
2009-07-31 11:05:23 -07:00
|
|
|
else
|
|
|
|
opoo "Cannot verify package integrity"
|
|
|
|
puts "The formula did not provide a download checksum"
|
2009-08-11 12:20:55 -07:00
|
|
|
puts "For your reference the #{type} is: #{hash}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-08-24 01:13:15 +01: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
|
2011-08-24 01:13:15 +01:00
|
|
|
return if patches.nil?
|
2009-09-15 20:07:40 +01:00
|
|
|
|
2009-09-09 11:59:46 -04:00
|
|
|
if not patches.kind_of? Hash
|
2009-11-13 14:27:21 -05:00
|
|
|
# We assume -p1
|
2009-09-16 17:08:32 +01:00
|
|
|
patch_defns = { :p1 => patches }
|
2009-09-09 11:59:46 -04:00
|
|
|
else
|
|
|
|
patch_defns = patches
|
|
|
|
end
|
|
|
|
|
|
|
|
patch_list=[]
|
|
|
|
n=0
|
|
|
|
patch_defns.each do |arg, urls|
|
2009-09-16 17:08:32 +01:00
|
|
|
# DATA.each does each line, which doesn't work so great
|
|
|
|
urls = [urls] unless urls.kind_of? Array
|
|
|
|
|
2009-09-09 11:59:46 -04:00
|
|
|
urls.each do |url|
|
2009-09-04 15:28:18 +01:00
|
|
|
p = {:filename => '%03d-homebrew.diff' % n+=1, :compression => false}
|
2009-09-15 20:07:40 +01:00
|
|
|
|
2009-09-04 15:28:18 +01:00
|
|
|
if defined? DATA and url == DATA
|
2011-08-23 23:25:47 +01:00
|
|
|
pn = Pathname.new p[:filename]
|
|
|
|
pn.write(DATA.read.to_s.gsub("HOMEBREW_PREFIX", HOMEBREW_PREFIX))
|
2009-09-04 15:28:18 +01:00
|
|
|
elsif url =~ %r[^\w+\://]
|
2009-09-15 20:07:40 +01:00
|
|
|
out_fn = p[:filename]
|
|
|
|
case url
|
|
|
|
when /\.gz$/
|
|
|
|
p[:compression] = :gzip
|
2009-09-04 15:28:18 +01:00
|
|
|
out_fn += '.gz'
|
2009-09-15 20:07:40 +01:00
|
|
|
when /\.bz2$/
|
|
|
|
p[:compression] = :bzip2
|
2009-09-04 15:28:18 +01:00
|
|
|
out_fn += '.bz2'
|
2009-09-15 20:07:40 +01:00
|
|
|
end
|
|
|
|
p[:curl_args] = [url, '-o', out_fn]
|
|
|
|
else
|
|
|
|
# it's a file on the local filesystem
|
|
|
|
p[:filename] = url
|
2009-08-11 18:16:12 +01:00
|
|
|
end
|
2009-09-15 20:07:40 +01:00
|
|
|
|
|
|
|
p[:args] = ["-#{arg}", '-i', p[:filename]]
|
|
|
|
|
|
|
|
patch_list << p
|
2009-08-11 18:16:12 +01:00
|
|
|
end
|
2009-09-09 11:59:46 -04:00
|
|
|
end
|
2010-07-04 14:17:03 -07:00
|
|
|
|
2009-09-04 15:28:18 +01:00
|
|
|
return if patch_list.empty?
|
2009-09-15 20:07:40 +01:00
|
|
|
|
2011-08-29 14:55:28 -07:00
|
|
|
external_patches = patch_list.collect{|p| p[:curl_args]}.select{|p| p}.flatten
|
|
|
|
unless external_patches.empty?
|
|
|
|
ohai "Downloading patches"
|
|
|
|
# downloading all at once is much more efficient, especially for FTP
|
|
|
|
curl(*external_patches)
|
|
|
|
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|
|
|
|
|
case p[:compression]
|
2009-09-23 16:44:10 +01:00
|
|
|
when :gzip then safe_system "/usr/bin/gunzip", p[:filename]+'.gz'
|
|
|
|
when :bzip2 then safe_system "/usr/bin/bunzip2", p[:filename]+'.bz2'
|
2009-08-11 18:16:12 +01:00
|
|
|
end
|
2009-09-09 11:59:46 -04:00
|
|
|
# -f means it doesn't prompt the user if there are errors, if just
|
|
|
|
# exits with non-zero status
|
2009-09-23 16:44:10 +01:00
|
|
|
safe_system '/usr/bin/patch', '-f', *(p[: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}")
|
2009-08-30 16:11:44 +01:00
|
|
|
raise "Invalid @#{name}" if v.to_s.empty? or v =~ /\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)
|
2009-11-23 10:07:23 -08:00
|
|
|
unless instance_variable_defined? "@#{type}"
|
2009-09-22 13:03:46 -04:00
|
|
|
class_value = self.class.send(type)
|
|
|
|
instance_variable_set("@#{type}", class_value) if class_value
|
|
|
|
end
|
|
|
|
end
|
2009-08-22 17:26:15 +01:00
|
|
|
|
2009-07-31 14:17:56 +01:00
|
|
|
def method_added method
|
|
|
|
raise 'You cannot override Formula.brew' if method == 'brew'
|
|
|
|
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.
|
2012-01-22 22:32:15 -06:00
|
|
|
attr_reader :standard, :unstable
|
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
|
|
|
|
2011-09-11 15:23:41 -07:00
|
|
|
attr_rw :version, :homepage, :mirrors, :specs, :deps, :external_deps
|
2011-03-21 14:23:28 -07:00
|
|
|
attr_rw :keg_only_reason, :fails_with_llvm_reason, :skip_clean_all
|
2012-01-22 22:32:15 -06:00
|
|
|
attr_rw :bottle_url, :bottle_sha1
|
2010-10-25 21:12:31 -07:00
|
|
|
attr_rw(*CHECKSUM_TYPES)
|
2009-10-17 14:35:24 +02:00
|
|
|
|
|
|
|
def head val=nil, specs=nil
|
2010-07-04 14:17:03 -07:00
|
|
|
return @head if val.nil?
|
|
|
|
@unstable = SoftwareSpecification.new(val, specs)
|
|
|
|
@head = val
|
|
|
|
@specs = specs
|
|
|
|
end
|
|
|
|
|
|
|
|
def url val=nil, specs=nil
|
|
|
|
return @url if val.nil?
|
2012-01-22 22:32:15 -06:00
|
|
|
@standard = SoftwareSpecification.new(val, specs)
|
2010-07-04 14:17:03 -07:00
|
|
|
@url = val
|
|
|
|
@specs = 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
|
|
|
|
raise "url and md5 must be specified in a block" unless block_given?
|
|
|
|
instance_eval &block unless ARGV.build_devel? or ARGV.build_head?
|
|
|
|
end
|
|
|
|
|
|
|
|
def devel &block
|
|
|
|
raise "url and md5 must be specified in a block" unless block_given?
|
2012-02-02 13:12:09 -06:00
|
|
|
|
|
|
|
if ARGV.build_devel?
|
|
|
|
# clear out mirrors from the stable release
|
|
|
|
@mirrors = nil
|
|
|
|
|
|
|
|
instance_eval &block
|
|
|
|
end
|
2012-01-22 22:32:15 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
def bottle url=nil, &block
|
|
|
|
if block_given?
|
|
|
|
eval <<-EOCLASS
|
|
|
|
module BottleData
|
|
|
|
def self.url url; @url = url; end
|
|
|
|
def self.sha1 sha1; @sha1 = sha1; end
|
|
|
|
def self.return_data; [@url,@sha1]; end
|
|
|
|
end
|
|
|
|
EOCLASS
|
|
|
|
BottleData.instance_eval &block
|
|
|
|
@bottle_url, @bottle_sha1 = BottleData.return_data
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-09-11 15:23:41 -07:00
|
|
|
def mirror val, specs=nil
|
|
|
|
@mirrors ||= []
|
|
|
|
@mirrors << {:url => val, :specs => specs}
|
|
|
|
# Added the uniq after some inspection with Pry---seems `mirror` gets
|
|
|
|
# called three times. The first two times only one copy of the input is
|
|
|
|
# left in `@mirrors`. On the final call, two copies are present. This
|
|
|
|
# happens with `@deps` as well. Odd.
|
|
|
|
@mirrors.uniq!
|
|
|
|
end
|
|
|
|
|
2010-01-13 09:00:24 +00:00
|
|
|
def depends_on name
|
2009-09-18 19:16:39 +01:00
|
|
|
@deps ||= []
|
2011-11-05 19:40:21 -04:00
|
|
|
@external_deps ||= {:python => [], :perl => [], :ruby => [], :jruby => [], :chicken => [], :rbx => [], :node => []}
|
2009-09-18 19:16:39 +01:00
|
|
|
|
|
|
|
case name
|
2010-07-20 12:27:28 -07:00
|
|
|
when String, Formula
|
|
|
|
@deps << name
|
2009-09-18 19:16:39 +01:00
|
|
|
when Hash
|
2010-01-13 09:00:24 +00:00
|
|
|
key, value = name.shift
|
|
|
|
case value
|
2011-11-05 19:40:21 -04:00
|
|
|
when :python, :perl, :ruby, :jruby, :chicken, :rbx, :node
|
2010-01-13 09:00:24 +00:00
|
|
|
@external_deps[value] << key
|
2010-09-19 10:26:01 -07:00
|
|
|
when :optional, :recommended, :build
|
2010-07-20 12:27:28 -07:00
|
|
|
@deps << key
|
2010-09-19 10:53:39 -07:00
|
|
|
else
|
|
|
|
raise "Unsupported dependency type #{value}"
|
2010-01-13 09:00:24 +00:00
|
|
|
end
|
2009-09-18 19:16:39 +01:00
|
|
|
when Symbol
|
2010-07-20 12:27:28 -07:00
|
|
|
opoo "#{self.name} -- #{name}: Using symbols for deps is deprecated; use a string instead"
|
|
|
|
@deps << name.to_s
|
2009-09-18 19:16:39 +01:00
|
|
|
else
|
|
|
|
raise "Unsupported type #{name.class}"
|
|
|
|
end
|
|
|
|
end
|
2009-09-28 14:06:53 -07:00
|
|
|
|
|
|
|
def skip_clean paths
|
2010-07-25 15:53:39 -07:00
|
|
|
if paths == :all
|
|
|
|
@skip_clean_all = true
|
|
|
|
return
|
|
|
|
end
|
2009-09-28 14:06:53 -07:00
|
|
|
@skip_clean_paths ||= []
|
|
|
|
[paths].flatten.each do |p|
|
|
|
|
@skip_clean_paths << p.to_s unless @skip_clean_paths.include? p.to_s
|
|
|
|
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
|
|
|
|
|
|
|
def fails_with_llvm msg=nil, data=nil
|
|
|
|
@fails_with_llvm_reason = FailsWithLLVM.new(msg, data)
|
|
|
|
end
|
2009-09-28 14:06:53 -07:00
|
|
|
end
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
# see ack.rb for an example usage
|
2011-03-12 17:48:48 -08:00
|
|
|
class ScriptFileFormula < Formula
|
2009-07-24 15:10:01 +01:00
|
|
|
def install
|
2009-08-11 12:20:55 -07:00
|
|
|
bin.install Dir['*']
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
# see flac.rb for example usage
|
2011-03-12 17:48:48 -08:00
|
|
|
class GithubGistFormula < ScriptFileFormula
|
2010-12-22 17:08:38 -08:00
|
|
|
def initialize name='__UNKNOWN__', path=nil
|
2011-03-20 13:56:31 +09:00
|
|
|
super name, path
|
2009-08-30 15:32:15 +01:00
|
|
|
@version=File.basename(File.dirname(url))[0,6]
|
2009-07-24 15:10:01 +01:00
|
|
|
end
|
|
|
|
end
|