Class: Textus::Store

Inherits:
Object
  • Object
show all
Defined in:
lib/textus/store.rb,
lib/textus/store/reader.rb,
lib/textus/store/writer.rb,
lib/textus/store/sentinel.rb,
lib/textus/store/audit_log.rb,
lib/textus/store/staleness.rb,
lib/textus/store/validator.rb,
lib/textus/store/staleness/intake_check.rb,
lib/textus/store/staleness/generator_check.rb

Defined Under Namespace

Classes: AuditLog, Reader, Sentinel, Staleness, Validator, Writer

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root) ⇒ Store

Returns a new instance of Store.



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/textus/store.rb', line 39

def initialize(root)
  @root = File.expand_path(root)
  @manifest = Manifest.load(@root)
  @bus = Hooks::Dispatcher.new(audit_log: audit_log)
  @registry = Hooks::Registry.new(dispatcher: @bus)
  @schemas = {}
  load_hooks
  @reader = Reader.new(self)
  @writer = Writer.new(self)
  @bus.publish(:store_loaded, store: Textus::Application::Context.system(self))
end

Instance Attribute Details

#busObject (readonly)

Returns the value of attribute bus.



6
7
8
# File 'lib/textus/store.rb', line 6

def bus
  @bus
end

#manifestObject (readonly)

Returns the value of attribute manifest.



6
7
8
# File 'lib/textus/store.rb', line 6

def manifest
  @manifest
end

#readerObject (readonly)

Returns the value of attribute reader.



6
7
8
# File 'lib/textus/store.rb', line 6

def reader
  @reader
end

#registryObject (readonly)

Returns the value of attribute registry.



6
7
8
# File 'lib/textus/store.rb', line 6

def registry
  @registry
end

#rootObject (readonly)

Returns the value of attribute root.



6
7
8
# File 'lib/textus/store.rb', line 6

def root
  @root
end

#writerObject (readonly)

Returns the value of attribute writer.



6
7
8
# File 'lib/textus/store.rb', line 6

def writer
  @writer
end

Class Method Details

.discover(start_dir = Dir.pwd, root: nil) ⇒ Object

Raises:



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/textus/store.rb', line 15

def self.discover(start_dir = Dir.pwd, root: nil)
  explicit = root || ENV.fetch("TEXTUS_ROOT", nil)
  return discover_explicit(explicit) if explicit

  dir = File.expand_path(start_dir)
  loop do
    candidate = File.join(dir, ".textus")
    return new(candidate) if File.directory?(candidate) && File.exist?(File.join(candidate, "manifest.yaml"))

    parent = File.dirname(dir)
    break if parent == dir

    dir = parent
  end
  raise IoError.new("no .textus directory found from #{start_dir}")
end

.mint_uidObject

A Textus UID: 16 lowercase hex chars (SecureRandom.hex(8)). Not a UUID —short on purpose. Random enough for collision-never-in-practice within a single store.



11
12
13
# File 'lib/textus/store.rb', line 11

def self.mint_uid
  SecureRandom.hex(8)
end

Instance Method Details

#audit_logObject



78
79
80
# File 'lib/textus/store.rb', line 78

def audit_log
  @audit_log ||= Store::AuditLog.new(@root)
end

#load_hooksObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/textus/store.rb', line 51

def load_hooks
  Textus.with_registry(@registry) do
    Hooks::Builtin.register_all
    dir = File.join(@root, "hooks")
    return unless File.directory?(dir)

    Dir.glob(File.join(dir, "**/*.rb")).sort.each do |f| # rubocop:disable Lint/RedundantDirGlobSort
      begin
        load(f)
      rescue StandardError, ScriptError => e
        raise UsageError.new("failed loading hook #{File.basename(f)}: #{e.class}: #{e.message}")
      end
    end
  end
end

#schema_for(name) ⇒ Object



67
68
69
70
71
72
73
74
75
76
# File 'lib/textus/store.rb', line 67

def schema_for(name)
  return nil if name.nil?

  @schemas[name] ||= begin
    sp = File.join(@root, "schemas", "#{name}.yaml")
    raise IoError.new("schema not found: #{sp}") unless File.exist?(sp)

    Schema.load(sp)
  end
end