aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharlie Sharpsteen2011-09-11 15:23:41 -0700
committerCharlie Sharpsteen2011-09-19 09:24:43 -0700
commitefcdbd691e672b8fa0f57540e1f687b07b7d84f8 (patch)
treea865faf3aaff17c7a0bbfe0c5ec8647e68e3f070
parent3b5869acb59c9cc7c9ab0dfdf3fe756f3245511c (diff)
downloadhomebrew-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.rb4
-rw-r--r--Library/Homebrew/formula.rb40
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 => []}