class Dry::Files::MemoryFileSystem

Memory File System abstraction to support `Dry::Files`

@since 0.1.0 @api private

Constants

EMPTY_CONTENT

@since 0.1.0 @api private

Public Class Methods

new(root: Node.root) click to toggle source

Creates a new instance

@param root [Dry::Files::MemoryFileSystem::Node] the root node of the

in-memory file system

@return [Dry::Files::MemoryFileSystem]

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 28
def initialize(root: Node.root)
  @root = root
end

Public Instance Methods

chdir(path, &blk) click to toggle source

Temporary changes the current working directory of the process to the given path and yield the given block.

The argument `path` is intended to be a directory.

@param path [String] the target directory @param blk [Proc] the code to execute with the target directory

@raise [Dry::Files::IOError] if path cannot be found or it isn't a

directory

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 173
def chdir(path, &blk)
  path = Path[path]
  directory = find(path)

  raise IOError, Errno::ENOENT.new(path.to_s) if directory.nil?
  raise IOError, Errno::ENOTDIR.new(path.to_s) unless directory.directory?

  current_root = @root
  @root = directory
  blk.call
ensure
  @root = current_root
end
chmod(path, mode) click to toggle source

Sets node UNIX mode

@param path [String,Array<String>] the path to the node @param mode [Integer] a UNIX mode, in base 2, 8, 10, or 16

@raise [Dry::Files::IOError] if path cannot be found

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 315
def chmod(path, mode)
  path = Path[path]
  node = find(path)

  raise IOError, Errno::ENOENT.new(path.to_s) if node.nil?

  node.chmod = mode
end
cp(source, destination) click to toggle source

Copies file content from `source` to `destination` All the intermediate `destination` directories are created.

@param source [String,Array<String>] the file(s) or directory to copy @param destination [String,Array<String>] the directory destination

@raise [Dry::Files::IOError] if source cannot be found

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 242
def cp(source, destination)
  content = read(source)
  write(destination, content)
end
directory?(path) click to toggle source

Check if the given path corresponds to a directory.

@param path [String,Array<String>] the path to the directory @return [TrueClass,FalseClass] the result of the check

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 362
def directory?(path)
  path = Path[path]
  !find_directory(path).nil?
end
executable?(path) click to toggle source

Check if the given path is an executable.

@param path [String,Array<String>] the path to the node @return [TrueClass,FalseClass] the result of the check

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 374
def executable?(path)
  path = Path[path]

  node = find(path)
  return false if node.nil?

  node.executable?
end
exist?(path) click to toggle source

Check if the given path exist.

@param path [String,Array<String>] the path to the node @return [TrueClass,FalseClass] the result of the check

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 349
def exist?(path)
  path = Path[path]

  !find(path).nil?
end
expand_path(path, dir) click to toggle source

Converts a path to an absolute path.

@param path [String,Array<String>] the path to the file @param dir [String,Array<String>] the base directory

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 144
def expand_path(path, dir)
  return path if Path.absolute?(path)

  join(dir, path)
end
join(*path) click to toggle source

Returns a new string formed by joining the strings using Operating System path separator

@param path [String,Array<String>] path tokens

@return [String] the joined path

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 133
def join(*path)
  Path[path]
end
mkdir(path) click to toggle source

Creates a directory and all its parent directories.

The argument `path` is intended to be a directory that you want to explicitly create.

@see mkdir_p

@param path [String,Array<String>] the directory to create

@raise [Dry::Files::IOError] in case path is an already existing file

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 200
def mkdir(path)
  path = Path[path]
  node = @root

  for_each_segment(path) do |segment|
    node = node.set(segment)
    raise IOError, Errno::EEXIST.new(path.to_s) if node.file?
  end
end
mkdir_p(path) click to toggle source

Creates a directory and all its parent directories.

The argument `path` is intended to be a file, where its directory ancestors will be implicitly created.

@see mkdir

@param path [String,Array<String>] the file that will be in the

directories that this method creates

@raise [Dry::Files::IOError] in case of I/O error

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 224
def mkdir_p(path)
  path = Path[path]

  mkdir(
    Path.dirname(path)
  )
end
mode(path) click to toggle source

Gets node UNIX mode

@param path [String,Array<String>] the path to the node @return [Integer] the UNIX mode

@raise [Dry::Files::IOError] if path cannot be found

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 333
def mode(path)
  path = Path[path]
  node = find(path)

  raise IOError, Errno::ENOENT.new(path.to_s) if node.nil?

  node.mode
end
open(path, *, &blk) click to toggle source

Opens (or creates) a new file for read/write operations.

@param path [String] the target file @yieldparam [Dry::Files::MemoryFileSystem::Node]

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 39
def open(path, *, &blk)
  file = touch(path)
  blk.call(file)
end
pwd() click to toggle source

Returns the name of the current working directory.

@return [String] the current working directory.

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 156
def pwd
  @root.segment
end
read(path) click to toggle source

Read file contents

@param path [String, Array<String>] the target path @return [String] the file contents

@raise [Dry::Files::IOError] in case the target path is a directory or

if the file cannot be found

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 54
def read(path)
  path = Path[path]
  raise IOError, Errno::EISDIR.new(path.to_s) if directory?(path)

  file = find_file(path)
  raise IOError, Errno::ENOENT.new(path.to_s) if file.nil?

  file.read
end
readlines(path) click to toggle source

Reads the entire file specified by path as individual lines, and returns those lines in an array

@param path [String, Array<String>] the target path @return [Array<String>] the file contents

@raise [Dry::Files::IOError] in case the target path is a directory or

if the file cannot be found

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 75
def readlines(path)
  path = Path[path]
  node = find(path)

  raise IOError, Errno::ENOENT.new(path.to_s) if node.nil?
  raise IOError, Errno::EISDIR.new(path.to_s) if node.directory?

  node.readlines
end
rm(path) click to toggle source

Removes (deletes) a file

@param path [String,Array<String>] the file to remove

@raise [Dry::Files::IOError] if path cannot be found or it's a directory

@see rm_rf

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 257
def rm(path)
  path = Path[path]
  file = nil
  parent = @root
  node = @root

  for_each_segment(path) do |segment|
    break unless node

    file = segment
    parent = node
    node = node.get(segment)
  end

  raise IOError, Errno::ENOENT.new(path.to_s) if node.nil?
  raise IOError, Errno::EPERM.new(path.to_s) if node.directory?

  parent.unset(file)
end
rm_rf(path) click to toggle source

Removes (deletes) a directory

@param path [String,Array<String>] the directory to remove

@raise [Dry::Files::IOError] if path cannot be found

@see rm

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 287
def rm_rf(path)
  path = Path[path]
  file = nil
  parent = @root
  node = @root

  for_each_segment(path) do |segment|
    break unless node

    file = segment
    parent = node
    node = node.get(segment)
  end

  raise IOError, Errno::ENOENT.new(path.to_s) if node.nil?

  parent.unset(file)
end
touch(path) click to toggle source

Creates a file, if it doesn't exist, and set empty content.

If the file was already existing, it's a no-op.

@param path [String, Array<String>] the target path

@raise [Dry::Files::IOError] in case the target path is a directory

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 95
def touch(path)
  path = Path[path]
  raise IOError, Errno::EISDIR.new(path.to_s) if directory?(path)

  content = read(path) if exist?(path)
  write(path, content || EMPTY_CONTENT)
end
write(path, *content) click to toggle source

Creates a new file or rewrites the contents of an existing file for the given path and content All the intermediate directories are created.

@param path [String, Array<String>] the target path @param content [String, Array<String>] the content to write

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 112
def write(path, *content)
  path = Path[path]
  node = @root

  for_each_segment(path) do |segment|
    node = node.set(segment)
  end

  node.write(*content)
  node
end

Private Instance Methods

find(path) click to toggle source

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 416
def find(path)
  node = @root

  for_each_segment(path) do |segment|
    break unless node

    node = node.get(segment)
  end

  node
end
find_directory(path) click to toggle source

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 394
def find_directory(path)
  node = find(path)

  return if node.nil?
  return unless node.directory?

  node
end
find_file(path) click to toggle source

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 405
def find_file(path)
  node = find(path)

  return if node.nil?
  return unless node.file?

  node
end
for_each_segment(path, &blk) click to toggle source

@since 0.1.0 @api private

# File lib/dry/files/memory_file_system.rb, line 387
def for_each_segment(path, &blk)
  segments = Path.split(path)
  segments.each(&blk)
end