diff options
Diffstat (limited to 'Library/Homebrew/cask/lib/hbc/download_strategy.rb')
| -rw-r--r-- | Library/Homebrew/cask/lib/hbc/download_strategy.rb | 85 |
1 files changed, 76 insertions, 9 deletions
diff --git a/Library/Homebrew/cask/lib/hbc/download_strategy.rb b/Library/Homebrew/cask/lib/hbc/download_strategy.rb index 245ad4ade..016bb66e6 100644 --- a/Library/Homebrew/cask/lib/hbc/download_strategy.rb +++ b/Library/Homebrew/cask/lib/hbc/download_strategy.rb @@ -10,7 +10,7 @@ module Hbc class AbstractDownloadStrategy attr_reader :cask, :name, :url, :uri_object, :version - def initialize(cask, command: SystemCommand) + def initialize(cask, command = SystemCommand) @cask = cask @command = command # TODO: this excess of attributes is a function of integrating @@ -33,8 +33,8 @@ module Hbc class HbVCSDownloadStrategy < AbstractDownloadStrategy REF_TYPES = [:branch, :revision, :revisions, :tag].freeze - def initialize(*args, **options) - super(*args, **options) + def initialize(cask, command = SystemCommand) + super @ref_type, @ref = extract_ref @clone = Hbc.cache.join(cache_filename) end @@ -64,6 +64,11 @@ module Hbc end class CurlDownloadStrategy < AbstractDownloadStrategy + # TODO: should be part of url object + def mirrors + @mirrors ||= [] + end + def tarball_path @tarball_path ||= Hbc.cache.join("#{name}--#{version}#{ext}") end @@ -90,8 +95,13 @@ module Hbc end end + def downloaded_size + temporary_path.size? || 0 + end + def _fetch - curl_download url, *cask_curl_args, to: temporary_path, user_agent: uri_object.user_agent + odebug "Calling curl with args #{cask_curl_args}" + curl(*cask_curl_args) end def fetch @@ -121,12 +131,33 @@ module Hbc ignore_interrupts { temporary_path.rename(tarball_path) } end tarball_path + rescue CurlDownloadStrategyError + raise if mirrors.empty? + puts "Trying a mirror..." + @url = mirrors.shift + retry end private def cask_curl_args - cookies_args + referer_args + default_curl_args.tap do |args| + args.concat(user_agent_args) + args.concat(cookies_args) + args.concat(referer_args) + end + end + + def default_curl_args + [url, "-C", downloaded_size, "-o", temporary_path] + end + + def user_agent_args + if uri_object.user_agent + ["-A", uri_object.user_agent] + else + [] + end end def cookies_args @@ -160,7 +191,8 @@ module Hbc class CurlPostDownloadStrategy < CurlDownloadStrategy def cask_curl_args - super.concat(post_args) + super + default_curl_args.concat(post_args) end def post_args @@ -193,8 +225,8 @@ module Hbc # super does not provide checks for already-existing downloads def fetch - if cached_location.directory? - puts "Already downloaded: #{cached_location}" + if tarball_path.exist? + puts "Already downloaded: #{tarball_path}" else @url = @url.sub(/^svn\+/, "") if @url =~ %r{^svn\+http://} ohai "Checking out #{@url}" @@ -220,8 +252,9 @@ module Hbc else fetch_repo @clone, @url end + compress end - cached_location + tarball_path end # This primary reason for redefining this method is the trust_cert @@ -255,6 +288,10 @@ module Hbc print_stderr: false) end + def tarball_path + @tarball_path ||= cached_location.dirname.join(cached_location.basename.to_s + "-#{@cask.version}.tar") + end + def shell_quote(str) # Oh god escaping shell args. # See http://notetoself.vrensk.com/2008/08/escaping-single-quotes-in-ruby-harder-than-expected/ @@ -267,5 +304,35 @@ module Hbc yield name, url end end + + private + + # TODO/UPDATE: the tar approach explained below is fragile + # against challenges such as case-sensitive filesystems, + # and must be re-implemented. + # + # Seems nutty: we "download" the contents into a tape archive. + # Why? + # * A single file is tractable to the rest of the Cask toolchain, + # * An alternative would be to create a Directory container type. + # However, some type of file-serialization trick would still be + # needed in order to enable calculating a single checksum over + # a directory. So, in that alternative implementation, the + # special cases would propagate outside this class, including + # the use of tar or equivalent. + # * SubversionDownloadStrategy.cached_location is not versioned + # * tarball_path provides a needed return value for our overridden + # fetch method. + # * We can also take this private opportunity to strip files from + # the download which are protocol-specific. + + def compress + Dir.chdir(cached_location) do + @command.run!("/usr/bin/tar", + args: ['-s/^\.//', "--exclude", ".svn", "-cf", Pathname.new(tarball_path), "--", "."], + print_stderr: false) + end + clear_cache + end end end |
