Module: Textus::Builder::Pipeline

Defined in:
lib/textus/builder/pipeline.rb

Defined Under Namespace

Classes: Deps

Class Method Summary collapse

Class Method Details

.renderersObject



35
36
37
38
39
40
41
42
# File 'lib/textus/builder/pipeline.rb', line 35

def self.renderers
  @renderers ||= {
    "markdown" => Renderer::Markdown,
    "text" => Renderer::Text,
    "json" => Renderer::Json,
    "yaml" => Renderer::Yaml,
  }
end

.run(mentry:, deps:) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/textus/builder/pipeline.rb', line 44

def self.run(mentry:, deps:)
  # 1. Load sources + project + reduce
  data =
    if mentry.is_a?(Textus::Manifest::Entry::Derived) && mentry.projection?
      Textus::Projection.new(
        reader: deps.reader,
        spec: mentry.source.to_h.transform_keys(&:to_s),
        lister: deps.lister,
        rpc: deps.rpc,
        transform_context: deps.transform_context,
      ).run
    else
      { "entries" => [], "count" => 0, "generated_at" => Time.now.utc.iso8601 }
    end
  data = data.merge("boot" => deps.inject_boot.call) if mentry.inject_boot && deps.inject_boot

  # 2. Render
  klass = renderers[mentry.format] or
    raise UsageError.new("builder: unsupported format #{mentry.format.inspect} for '#{mentry.key}'")
  bytes = klass.new(template_loader: deps.template_loader).call(mentry: mentry, data: data)

  # 3. Write (idempotent: skip if only generated_at would differ)
  target_path = Key::Path.resolve(deps.manifest.data, mentry)
  FileUtils.mkdir_p(File.dirname(target_path))
  write_if_changed(target_path, bytes, mentry.format)

  target_path
end

.write_if_changed(target_path, bytes, _format) ⇒ Object

Built artifacts are content-addressed (no volatile timestamp, ADR 0070), so identity is plain byte-equality: skip the write when nothing changed. ‘format` is retained for signature stability across renderers.



76
77
78
79
80
# File 'lib/textus/builder/pipeline.rb', line 76

def self.write_if_changed(target_path, bytes, _format)
  return if File.exist?(target_path) && File.binread(target_path) == bytes

  File.binwrite(target_path, bytes)
end