Class: Mistri::Workspace::Directory

Inherits:
Object
  • Object
show all
Defined in:
lib/mistri/workspace/directory.rb

Overview

Documents as ordinary files under a host-controlled root. Model-supplied paths cannot escape lexically or traverse an existing symlink. The host must keep the root and tree stable for the instance's lifetime; this is not an OS sandbox against concurrent filesystem mutation.

Instance Method Summary collapse

Constructor Details

#initialize(root) ⇒ Directory

Returns a new instance of Directory.



13
14
15
16
17
18
# File 'lib/mistri/workspace/directory.rb', line 13

def initialize(root)
  expanded = File.expand_path(root)
  FileUtils.mkdir_p(expanded)
  @root = File.realpath(expanded)
  @root_prefix = @root.end_with?(File::SEPARATOR) ? @root : "#{@root}#{File::SEPARATOR}"
end

Instance Method Details

#delete(path) ⇒ Object



33
34
35
36
37
# File 'lib/mistri/workspace/directory.rb', line 33

def delete(path)
  full = resolve(path)
  FileUtils.rm_f(full)
  nil
end

#list(prefix = nil) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/mistri/workspace/directory.rb', line 39

def list(prefix = nil)
  paths = Dir.glob("**/*", base: @root).filter_map do |path|
    full = File.join(@root, path)
    next if traverses_symlink?(full)
    next unless File.file?(full)

    path
  end.sort
  prefix ? paths.select { |p| p.start_with?(prefix.to_s) } : paths
end

#read(path) ⇒ Object



20
21
22
23
# File 'lib/mistri/workspace/directory.rb', line 20

def read(path)
  full = resolve(path)
  File.exist?(full) ? File.read(full) : nil
end

#write(path, content) ⇒ Object



25
26
27
28
29
30
31
# File 'lib/mistri/workspace/directory.rb', line 25

def write(path, content)
  full = resolve(path)
  FileUtils.mkdir_p(File.dirname(full))
  full = resolve(path)
  File.write(full, content.to_s)
  nil
end