Class: URI::Generic

Inherits:
Object show all
Defined in:
lib/buildr/core/transports.rb

Direct Known Subclasses

FILE, SFTP

Instance Method Summary collapse

Instance Method Details

#download(target, options = nil) ⇒ Object

:call-seq:

download(target, options?)

Downloads the resource to the target.

The target may be a file name (string or task), in which case the file is created from the resource. The target may also be any object that responds to write, e.g. File, StringIO, Pipe.

Use the progress bar when running in verbose mode.



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/buildr/core/transports.rb', line 144

def download(target, options = nil)
  case target
  when Rake::Task
    download target.name, options
  when String
    # If download breaks we end up with a partial file which is
    # worse than not having a file at all, so download to temporary
    # file and then move over.
    modified = File.stat(target).mtime if File.exist?(target)
    temp = nil
    Tempfile.open File.basename(target) do |temp|
      temp.binmode
      read({:progress=>verbose}.merge(options || {}).merge(:modified=>modified)) { |chunk| temp.write chunk }
    end
    mkpath File.dirname(target)
    FileUtils.mv temp.path, target
  when File
    read({:progress=>verbose}.merge(options || {}).merge(:modified=>target.mtime)) { |chunk| target.write chunk }
    target.flush
  else
    raise ArgumentError, 'Expecting a target that is either a file name (string, task) or object that responds to write (file, pipe).' unless target.respond_to?(:write)
    read({:progress=>verbose}.merge(options || {})) { |chunk| target.write chunk }
    target.flush
  end
end

#read(options = nil, &block) ⇒ Object

:call-seq:

read(options?) => content
read(options?) { |chunk| ... }

Reads from the resource behind this URI. The first form returns the content of the resource, the second form yields to the block with each chunk of content (usually more than one).

For options, see URI::read.



131
132
133
# File 'lib/buildr/core/transports.rb', line 131

def read(options = nil, &block)
  fail 'This protocol doesn\'t support reading (yet, how about helping by implementing it?)'
end

#upload(source, options = nil) ⇒ Object

:call-seq:

upload(source, options?)

Uploads from source to the resource.

The source may be a file name (string or task), in which case the file is uploaded to the resource. If the source is a directory, uploads all files inside the directory (including nested directories). The source may also be any object that responds to read (and optionally size), e.g. File, StringIO, Pipe.

Use the progress bar when running in verbose mode.



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/buildr/core/transports.rb', line 205

def upload(source, options = nil)
  source = source.name if Rake::Task === source
  options ||= {}
  if String === source
    raise NotFoundError, 'No source file/directory to upload.' unless File.exist?(source)
    if File.directory?(source)
      Dir.glob("#{source}/**/*").reject { |file| File.directory?(file) }.each do |file|
        uri = self + (File.join(self.path, file.sub(source, '')))
        uri.upload file, {:digests=>[]}.merge(options)
      end
    else
      File.open(source, 'rb') { |input| upload input, options }
    end
  elsif source.respond_to?(:read)
    digests = (options[:digests] || [:md5, :sha1]).
      inject({}) { |hash, name| hash[name] = Digest.const_get(name.to_s.upcase).new ; hash }
    size = source.size rescue nil
    write (options).merge(:progress=>verbose && size, :size=>size) do |bytes|
      source.read(bytes).tap do |chunk|
        digests.values.each { |digest| digest << chunk } if chunk
      end
    end
    digests.each do |key, digest|
      self.merge("#{self.path}.#{key}").write "#{digest.hexdigest} #{File.basename(path)}",
        (options).merge(:progress=>false)
    end
  else
    raise ArgumentError, 'Expecting source to be a file name (string, task) or any object that responds to read (file, pipe).'
  end
end

#write(*args, &block) ⇒ Object

:call-seq:

write(content, options?)
write(options?) { |bytes| .. }

Writes to the resource behind the URI. The first form writes the content from a string or an object that responds to read and optionally size. The second form writes the content by yielding to the block. Each yield should return up to the specified number of bytes, the last yield returns nil.

For options, see URI::write.



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/buildr/core/transports.rb', line 179

def write(*args, &block)
  options = args.pop if Hash === args.last
  options ||= {}
  if String === args.first
    ios = StringIO.new(args.first, 'r')
    write(options.merge(:size=>args.first.size)) { |bytes| ios.read(bytes) }
  elsif args.first.respond_to?(:read)
    size = args.first.size rescue nil
    write({:size=>size}.merge(options)) { |bytes| args.first.read(bytes) }
  elsif args.empty? && block
    write_internal options, &block
  else
    raise ArgumentError, 'Either give me the content, or pass me a block, otherwise what would I upload?'
  end
end