Module: Textus::Manifest::Entry::Parser

Defined in:
lib/textus/manifest/entry/parser.rb

Class Method Summary collapse

Class Method Details

.call(raw) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/textus/manifest/entry/parser.rb', line 5

def self.call(raw)
  key = raw["key"] or raise UsageError.new("manifest entry missing key")
  lane = raw["lane"] or raise UsageError.new("manifest entry '#{key}' missing lane")

  raw_kind = raw["kind"] or raise BadManifest.new("entry '#{key}' missing required `kind:` (#{Entry::REGISTRY.keys.join("|")})")
  kind = raw_kind.to_sym
  if %i[derived intake].include?(kind)
    raise BadManifest.new(
      "entry '#{key}': kind: #{kind} was collapsed into `kind: produced` (ADR 0095) — " \
      "the produce method is `source.from` (#{kind == :intake ? "handler" : "project|command"})",
    )
  end

  explicit_path = raw["path"]
  format = resolve_format(raw, explicit_path)
  path   = explicit_path || derive_path(key, kind, format)

  common = {
    raw: raw,
    key: key, path: path, lane: lane,
    schema: raw["schema"], owner: raw["owner"],
    format: format,
    publish_targets: publish_targets(raw)
  }

  klass = Entry::REGISTRY[kind] or
    raise BadManifest.new("entry '#{key}': unknown kind: #{kind.inspect} (known: #{Entry::REGISTRY.keys.join(", ")})")
  klass.from_raw(common, raw)
end

.parse_source(raw, _key) ⇒ Object

Parse the optional ‘source:` block. Returns nil when absent (workflow produced entries register their produce logic in .textus/workflows/).



37
38
39
40
41
42
# File 'lib/textus/manifest/entry/parser.rb', line 37

def self.parse_source(raw, _key)
  block = raw["source"]
  return nil if block.nil?

  Textus::Manifest::Policy::Source.new(block)
end

.publish_targets(raw) ⇒ Object

ADR 0094: ‘publish:` is a LIST of target objects — to-targets

template?, inject_boot?

and/or a tree-target [tree]. The

ADR-0052 map forms ([…] / …) are retired.



47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/textus/manifest/entry/parser.rb', line 47

def self.publish_targets(raw)
  block = raw["publish"]
  return [] if block.nil?

  unless block.is_a?(Array)
    raise BadManifest.new(
      "entry '#{raw["key"]}': `publish:` must be a list of targets " \
      "[{to:, template:?} | {tree:}] (ADR 0094); the `publish: { … }` map form was retired",
    )
  end
  block.map { |t| Textus::Manifest::Policy::PublishTarget.new(t) }
end

.resolve_format(raw, path) ⇒ Object

Raises:



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/textus/manifest/entry/parser.rb', line 60

def self.resolve_format(raw, path)
  declared = raw["format"]

  return declared || "markdown" if path.nil? || path.empty?

  ext      = File.extname(path)
  inferred = Textus::Format.infer_from_extension(ext)

  if declared.nil?
    return inferred if inferred

    return "markdown"
  end

  raise UsageError.new("entry '#{raw["key"]}': unknown format #{declared.inspect}") unless Textus::Format.formats.include?(declared)

  if ext != "" && inferred && inferred != declared
    raise UsageError.new(
      "entry '#{raw["key"]}': path extension #{ext.inspect} does not match declared format #{declared.inspect}",
    )
  end

  declared
end