Class: Staticky::Files::MemoryFileSystem

Inherits:
Object
  • Object
show all
Defined in:
lib/staticky/files/memory_file_system.rb,
lib/staticky/files/memory_file_system/node.rb

Overview

Memory File System abstraction to support ‘Staticky::Files`

Defined Under Namespace

Classes: Node

Constant Summary collapse

EMPTY_CONTENT =

rubocop:disable Metrics/ClassLength

""

Instance Method Summary collapse

Constructor Details

#initialize(root: Node.root) ⇒ Staticky::Files::MemoryFileSystem

Creates a new instance

the in-memory file system

Parameters:



19
20
21
# File 'lib/staticky/files/memory_file_system.rb', line 19

def initialize(root: Node.root)
  @root = root
end

Instance Method Details

#chdir(path) ⇒ Object

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.

Parameters:

  • path (String)

    the target directory

  • blk (Proc)

    the code to execute with the target directory

Raises:



149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/staticky/files/memory_file_system.rb', line 149

def chdir(path)
  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
  yield
ensure
  @root = current_root
end

#chmod(path, mode) ⇒ Object

Sets node UNIX mode

Parameters:

  • path (String, Array<String>)

    the path to the node

  • mode (Integer)

    a UNIX mode, in base 2, 8, 10, or 16

Raises:



276
277
278
279
280
281
282
283
# File 'lib/staticky/files/memory_file_system.rb', line 276

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) ⇒ Object

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

Parameters:

  • source (String, Array<String>)

    the file(s) or directory to copy

  • destination (String, Array<String>)

    the directory destination

Raises:



211
212
213
214
# File 'lib/staticky/files/memory_file_system.rb', line 211

def cp(source, destination)
  content = read(source)
  write(destination, content)
end

#directory?(path) ⇒ TrueClass, FalseClass

Check if the given path corresponds to a directory.

Parameters:

  • path (String, Array<String>)

    the path to the directory

Returns:

  • (TrueClass, FalseClass)

    the result of the check



314
315
316
317
# File 'lib/staticky/files/memory_file_system.rb', line 314

def directory?(path)
  path = Path[path]
  !find_directory(path).nil?
end

#entries(path) ⇒ Array<String>

Reads entries from a directory

Parameters:

  • path (String, Pathname)

    the path to file

Returns:

  • (Array<String>)

    the entries

Raises:



338
339
340
341
342
343
344
345
# File 'lib/staticky/files/memory_file_system.rb', line 338

def entries(path)
  path = Path[path]
  node = find(path)
  raise IOError, Errno::ENOENT.new(path.to_s) if node.nil?
  raise IOError, Errno::ENOTDIR.new(path.to_s) unless node.directory?

  [".", ".."] + Array(node.children&.keys)
end

#executable?(path) ⇒ TrueClass, FalseClass

Check if the given path is an executable.

Parameters:

  • path (String, Array<String>)

    the path to the node

Returns:

  • (TrueClass, FalseClass)

    the result of the check



323
324
325
326
327
328
329
330
# File 'lib/staticky/files/memory_file_system.rb', line 323

def executable?(path)
  path = Path[path]

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

  node.executable?
end

#exist?(path) ⇒ TrueClass, FalseClass

Check if the given path exist.

Parameters:

  • path (String, Array<String>)

    the path to the node

Returns:

  • (TrueClass, FalseClass)

    the result of the check



304
305
306
307
308
# File 'lib/staticky/files/memory_file_system.rb', line 304

def exist?(path)
  path = Path[path]

  !find(path).nil?
end

#expand_path(path, dir) ⇒ Object

Converts a path to an absolute path.

Parameters:

  • path (String, Array<String>)

    the path to the file

  • dir (String, Array<String>)

    the base directory



126
127
128
129
130
# File 'lib/staticky/files/memory_file_system.rb', line 126

def expand_path(path, dir)
  return path if Path.absolute?(path)

  join(dir, path)
end

#glob(pattern) ⇒ Array<String>

Returns an array of file paths that match the given pattern.

Parameters:

  • pattern (Pathname, String)

    the glob pattern to match

Returns:

  • (Array<String>)

    the matching file paths



351
352
353
354
355
# File 'lib/staticky/files/memory_file_system.rb', line 351

def glob(pattern)
  matches = []
  traverse(@root, "/", pattern.to_s, matches)
  matches
end

#join(*path) ⇒ String

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

Parameters:

  • path (String, Array<String>)

    path tokens

Returns:

  • (String)

    the joined path



118
119
120
# File 'lib/staticky/files/memory_file_system.rb', line 118

def join(*path)
  Path[path]
end

#mkdir(path) ⇒ Object

Creates a directory and all its parent directories.

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

file, or the file system cannot be accessed

Parameters:

  • path (String, Array<String>)

    the directory to create

Raises:

See Also:



174
175
176
177
178
179
180
181
182
183
# File 'lib/staticky/files/memory_file_system.rb', line 174

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?
    raise IOError, Errno::EACCES.new(path.to_s) unless node.readable?
  end
end

#mkdir_p(path) ⇒ Object

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.

Parameters:

  • path (String, Array<String>)

    the file that will be in the directories that this method creates

Raises:

See Also:



196
197
198
199
200
201
202
# File 'lib/staticky/files/memory_file_system.rb', line 196

def mkdir_p(path)
  path = Path[path]

  mkdir(
    Path.dirname(path)
  )
end

#mode(path) ⇒ Integer

Gets node UNIX mode

Parameters:

  • path (String, Array<String>)

    the path to the node

Returns:

  • (Integer)

    the UNIX mode

Raises:



291
292
293
294
295
296
297
298
# File 'lib/staticky/files/memory_file_system.rb', line 291

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) {|| ... } ⇒ Staticky::Files::MemoryFileSystem::Node

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

Parameters:

  • path (String)

    the target file

Yield Parameters:

Returns:



28
29
30
31
32
33
34
35
36
# File 'lib/staticky/files/memory_file_system.rb', line 28

def open(path, *)
  file = touch(path)

  if block_given?
    yield file
  else
    file
  end
end

#pwdString

Returns the name of the current working directory.

Returns:

  • (String)

    the current working directory.



135
136
137
# File 'lib/staticky/files/memory_file_system.rb', line 135

def pwd
  @root.segment
end

#read(path) ⇒ String

Read file contents

or if the file cannot be found

Parameters:

  • path (String, Array<String>)

    the target path

Returns:

  • (String)

    the file contents

Raises:



45
46
47
48
49
50
51
52
53
# File 'lib/staticky/files/memory_file_system.rb', line 45

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) ⇒ Array<String>

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

or if the file cannot be found, or if the file is not readable

Parameters:

  • path (String, Array<String>)

    the target path

Returns:

  • (Array<String>)

    the file contents

Raises:



63
64
65
66
67
68
69
70
71
72
# File 'lib/staticky/files/memory_file_system.rb', line 63

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?
  raise IOError, Errno::EACCES.new(path.to_s) unless node.readable?

  node.readlines
end

#rm(path) ⇒ Object

Removes (deletes) a file

a directory

Parameters:

  • path (String, Array<String>)

    the file to remove

Raises:

See Also:



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/staticky/files/memory_file_system.rb', line 224

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) ⇒ Object

Removes (deletes) a directory

Parameters:

  • path (String, Array<String>)

    the directory to remove

Raises:

See Also:



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/staticky/files/memory_file_system.rb', line 251

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) ⇒ Object

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

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

Parameters:

  • path (String, Array<String>)

    the target path

Raises:



81
82
83
84
85
86
87
# File 'lib/staticky/files/memory_file_system.rb', line 81

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) ⇒ Object

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

Parameters:

  • path (String, Array<String>)

    the target path

  • content (String, Array<String>)

    the content to write

Raises:



97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/staticky/files/memory_file_system.rb', line 97

def write(path, *content)
  path = Path[path]
  raise IOError, Errno::EISDIR.new(path.to_s) if directory?(path)

  node = @root

  for_each_segment(path) do |segment|
    node = node.set(segment)
    raise IOError, Errno::EACCES.new(path.to_s) unless node.readable?
  end

  node.write(*content)
  node
end