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
|
||||
|
||||
|
||||
# NOTE this is ugly code, and inefficient too, and can have infinite cycles
|
||||
# I have no time currently to improve it, feel free to submit a more elegant
|
||||
# solution. Thanks! --mxcl
|
||||
def expand_deps fae
|
||||
def expand_deps ff
|
||||
deps = []
|
||||
fae.each do |f|
|
||||
case f.deps
|
||||
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
|
||||
ff.deps.collect do |f|
|
||||
deps += expand_deps(Formula.factory(f))
|
||||
end
|
||||
|
||||
# TODO much more efficient to use a set and not recurse stuff already done
|
||||
return deps.flatten.uniq
|
||||
deps << ff
|
||||
end
|
||||
|
||||
|
||||
|
||||
@ -114,8 +114,6 @@ class Formula
|
||||
# :p2 => ['http://moo.com/patch5', 'http://moo.com/patch6']
|
||||
# }
|
||||
def patches; [] end
|
||||
# reimplement and specify dependencies
|
||||
def deps; end
|
||||
# sometimes the clean process breaks things, return true to skip anything
|
||||
def skip_clean? path; false end
|
||||
|
||||
@ -157,6 +155,7 @@ class Formula
|
||||
end
|
||||
|
||||
def self.factory name
|
||||
return name if name.kind_of? Formula
|
||||
require self.path(name)
|
||||
return eval(self.class(name)).new(name)
|
||||
rescue LoadError
|
||||
@ -167,6 +166,10 @@ class Formula
|
||||
HOMEBREW_PREFIX+'Library'+'Formula'+"#{name.downcase}.rb"
|
||||
end
|
||||
|
||||
def deps
|
||||
self.class.deps or []
|
||||
end
|
||||
|
||||
protected
|
||||
# Pretty titles the command and buffers stdout/stderr
|
||||
# Throws if there's an error
|
||||
@ -280,8 +283,30 @@ private
|
||||
end
|
||||
|
||||
class <<self
|
||||
attr_reader :url, :version, :homepage, :head
|
||||
attr_reader :url, :version, :homepage, :head, :deps
|
||||
attr_reader *CHECKSUM_TYPES
|
||||
|
||||
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
|
||||
|
||||
|
||||
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"
|
||||
end
|
||||
|
||||
|
||||
begin
|
||||
case ARGV.shift
|
||||
when '--prefix' then puts HOMEBREW_PREFIX
|
||||
@ -104,7 +105,7 @@ begin
|
||||
unless system "which #{ENV['CC'] or 'cc'} &> /dev/null" and $?.success?
|
||||
raise "We cannot find a c compiler, have you installed the latest Xcode?"
|
||||
end
|
||||
fae = ARGV.formulae.reject do |f|
|
||||
formulae = ARGV.formulae.reject do |f|
|
||||
if f.installed?
|
||||
message = "Formula already installed: #{f.prefix}"
|
||||
if ARGV.formulae.count > 1
|
||||
@ -115,20 +116,24 @@ begin
|
||||
true
|
||||
end
|
||||
end
|
||||
exit 0 if fae.empty?
|
||||
exit 0 if formulae.empty?
|
||||
else
|
||||
fae=ARGV.formulae
|
||||
formulae = ARGV.formulae
|
||||
end
|
||||
|
||||
# the resulting order will be optimal for super-deps and deps
|
||||
fae=expand_deps fae
|
||||
deps = []
|
||||
formulae.each { |f| deps += expand_deps f }
|
||||
formulae = deps.reject { |f| f.installed? }
|
||||
|
||||
require 'set'
|
||||
done = Set.new
|
||||
|
||||
require 'beer_events'
|
||||
|
||||
watch_out_for_spill do
|
||||
fae.each do |f|
|
||||
# we need to ensure a pristine ENV for each process or the formula
|
||||
# will start with the ENV from the previous build
|
||||
formulae.each do |f|
|
||||
next if done.include? f.class
|
||||
done << f.class
|
||||
|
||||
pid=fork
|
||||
if pid.nil?
|
||||
exec __FILE__, "install-just-one", f.name, *ARGV.options
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user