Dependency resolution with fancy syntax
Is it a DSL? No. But people call it that apparently. To add a dependency: class Doe <Formula depends_on 'ray' depends_on 'mee' => :optional depends_on 'far' => :recommended depends_on Sew.new end Sew would be a formula you have defined in this Formula file. This is useful, eg. see Python's formula. Formula specified in this fashion cannot be linked into the HOMEBREW_PREFIX, they are considered private libraries. This allows you to create custom installations that are very specific to your formula. More features to come, like specifying versions
This commit is contained in:
parent
a793e30405
commit
77dd27e8e6
@ -144,31 +144,12 @@ def clean f
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# NOTE this is ugly code, and inefficient too, and can have infinite cycles
|
def expand_deps ff
|
||||||
# I have no time currently to improve it, feel free to submit a more elegant
|
|
||||||
# solution. Thanks! --mxcl
|
|
||||||
def expand_deps fae
|
|
||||||
deps = []
|
deps = []
|
||||||
fae.each do |f|
|
ff.deps.collect do |f|
|
||||||
case f.deps
|
deps += expand_deps(Formula.factory(f))
|
||||||
when String, Array
|
|
||||||
f.deps.each do |name|
|
|
||||||
f = Formula.factory name
|
|
||||||
deps << expand_deps(f) if f.deps # hideous inefficient
|
|
||||||
deps << f unless f.installed?
|
|
||||||
end
|
|
||||||
when Hash
|
|
||||||
# TODO implement optional and recommended
|
|
||||||
names = []
|
|
||||||
f.deps.each_value {|v| names << v}
|
|
||||||
ff=names.flatten.collect {|name| Formula.factory name}
|
|
||||||
deps << expand_deps(ff)
|
|
||||||
end
|
|
||||||
deps << f
|
|
||||||
end
|
end
|
||||||
|
deps << ff
|
||||||
# TODO much more efficient to use a set and not recurse stuff already done
|
|
||||||
return deps.flatten.uniq
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -114,8 +114,6 @@ class Formula
|
|||||||
# :p2 => ['http://moo.com/patch5', 'http://moo.com/patch6']
|
# :p2 => ['http://moo.com/patch5', 'http://moo.com/patch6']
|
||||||
# }
|
# }
|
||||||
def patches; [] end
|
def patches; [] end
|
||||||
# reimplement and specify dependencies
|
|
||||||
def deps; end
|
|
||||||
# sometimes the clean process breaks things, return true to skip anything
|
# sometimes the clean process breaks things, return true to skip anything
|
||||||
def skip_clean? path; false end
|
def skip_clean? path; false end
|
||||||
|
|
||||||
@ -157,6 +155,7 @@ class Formula
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.factory name
|
def self.factory name
|
||||||
|
return name if name.kind_of? Formula
|
||||||
require self.path(name)
|
require self.path(name)
|
||||||
return eval(self.class(name)).new(name)
|
return eval(self.class(name)).new(name)
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
@ -167,6 +166,10 @@ class Formula
|
|||||||
HOMEBREW_PREFIX+'Library'+'Formula'+"#{name.downcase}.rb"
|
HOMEBREW_PREFIX+'Library'+'Formula'+"#{name.downcase}.rb"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def deps
|
||||||
|
self.class.deps or []
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
# Pretty titles the command and buffers stdout/stderr
|
# Pretty titles the command and buffers stdout/stderr
|
||||||
# Throws if there's an error
|
# Throws if there's an error
|
||||||
@ -280,9 +283,31 @@ private
|
|||||||
end
|
end
|
||||||
|
|
||||||
class <<self
|
class <<self
|
||||||
attr_reader :url, :version, :homepage, :head
|
attr_reader :url, :version, :homepage, :head, :deps
|
||||||
attr_reader *CHECKSUM_TYPES
|
attr_reader *CHECKSUM_TYPES
|
||||||
end
|
|
||||||
|
def depends_on name, *args
|
||||||
|
@deps ||= []
|
||||||
|
|
||||||
|
case name
|
||||||
|
when String
|
||||||
|
# noop
|
||||||
|
when Hash
|
||||||
|
name = name.keys.first # indeed, we only support one mapping
|
||||||
|
when Symbol
|
||||||
|
name = name.to_s
|
||||||
|
when Formula
|
||||||
|
@deps << name
|
||||||
|
return # we trust formula dev to not dupe their own instantiations
|
||||||
|
else
|
||||||
|
raise "Unsupported type #{name.class}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# we get duplicates because every new fork of this process repeats this
|
||||||
|
# step for some reason I am not sure about
|
||||||
|
@deps << name unless @deps.include? name
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# see ack.rb for an example usage
|
# see ack.rb for an example usage
|
||||||
|
|||||||
23
bin/brew
23
bin/brew
@ -38,6 +38,7 @@ unless system "which -s gcc-4.2" and $?.success?
|
|||||||
abort "Sorry, Homebrew requires gcc 4.2, which is provided by Xcode 3.1"
|
abort "Sorry, Homebrew requires gcc 4.2, which is provided by Xcode 3.1"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
case ARGV.shift
|
case ARGV.shift
|
||||||
when '--prefix' then puts HOMEBREW_PREFIX
|
when '--prefix' then puts HOMEBREW_PREFIX
|
||||||
@ -104,7 +105,7 @@ begin
|
|||||||
unless system "which #{ENV['CC'] or 'cc'} &> /dev/null" and $?.success?
|
unless system "which #{ENV['CC'] or 'cc'} &> /dev/null" and $?.success?
|
||||||
raise "We cannot find a c compiler, have you installed the latest Xcode?"
|
raise "We cannot find a c compiler, have you installed the latest Xcode?"
|
||||||
end
|
end
|
||||||
fae = ARGV.formulae.reject do |f|
|
formulae = ARGV.formulae.reject do |f|
|
||||||
if f.installed?
|
if f.installed?
|
||||||
message = "Formula already installed: #{f.prefix}"
|
message = "Formula already installed: #{f.prefix}"
|
||||||
if ARGV.formulae.count > 1
|
if ARGV.formulae.count > 1
|
||||||
@ -115,20 +116,24 @@ begin
|
|||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
exit 0 if fae.empty?
|
exit 0 if formulae.empty?
|
||||||
else
|
else
|
||||||
fae=ARGV.formulae
|
formulae = ARGV.formulae
|
||||||
end
|
end
|
||||||
|
|
||||||
# the resulting order will be optimal for super-deps and deps
|
deps = []
|
||||||
fae=expand_deps fae
|
formulae.each { |f| deps += expand_deps f }
|
||||||
|
formulae = deps.reject { |f| f.installed? }
|
||||||
|
|
||||||
|
require 'set'
|
||||||
|
done = Set.new
|
||||||
|
|
||||||
require 'beer_events'
|
require 'beer_events'
|
||||||
|
|
||||||
watch_out_for_spill do
|
watch_out_for_spill do
|
||||||
fae.each do |f|
|
formulae.each do |f|
|
||||||
# we need to ensure a pristine ENV for each process or the formula
|
next if done.include? f.class
|
||||||
# will start with the ENV from the previous build
|
done << f.class
|
||||||
|
|
||||||
pid=fork
|
pid=fork
|
||||||
if pid.nil?
|
if pid.nil?
|
||||||
exec __FILE__, "install-just-one", f.name, *ARGV.options
|
exec __FILE__, "install-just-one", f.name, *ARGV.options
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user