diff options
| author | Max Howell | 2009-09-18 19:16:39 +0100 |
|---|---|---|
| committer | Max Howell | 2009-09-21 18:27:48 +0100 |
| commit | 77dd27e8e6e9e2f31fc8ca90bb6d63399922d013 (patch) | |
| tree | 95da1d90b212516c0e725fca444af4625d4e97f5 | |
| parent | a793e3040513f72a5108944a8c3ee1cbfb37ebb2 (diff) | |
| download | brew-77dd27e8e6e9e2f31fc8ca90bb6d63399922d013.tar.bz2 | |
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
| -rw-r--r-- | Library/Homebrew/brew.h.rb | 27 | ||||
| -rw-r--r-- | Library/Homebrew/formula.rb | 33 | ||||
| -rwxr-xr-x | bin/brew | 23 |
3 files changed, 47 insertions, 36 deletions
diff --git a/Library/Homebrew/brew.h.rb b/Library/Homebrew/brew.h.rb index 875f61be0..0d977ae95 100644 --- a/Library/Homebrew/brew.h.rb +++ b/Library/Homebrew/brew.h.rb @@ -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 diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 9c5123545..a4bebdd2b 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -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,9 +283,31 @@ private end class <<self - attr_reader :url, :version, :homepage, :head + attr_reader :url, :version, :homepage, :head, :deps 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 # see ack.rb for an example usage @@ -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 'beer_events' + 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 |
