diff options
| author | Charlie Sharpsteen | 2011-09-11 15:23:41 -0700 |
|---|---|---|
| committer | Charlie Sharpsteen | 2011-09-19 09:24:43 -0700 |
| commit | efcdbd691e672b8fa0f57540e1f687b07b7d84f8 (patch) | |
| tree | a865faf3aaff17c7a0bbfe0c5ec8647e68e3f070 | |
| parent | 3b5869acb59c9cc7c9ab0dfdf3fe756f3245511c (diff) | |
| download | homebrew-efcdbd691e672b8fa0f57540e1f687b07b7d84f8.tar.bz2 | |
mirror support: Add mirror method to Formula.rb
Mirrors can now be declared using the `mirror` method which works similar to
`depends_on` and takes the same arguments as `url`.
The formula class now has a public `fetch` method that cycles through the
mirror list if the downloader for the primary URL throws a `DownloadError`.
Other brew commands, like brew-fetch, also benefit from mirror support by using
this method.
Closes #7574.
| -rw-r--r-- | Library/Homebrew/cmd/fetch.rb | 4 | ||||
| -rw-r--r-- | Library/Homebrew/formula.rb | 40 |
2 files changed, 38 insertions, 6 deletions
diff --git a/Library/Homebrew/cmd/fetch.rb b/Library/Homebrew/cmd/fetch.rb index de3efe124..19060bc01 100644 --- a/Library/Homebrew/cmd/fetch.rb +++ b/Library/Homebrew/cmd/fetch.rb @@ -10,7 +10,7 @@ module Homebrew extend self bucket << f bucket << f.recursive_deps end - + bucket = bucket.flatten.uniq else bucket = ARGV.formulae @@ -24,7 +24,7 @@ module Homebrew extend self FileUtils.rm_rf where_to if File.exist? where_to end - the_tarball = f.downloader.fetch + the_tarball, _ = f.fetch next unless the_tarball.kind_of? Pathname previous_md5 = f.instance_variable_get(:@md5) diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 2ecf30758..6ed03af14 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -458,6 +458,10 @@ class Formula HOMEBREW_REPOSITORY+"Library/Formula/#{name.downcase}.rb" end + def mirrors + self.class.mirrors or [] + end + def deps self.class.deps or [] end @@ -549,8 +553,26 @@ private CHECKSUM_TYPES=[:md5, :sha1, :sha256].freeze - public # for FormulaInstaller + public + # For brew-fetch and others. + def fetch + downloader = @downloader + mirror_list = mirrors + + begin + fetched = downloader.fetch + rescue DownloadError => e + raise e if mirror_list.empty? + opoo "#{e.message}\nTrying a mirror." + url, specs = mirror_list.shift.values_at :url, :specs + downloader = download_strategy.new url, name, version, specs + retry + end + return fetched, downloader + end + + # For FormulaInstaller. def verify_download_integrity fn, *args require 'digest' if args.length != 2 @@ -585,10 +607,10 @@ EOF def stage HOMEBREW_CACHE.mkpath - fetched = @downloader.fetch + fetched, downloader = fetch verify_download_integrity fetched if fetched.kind_of? Pathname mktemp do - @downloader.stage + downloader.stage yield end end @@ -688,7 +710,7 @@ EOF end end - attr_rw :version, :homepage, :specs, :deps, :external_deps + attr_rw :version, :homepage, :mirrors, :specs, :deps, :external_deps attr_rw :keg_only_reason, :fails_with_llvm_reason, :skip_clean_all attr_rw :bottle, :bottle_sha1 attr_rw(*CHECKSUM_TYPES) @@ -707,6 +729,16 @@ EOF @specs = specs end + 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 + def depends_on name @deps ||= [] @external_deps ||= {:python => [], :perl => [], :ruby => [], :jruby => []} |
