class Arv::Collection

Public Class Methods

new(manifest_text="") click to toggle source
# File lib/arvados/collection.rb, line 9
def initialize(manifest_text="")
  @manifest_text = manifest_text
  @modified = false
  @root = CollectionRoot.new
  manifest = Keep::Manifest.new(manifest_text)
  manifest.each_line do |stream_root, locators, file_specs|
    if stream_root.empty? or locators.empty? or file_specs.empty?
      raise ArgumentError.new("manifest text includes malformed line")
    end
    loc_list = LocatorList.new(locators)
    file_specs.map { |s| manifest.split_file_token(s) }.
        each do |file_start, file_len, file_path|
      begin
        @root.file_at(normalize_path(stream_root, file_path)).
          add_segment(loc_list.segment(file_start, file_len))
      rescue Errno::ENOTDIR, Errno::EISDIR => error
        raise ArgumentError.new("%p is both a stream and file" %
                                error.to_s.partition(" - ").last)
      end
    end
  end
end

Public Instance Methods

cp_r(source, target, source_collection=nil) click to toggle source
# File lib/arvados/collection.rb, line 50
def cp_r(source, target, source_collection=nil)
  opts = {:descend_target => !source.end_with?("/")}
  copy(:merge, source.chomp("/"), target, source_collection, opts)
end
each_file_path(&block) click to toggle source
# File lib/arvados/collection.rb, line 55
def each_file_path(&block)
  @root.each_file_path(&block)
end
exist?(path) click to toggle source
# File lib/arvados/collection.rb, line 59
def exist?(path)
  begin
    substream, item = find(path)
    not (substream.leaf? or substream[item].nil?)
  rescue Errno::ENOENT, Errno::ENOTDIR
    false
  end
end
manifest_text() click to toggle source
# File lib/arvados/collection.rb, line 32
def manifest_text
  @manifest_text ||= @root.manifest_text
end
modified?() click to toggle source
# File lib/arvados/collection.rb, line 36
def modified?
  @modified
end
normalize() click to toggle source
# File lib/arvados/collection.rb, line 45
def normalize
  @manifest_text = @root.manifest_text
  self
end
rename(source, target) click to toggle source
# File lib/arvados/collection.rb, line 68
def rename(source, target)
  copy(:add_copy, source, target) { rm_r(source) }
end
rm(source) click to toggle source
# File lib/arvados/collection.rb, line 72
def rm(source)
  remove(source)
end
rm_r(source) click to toggle source
# File lib/arvados/collection.rb, line 76
def rm_r(source)
  remove(source, :recursive => true)
end
unmodified() click to toggle source
# File lib/arvados/collection.rb, line 40
def unmodified
  @modified = false
  self
end

Protected Instance Methods

find(*parts) click to toggle source
# File lib/arvados/collection.rb, line 82
def find(*parts)
  @root.find(normalize_path(*parts))
end

Private Instance Methods

copy(copy_method, source, target, source_collection=nil, opts={}) { || ... } click to toggle source
# File lib/arvados/collection.rb, line 105
def copy(copy_method, source, target, source_collection=nil, opts={})
  # Find the item at path `source` in `source_collection`, find the
  # destination stream at path `target`, and use `copy_method` to copy
  # the found object there.  If a block is passed in, it will be called
  # right before we do the actual copy, after we confirm that everything
  # is found and can be copied.
  source_collection = self if source_collection.nil?
  src_stream, src_tail = source_collection.find(source)
  dst_stream_path, _, dst_tail = normalize_path(target).rpartition("/")
  if dst_stream_path.empty?
    dst_stream, dst_tail = @root.find(dst_tail)
    dst_tail ||= src_tail
  else
    dst_stream = @root.stream_at(dst_stream_path)
    dst_tail = src_tail if dst_tail.empty?
  end
  if (source_collection.equal?(self) and
      (src_stream.path == dst_stream.path) and (src_tail == dst_tail))
    return self
  end
  src_item = src_stream[src_tail]
  check_method = "check_can_#{copy_method}".to_sym
  target_name = nil
  if opts.fetch(:descend_target, true)
    begin
      # Find out if `target` refers to a stream we should copy into.
      tail_stream = dst_stream[dst_tail]
      tail_stream.send(check_method, src_item, src_tail)
      # Yes it does.  Copy the item at `source` into it with the same name.
      dst_stream = tail_stream
      target_name = src_tail
    rescue Errno::ENOENT, Errno::ENOTDIR
      # It does not.  We'll fall back to writing to `target` below.
    end
  end
  if target_name.nil?
    dst_stream.send(check_method, src_item, dst_tail)
    target_name = dst_tail
  end
  # At this point, we know the operation will work.  Call any block as
  # a pre-copy hook.
  if block_given?
    yield
    # Re-find the destination stream, in case the block removed
    # the original (that's how rename is implemented).
    dst_stream = @root.stream_at(dst_stream.path)
  end
  dst_stream.send(copy_method, src_item, target_name)
  modified
end
modified() click to toggle source
# File lib/arvados/collection.rb, line 88
def modified
  @manifest_text = nil
  @modified = true
  self
end
normalize_path(*parts) click to toggle source
# File lib/arvados/collection.rb, line 94
def normalize_path(*parts)
  path = File.join(*parts)
  if path.empty?
    raise ArgumentError.new("empty path")
  elsif (path == ".") or path.start_with?("./")
    path
  else
    "./#{path}"
  end
end
remove(path, opts={}) click to toggle source
# File lib/arvados/collection.rb, line 156
def remove(path, opts={})
  stream, name = find(path)
  stream.delete(name, opts)
  modified
end