2012-02-04 18:45:08 -08:00
|
|
|
require 'download_strategy'
|
2012-06-18 19:58:35 -05:00
|
|
|
require 'checksums'
|
2012-02-04 18:45:08 -08:00
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
class SoftwareSpec
|
2012-06-25 21:39:28 -05:00
|
|
|
attr_reader :checksum, :mirrors, :specs
|
2012-02-04 18:45:08 -08:00
|
|
|
|
2012-06-26 12:44:43 -05:00
|
|
|
def initialize url=nil, version=nil
|
|
|
|
@url = url
|
|
|
|
@version = version
|
2012-07-05 13:11:44 -05:00
|
|
|
@mirrors = []
|
2012-06-26 12:44:43 -05:00
|
|
|
end
|
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
# Was the version defined in the DSL, or detected from the URL?
|
|
|
|
def explicit_version?
|
|
|
|
@explicit_version || false
|
|
|
|
end
|
|
|
|
|
2012-02-04 18:45:08 -08:00
|
|
|
def download_strategy
|
2012-06-25 21:39:28 -05:00
|
|
|
@download_strategy ||= DownloadStrategyDetector.new(@url, @using).detect
|
2012-02-04 18:45:08 -08:00
|
|
|
end
|
|
|
|
|
2012-06-18 19:58:35 -05:00
|
|
|
def verify_download_integrity fn
|
|
|
|
fn.verify_checksum @checksum
|
|
|
|
rescue ChecksumMissingError
|
|
|
|
opoo "Cannot verify package integrity"
|
|
|
|
puts "The formula did not provide a download checksum"
|
|
|
|
puts "For your reference the SHA1 is: #{fn.sha1}"
|
|
|
|
rescue ChecksumMismatchError => e
|
|
|
|
e.advice = <<-EOS.undent
|
|
|
|
Archive: #{fn}
|
|
|
|
(To retry an incomplete download, remove the file above.)
|
|
|
|
EOS
|
|
|
|
raise e
|
|
|
|
end
|
|
|
|
|
2012-04-05 21:09:24 -05:00
|
|
|
# The methods that follow are used in the block-form DSL spec methods
|
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)
|
2012-06-18 19:58:35 -05:00
|
|
|
if val.nil?
|
|
|
|
@checksum if @checksum.nil? or @checksum.hash_type == :#{cksum}
|
|
|
|
else
|
|
|
|
@checksum = Checksum.new(:#{cksum}, val)
|
|
|
|
end
|
2012-04-05 21:09:24 -05:00
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def url val=nil, specs=nil
|
|
|
|
return @url if val.nil?
|
|
|
|
@url = val
|
|
|
|
if specs.nil?
|
2012-06-25 21:39:28 -05:00
|
|
|
@using = nil
|
2012-04-05 21:09:24 -05:00
|
|
|
else
|
2012-06-25 21:39:28 -05:00
|
|
|
@using = specs.delete :using
|
2012-04-05 21:09:24 -05:00
|
|
|
@specs = specs
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def version val=nil
|
|
|
|
unless val.nil?
|
|
|
|
@version = val
|
|
|
|
@explicit_version = true
|
|
|
|
end
|
|
|
|
@version ||= Pathname.new(@url).version
|
|
|
|
return @version
|
|
|
|
end
|
|
|
|
|
2012-06-26 01:35:37 -05:00
|
|
|
def mirror val
|
2012-04-05 21:09:24 -05:00
|
|
|
@mirrors ||= []
|
2012-06-26 01:35:37 -05:00
|
|
|
@mirrors << val
|
2012-04-05 21:09:24 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class HeadSoftwareSpec < SoftwareSpec
|
2012-06-26 12:44:43 -05:00
|
|
|
def initialize url=nil, version='HEAD'
|
2012-04-05 21:09:24 -05:00
|
|
|
super
|
|
|
|
end
|
|
|
|
|
|
|
|
def verify_download_integrity fn
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Bottle < SoftwareSpec
|
|
|
|
attr_writer :url
|
|
|
|
attr_reader :revision
|
|
|
|
|
2012-06-26 12:44:43 -05:00
|
|
|
def initialize url=nil, version=nil
|
2012-06-18 19:58:35 -05:00
|
|
|
super
|
2012-04-05 21:09:24 -05:00
|
|
|
@revision = 0
|
|
|
|
end
|
|
|
|
|
|
|
|
# Checksum methods in the DSL's bottle block optionally take
|
|
|
|
# a Hash, which indicates the platform the checksum applies on.
|
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)
|
|
|
|
@#{cksum} ||= Hash.new
|
|
|
|
case val
|
|
|
|
when nil
|
|
|
|
@#{cksum}[MacOS.cat]
|
|
|
|
when String
|
2012-06-18 19:58:35 -05:00
|
|
|
@#{cksum}[:lion] = Checksum.new(:#{cksum}, val)
|
2012-04-05 21:09:24 -05:00
|
|
|
when Hash
|
|
|
|
key, value = val.shift
|
2012-06-18 19:58:35 -05:00
|
|
|
@#{cksum}[value] = Checksum.new(:#{cksum}, key)
|
2012-04-05 21:09:24 -05:00
|
|
|
end
|
2012-06-18 19:58:35 -05:00
|
|
|
|
|
|
|
@checksum = @#{cksum}[MacOS.cat] if @#{cksum}.has_key? MacOS.cat
|
2012-04-05 21:09:24 -05:00
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def url val=nil
|
|
|
|
val.nil? ? @url : @url = val
|
|
|
|
end
|
|
|
|
|
|
|
|
# Used in the bottle DSL to set @revision, but acts as an
|
|
|
|
# as accessor for @version to preserve the interface
|
|
|
|
def version val=nil
|
|
|
|
if val.nil?
|
|
|
|
return @version ||= Pathname.new(@url).version
|
|
|
|
else
|
|
|
|
@revision = val
|
|
|
|
end
|
2012-02-04 18:45:08 -08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
# Used to annotate formulae that duplicate OS X provided software
|
|
|
|
# or cause conflicts when linked in.
|
|
|
|
class KegOnlyReason
|
|
|
|
attr_reader :reason, :explanation
|
|
|
|
|
|
|
|
def initialize reason, explanation=nil
|
|
|
|
@reason = reason
|
|
|
|
@explanation = explanation
|
2012-08-09 02:00:58 -05:00
|
|
|
@valid = case @reason
|
|
|
|
when :when_xquartz_installed then MacOS::XQuartz.installed?
|
|
|
|
else true
|
|
|
|
end
|
2012-02-04 18:45:08 -08:00
|
|
|
end
|
|
|
|
|
2012-08-09 02:00:58 -05:00
|
|
|
def valid?
|
|
|
|
@valid
|
|
|
|
end
|
2012-02-04 18:45:08 -08:00
|
|
|
|
2012-08-09 02:00:58 -05:00
|
|
|
def to_s
|
|
|
|
case @reason
|
|
|
|
when :provided_by_osx then <<-EOS.undent
|
|
|
|
Mac OS X already provides this software and installing another version in
|
|
|
|
parallel can cause all kinds of trouble.
|
|
|
|
|
|
|
|
#{@explanation}
|
|
|
|
EOS
|
|
|
|
when :when_xquartz_installed then <<-EOS.undent
|
|
|
|
XQuartz provides this software.
|
|
|
|
|
|
|
|
#{@explanation}
|
|
|
|
EOS
|
2012-02-04 18:45:08 -08:00
|
|
|
else
|
2012-08-09 02:00:58 -05:00
|
|
|
@reason
|
|
|
|
end.strip
|
2012-02-04 18:45:08 -08:00
|
|
|
end
|
|
|
|
end
|
2012-07-30 11:32:56 -07:00
|
|
|
|
|
|
|
|
|
|
|
# This class holds the build-time options defined for a Formula,
|
|
|
|
# and provides named access to those options during install.
|
|
|
|
class BuildOptions
|
2012-08-12 13:37:40 -05:00
|
|
|
include Enumerable
|
2012-07-30 11:32:56 -07:00
|
|
|
|
|
|
|
def initialize args
|
|
|
|
# Take a copy of the args (any string array, actually)
|
|
|
|
@args = Array.new(args)
|
|
|
|
# Extend it into an ARGV extension
|
|
|
|
@args.extend(HomebrewArgvExtension)
|
2012-08-12 00:58:48 -05:00
|
|
|
@options = Set.new
|
2012-07-30 11:32:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def add name, description=nil
|
|
|
|
if description.nil?
|
|
|
|
case name
|
|
|
|
when :universal, "universal"
|
2012-08-09 21:35:56 -07:00
|
|
|
description = "Build a universal binary"
|
2012-07-30 11:32:56 -07:00
|
|
|
when "32-bit"
|
2012-08-09 21:35:56 -07:00
|
|
|
description = "Build 32-bit only"
|
2012-07-30 11:32:56 -07:00
|
|
|
else
|
|
|
|
description = ""
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
@options << [name, description]
|
|
|
|
end
|
|
|
|
|
|
|
|
def has_option? name
|
2012-08-12 13:37:40 -05:00
|
|
|
@options.any? { |opt, _| opt == name }
|
2012-07-30 11:32:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def empty?
|
|
|
|
@options.empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
def each
|
2012-08-12 13:37:40 -05:00
|
|
|
@options.each { |opt, desc| yield opt, desc }
|
2012-07-30 11:32:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def include? name
|
|
|
|
@args.include? '--' + name
|
|
|
|
end
|
|
|
|
|
|
|
|
def head?
|
|
|
|
@args.flag? '--HEAD'
|
|
|
|
end
|
|
|
|
|
|
|
|
def devel?
|
|
|
|
@args.include? '--devel'
|
|
|
|
end
|
|
|
|
|
|
|
|
def stable?
|
|
|
|
not (head? or devel?)
|
|
|
|
end
|
|
|
|
|
|
|
|
# True if the user requested a universal build.
|
|
|
|
def universal?
|
|
|
|
@args.include? '--universal'
|
|
|
|
end
|
|
|
|
|
|
|
|
# Request a 32-bit only build.
|
|
|
|
# This is needed for some use-cases though we prefer to build Universal
|
|
|
|
# when a 32-bit version is needed.
|
|
|
|
def build_32_bit?
|
|
|
|
@args.include? '--32-bit'
|
|
|
|
end
|
|
|
|
end
|