lib/buildr/core/transports.rb in vic-buildr-1.3.1 vs lib/buildr/core/transports.rb in vic-buildr-1.3.3

- old
+ new

@@ -15,10 +15,12 @@ require 'cgi' require 'net/http' require 'net/https' +# PATCH: On Windows, Net::SSH 2.0.2 attempts to load the Pageant DLLs which break on JRuby. +$LOADED_FEATURES.unshift 'net/ssh/authentication/pageant' if RUBY_PLATFORM =~ /java/ require 'net/ssh' require 'net/sftp' require 'uri' require 'digest/md5' require 'digest/sha1' @@ -52,10 +54,13 @@ # Raised when trying to read/download a resource that doesn't exist. class NotFoundError < RuntimeError end + # How many bytes to read/write at once. + RW_CHUNK_SIZE = 2 ** 20 #:nodoc: + class << self # :call-seq: # read(uri, options?) => content # read(uri, options?) { |chunk| ... } @@ -288,26 +293,26 @@ # See URI::Generic#read def read(options = nil, &block) options ||= {} connect do |http| - puts "Requesting #{self}" if Buildr.application.options.trace + trace "Requesting #{self}" headers = { 'If-Modified-Since' => CGI.rfc1123_date(options[:modified].utc) } if options[:modified] request = Net::HTTP::Get.new(request_uri.empty? ? '/' : request_uri, headers) request.basic_auth self.user, self.password if self.user http.request request do |response| case response when Net::HTTPNotModified # No modification, nothing to do. - puts 'Not modified since last download' if Buildr.application.options.trace + trace 'Not modified since last download' return nil when Net::HTTPRedirection # Try to download from the new URI, handle relative redirects. - puts "Redirected to #{response['Location']}" if Buildr.application.options.trace + trace "Redirected to #{response['Location']}" return (self + URI.parse(response['location'])).read(options, &block) when Net::HTTPOK - puts "Downloading #{self}" if verbose + info "Downloading #{self}" result = nil with_progress_bar options[:progress], path.split('/').last, response.content_length do |progress| if block response.read_body do |chunk| block.call chunk @@ -334,13 +339,13 @@ private def write_internal(options, &block) #:nodoc: options ||= {} connect do |http| - puts "Uploading to #{path}" if Buildr.application.options.trace + trace "Uploading to #{path}" content = StringIO.new - while chunk = yield(32 * 4096) + while chunk = yield(RW_CHUNK_SIZE) content << chunk end headers = { 'Content-MD5'=>Digest::MD5.hexdigest(content.string) } request = Net::HTTP::Put.new(request_uri.empty? ? '/' : request_uri, headers) request.basic_auth self.user, self.password if self.user @@ -359,11 +364,11 @@ end case response when Net::HTTPRedirection # Try to download from the new URI, handle relative redirects. - puts "Redirected to #{response['Location']}" if Buildr.application.options.trace + trace "Redirected to #{response['Location']}" content.rewind return (self + URI.parse(response['location'])).write_internal(options) { |bytes| content.read(bytes) } when Net::HTTPSuccess else raise RuntimeError, "Failed to upload #{self}: #{response.message}" @@ -404,27 +409,27 @@ def read(options = {}, &block) # SSH options are based on the username/password from the URI. ssh_options = { :port=>port, :password=>password }.merge(options[:ssh_options] || {}) ssh_options[:password] ||= SFTP.passwords[host] begin - puts "Connecting to #{host}" if Buildr.application.options.trace + trace "Connecting to #{host}" result = nil Net::SFTP.start(host, user, ssh_options) do |sftp| SFTP.passwords[host] = ssh_options[:password] - puts 'connected' if Buildr.application.options.trace + trace 'connected' with_progress_bar options[:progress] && options[:size], path.split('/'), options[:size] || 0 do |progress| - puts "Downloading to #{path}" if Buildr.application.options.trace + trace "Downloading to #{path}" sftp.file.open(path, 'r') do |file| if block - while chunk = file.read(32 * 4096) + while chunk = file.read(RW_CHUNK_SIZE) block.call chunk progress << chunk end else result = '' - while chunk = file.read(32 * 4096) + while chunk = file.read(RW_CHUNK_SIZE) result << chunk progress << chunk end end end @@ -447,28 +452,28 @@ def write_internal(options, &block) #:nodoc: # SSH options are based on the username/password from the URI. ssh_options = { :port=>port, :password=>password }.merge(options[:ssh_options] || {}) ssh_options[:password] ||= SFTP.passwords[host] begin - puts "Connecting to #{host}" if Buildr.application.options.trace + trace "Connecting to #{host}" Net::SFTP.start(host, user, ssh_options) do |sftp| SFTP.passwords[host] = ssh_options[:password] - puts 'connected' if Buildr.application.options.trace + trace 'Connected' # To create a path, we need to create all its parent. We use realpath to determine if # the path already exists, otherwise mkdir fails. - puts "Creating path #{path}" if Buildr.application.options.trace - File.dirname(path).split('/').inject('') do |base, part| + trace "Creating path #{path}" + File.dirname(path).split('/').reject(&:empty?).inject('/') do |base, part| combined = base + part - sftp.realpath combined rescue sftp.mkdir combined, {} + sftp.close(sftp.opendir!(combined)) rescue sftp.mkdir! combined, {} "#{combined}/" end with_progress_bar options[:progress] && options[:size], path.split('/'), options[:size] || 0 do |progress| - puts "Uploading to #{path}" if Buildr.application.options.trace + trace "Uploading to #{path}" sftp.file.open(path, 'w') do |file| - while chunk = yield(32 * 4096) + while chunk = yield(RW_CHUNK_SIZE) file.write chunk progress << chunk end sftp.setstat(path, :permissions => options[:permissions]) if options[:permissions] end @@ -551,10 +556,10 @@ raise ArgumentError, 'Either you\'re attempting to write a file to another host (which we don\'t support), or you used two slashes by mistake, where you should have file:///<path>.' if host temp = nil Tempfile.open File.basename(path) do |temp| temp.binmode with_progress_bar options[:progress] && options[:size], path.split('/'), options[:size] || 0 do |progress| - while chunk = yield(32 * 4096) + while chunk = yield(RW_CHUNK_SIZE) temp.write chunk progress << chunk end end end